wip: doctor/cli/docs/api to vector db consolidation; api hardening for descriptions, tenant, and scopes; migrations and conversions of all DALs to EF v10

This commit is contained in:
master
2026-02-23 15:30:50 +02:00
parent bd8fee6ed8
commit e746577380
1424 changed files with 81225 additions and 25251 deletions

View File

@@ -104,6 +104,35 @@ public class StandardClientProvisioningStoreTests
Assert.Equal(new[] { "attestor", "signer" }, descriptor!.AllowedAudiences.OrderBy(value => value, StringComparer.Ordinal));
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task CreateOrUpdateAsync_NormalizesTenantAssignments()
{
var store = new TrackingClientStore();
var revocations = new TrackingRevocationStore();
var provisioning = new StandardClientProvisioningStore("standard", store, revocations, TimeProvider.System);
var registration = new AuthorityClientRegistration(
clientId: "tenant-multi-client",
confidential: false,
displayName: "Tenant Multi Client",
clientSecret: null,
allowedGrantTypes: new[] { "client_credentials" },
allowedScopes: new[] { "jobs:read" },
tenant: null,
properties: new Dictionary<string, string?>
{
[AuthorityClientMetadataKeys.Tenants] = " tenant-bravo tenant-alpha tenant-bravo "
});
await provisioning.CreateOrUpdateAsync(registration, TestContext.Current.CancellationToken);
Assert.True(store.Documents.TryGetValue("tenant-multi-client", out var document));
Assert.NotNull(document);
Assert.Equal("tenant-alpha tenant-bravo", document!.Properties[AuthorityClientMetadataKeys.Tenants]);
Assert.False(document.Properties.ContainsKey(AuthorityClientMetadataKeys.Tenant));
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task CreateOrUpdateAsync_MapsCertificateBindings()
@@ -191,6 +220,19 @@ public class StandardClientProvisioningStoreTests
return ValueTask.FromResult(document);
}
public ValueTask<IReadOnlyList<AuthorityClientDocument>> ListAsync(int limit = 500, int offset = 0, CancellationToken cancellationToken = default, IClientSessionHandle? session = null)
{
var take = limit <= 0 ? 500 : limit;
var skip = offset < 0 ? 0 : offset;
var page = Documents.Values
.OrderBy(client => client.ClientId, StringComparer.Ordinal)
.Skip(skip)
.Take(take)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityClientDocument>>(page);
}
public ValueTask UpsertAsync(AuthorityClientDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
Documents[document.ClientId] = document;

View File

@@ -322,6 +322,20 @@ internal sealed class InMemoryClientStore : IAuthorityClientStore
return ValueTask.FromResult(document);
}
public ValueTask<IReadOnlyList<AuthorityClientDocument>> ListAsync(int limit = 500, int offset = 0, CancellationToken cancellationToken = default, IClientSessionHandle? session = null)
{
var take = limit <= 0 ? 500 : limit;
var skip = offset < 0 ? 0 : offset;
var page = clients.Values
.OrderBy(client => client.ClientId, StringComparer.Ordinal)
.Skip(skip)
.Take(take)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityClientDocument>>(page);
}
public ValueTask UpsertAsync(AuthorityClientDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
clients[document.ClientId] = document;