Forge
csharp3407750f
1using AgentForge.Services;
2
3namespace AgentForge.Tests;
4
5[Collection(nameof(ForgeApiCollection))]
6public 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
View only · write via MCP/CIDE