| 1 | using System.Net.Http.Json; |
| 2 | using AgentForge.Data; |
| 3 | using AgentForge.Data.Entities; |
| 4 | using AgentForge.Models; |
| 5 | using AgentForge.Services; |
| 6 | using Microsoft.Extensions.DependencyInjection; |
| 7 | |
| 8 | namespace AgentForge.Tests; |
| 9 | |
| 10 | public sealed class ForgeInstanceAdminAuthTests |
| 11 | { |
| 12 | [Fact] |
| 13 | public async Task Instance_admin_can_create_org_without_bootstrap() |
| 14 | { |
| 15 | Environment.SetEnvironmentVariable("FORGE_REQUIRE_AUTH", "true"); |
| 16 | await using var factory = new ForgeWebApplicationFactory { PluginBundle = "ams-showcase" }; |
| 17 | using var scope = factory.Services.CreateScope(); |
| 18 | var repository = scope.ServiceProvider.GetRequiredService<ForgeRepository>(); |
| 19 | var auth = scope.ServiceProvider.GetRequiredService<ForgeAuthService>(); |
| 20 | var access = scope.ServiceProvider.GetRequiredService<ForgeRepoAccessService>(); |
| 21 | |
| 22 | var identity = repository.UpsertIdentity("github", "99", "host-admin", "Host Admin"); |
| 23 | repository.InsertInstanceAdmin(identity.Id); |
| 24 | var (_, token) = auth.CreateToken("oauth:github:host-admin", "read,write,accept_merge"); |
| 25 | |
| 26 | var principal = new ForgeAccessPrincipal( |
| 27 | auth.ValidateApiToken(token), |
| 28 | identity, |
| 29 | IsBootstrap: false, |
| 30 | IsInstanceAdmin: true); |
| 31 | |
| 32 | access.EnsureHostAdmin(principal); |
| 33 | |
| 34 | var client = factory.CreateClient(); |
| 35 | client.DefaultRequestHeaders.Authorization = |
| 36 | new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); |
| 37 | |
| 38 | var response = await client.PostAsJsonAsync( |
| 39 | "/api/v1/orgs", |
| 40 | new { slug = "labs", displayName = "Labs" }); |
| 41 | |
| 42 | Assert.Equal(System.Net.HttpStatusCode.Created, response.StatusCode); |
| 43 | } |
| 44 | } |
| 45 | |