| 1 | using AgentForge.Services; |
| 2 | |
| 3 | namespace AgentForge.Tests; |
| 4 | |
| 5 | [Collection(nameof(ForgeApiCollection))] |
| 6 | public sealed class ForgeOAuthTests |
| 7 | { |
| 8 | [Theory] |
| 9 | [InlineData("http://127.0.0.1:54321/callback", null, true)] |
| 10 | [InlineData("http://localhost:8080/callback", null, true)] |
| 11 | [InlineData("http://[::1]:9000/callback", null, true)] |
| 12 | [InlineData("https://127.0.0.1:443/callback", null, false)] |
| 13 | [InlineData("http://evil.com/callback", null, false)] |
| 14 | [InlineData("http://127.0.0.1:0/callback", null, false)] |
| 15 | [InlineData("", null, false)] |
| 16 | [InlineData("http://85.137.93.49:8770/view/auth/oauth/callback", "http://85.137.93.49:8770", true)] |
| 17 | [InlineData("http://85.137.93.49:8770/view/auth/oauth/callback", "http://127.0.0.1:8770", false)] |
| 18 | [InlineData("http://evil.com/view/auth/oauth/callback", "http://85.137.93.49:8770", false)] |
| 19 | public void RedirectAllowlist_accepts_loopback_and_forge_view_callback( |
| 20 | string redirectUri, |
| 21 | string? forgePublicBaseUrl, |
| 22 | bool expected) => |
| 23 | Assert.Equal(expected, ForgeOAuthRedirectAllowlist.IsAllowed(redirectUri, forgePublicBaseUrl)); |
| 24 | |
| 25 | [Fact] |
| 26 | public async Task Providers_returns_empty_when_github_not_configured() |
| 27 | { |
| 28 | await using var factory = new ForgeWebApplicationFactory(); |
| 29 | using var client = factory.CreateClient(); |
| 30 | using var response = await client.GetAsync("/api/v1/auth/providers"); |
| 31 | response.EnsureSuccessStatusCode(); |
| 32 | var json = await response.Content.ReadAsStringAsync(); |
| 33 | Assert.Contains("providers", json, StringComparison.OrdinalIgnoreCase); |
| 34 | } |
| 35 | |
| 36 | [Fact] |
| 37 | public async Task Login_rejects_non_loopback_redirect() |
| 38 | { |
| 39 | await using var factory = new ForgeWebApplicationFactory(); |
| 40 | using var client = factory.CreateClient(); |
| 41 | using var response = await client.GetAsync( |
| 42 | "/api/v1/auth/login?provider=github&redirect_uri=http://evil.com/cb&code_challenge=x&code_challenge_method=S256"); |
| 43 | Assert.Equal(System.Net.HttpStatusCode.BadRequest, response.StatusCode); |
| 44 | } |
| 45 | } |
| 46 | |