Backfill live auth scope and evidence route metadata
This commit is contained in:
@@ -5,6 +5,8 @@ using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Auth.Abstractions;
|
||||
using StellaOps.Authority.Persistence.InMemory.Stores;
|
||||
using StellaOps.Authority.Persistence.Postgres.Models;
|
||||
using StellaOps.Authority.Persistence.Postgres.Repositories;
|
||||
using StellaOps.Authority.Plugins.Abstractions;
|
||||
@@ -21,6 +23,57 @@ namespace StellaOps.Authority.Plugin.Standard.Tests;
|
||||
|
||||
public class StandardPluginBootstrapperTests
|
||||
{
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task StartAsync_EnsuresBootstrapClientsWithoutBootstrapUser()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddOptions<StandardPluginOptions>("standard")
|
||||
.Configure(options =>
|
||||
{
|
||||
options.TenantId = "demo-prod";
|
||||
options.BootstrapClients = new[]
|
||||
{
|
||||
new BootstrapClientOptions
|
||||
{
|
||||
ClientId = "stella-ops-ui",
|
||||
DisplayName = "Stella Ops Console",
|
||||
AllowedGrantTypes = "authorization_code refresh_token",
|
||||
AllowedScopes = $"openid profile {StellaOpsScopes.UiRead} {StellaOpsScopes.RegistryAdmin}",
|
||||
RedirectUris = "https://stella-ops.local/auth/callback https://stella-ops.local/auth/silent-refresh",
|
||||
PostLogoutRedirectUris = "https://stella-ops.local/",
|
||||
RequirePkce = true
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var clientStore = new InMemoryClientStore();
|
||||
services.AddSingleton<IAuthorityClientStore>(clientStore);
|
||||
services.AddSingleton<IAuthorityRevocationStore>(new StubRevocationStore());
|
||||
services.AddSingleton<TimeProvider>(new FakeTimeProvider(DateTimeOffset.Parse("2025-12-29T13:00:00Z")));
|
||||
services.AddSingleton(sp =>
|
||||
new StandardClientProvisioningStore(
|
||||
"standard",
|
||||
sp.GetRequiredService<IAuthorityClientStore>(),
|
||||
sp.GetRequiredService<IAuthorityRevocationStore>(),
|
||||
sp.GetRequiredService<TimeProvider>()));
|
||||
|
||||
services.AddSingleton<StandardPluginBootstrapper>(sp =>
|
||||
new StandardPluginBootstrapper("standard", sp.GetRequiredService<IServiceScopeFactory>(), NullLogger<StandardPluginBootstrapper>.Instance));
|
||||
|
||||
using var provider = services.BuildServiceProvider();
|
||||
var bootstrapper = provider.GetRequiredService<StandardPluginBootstrapper>();
|
||||
|
||||
await bootstrapper.StartAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
var client = await clientStore.FindByClientIdAsync("stella-ops-ui", TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(client);
|
||||
Assert.Contains(StellaOpsScopes.RegistryAdmin, client!.AllowedScopes);
|
||||
Assert.Contains("authorization_code", client.AllowedGrantTypes);
|
||||
Assert.True(client.RequirePkce);
|
||||
Assert.Equal("demo-prod", client.Properties[AuthorityClientMetadataKeys.Tenant]);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task StartAsync_DoesNotThrow_WhenBootstrapFails()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using StellaOps.Auth.Abstractions;
|
||||
using StellaOps.Authority.Plugin.Standard;
|
||||
using StellaOps.Cryptography;
|
||||
|
||||
@@ -25,6 +26,30 @@ public class StandardPluginOptionsTests
|
||||
options.Validate("standard");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Validate_AllowsBootstrapClientWhenConfigured()
|
||||
{
|
||||
var options = new StandardPluginOptions
|
||||
{
|
||||
BootstrapClients = new[]
|
||||
{
|
||||
new BootstrapClientOptions
|
||||
{
|
||||
ClientId = "stella-ops-ui",
|
||||
DisplayName = "Stella Ops Console",
|
||||
AllowedGrantTypes = "authorization_code refresh_token",
|
||||
AllowedScopes = $"openid profile {StellaOpsScopes.UiRead} {StellaOpsScopes.RegistryAdmin}",
|
||||
RedirectUris = "https://stella-ops.local/auth/callback",
|
||||
PostLogoutRedirectUris = "https://stella-ops.local/"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
options.Normalize(Path.Combine(Path.GetTempPath(), "config", "standard.yaml"));
|
||||
options.Validate("standard");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Validate_Throws_WhenBootstrapUserIncomplete()
|
||||
@@ -42,6 +67,30 @@ public class StandardPluginOptionsTests
|
||||
Assert.Contains("bootstrapUser", ex.Message, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Validate_Throws_WhenConfidentialBootstrapClientMissingSecret()
|
||||
{
|
||||
var options = new StandardPluginOptions
|
||||
{
|
||||
BootstrapClients = new[]
|
||||
{
|
||||
new BootstrapClientOptions
|
||||
{
|
||||
ClientId = "registry-admin",
|
||||
Confidential = true,
|
||||
AllowedGrantTypes = "client_credentials",
|
||||
AllowedScopes = StellaOpsScopes.RegistryAdmin
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
options.Normalize(Path.Combine(Path.GetTempPath(), "config", "standard.yaml"));
|
||||
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => options.Validate("standard"));
|
||||
Assert.Contains("clientsecret", ex.Message, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Validate_Throws_WhenLockoutWindowMinutesInvalid()
|
||||
@@ -115,6 +164,16 @@ public class StandardPluginOptionsTests
|
||||
{
|
||||
Username = " admin ",
|
||||
Password = " "
|
||||
},
|
||||
BootstrapClients = new[]
|
||||
{
|
||||
new BootstrapClientOptions
|
||||
{
|
||||
ClientId = " Stella-Ops-Ui ",
|
||||
AllowedGrantTypes = " refresh_token authorization_code ",
|
||||
AllowedScopes = $" {StellaOpsScopes.UiRead} {StellaOpsScopes.RegistryAdmin.ToUpperInvariant()} ",
|
||||
RedirectUris = " https://stella-ops.local/auth/callback "
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -123,6 +182,9 @@ public class StandardPluginOptionsTests
|
||||
Assert.Equal("tenant-a", options.TenantId);
|
||||
Assert.Equal("admin", options.BootstrapUser?.Username);
|
||||
Assert.Null(options.BootstrapUser?.Password);
|
||||
Assert.Equal("Stella-Ops-Ui", options.BootstrapClients[0].ClientId);
|
||||
Assert.Equal("authorization_code refresh_token", options.BootstrapClients[0].AllowedGrantTypes);
|
||||
Assert.Equal($"{StellaOpsScopes.RegistryAdmin} {StellaOpsScopes.UiRead}", options.BootstrapClients[0].AllowedScopes);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
|
||||
Reference in New Issue
Block a user