Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.

This commit is contained in:
StellaOps Bot
2025-12-26 21:54:17 +02:00
parent 335ff7da16
commit c2b9cd8d1f
3717 changed files with 264714 additions and 48202 deletions

View File

@@ -8,4 +8,4 @@
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
@@ -29,7 +29,7 @@
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitLab" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitLab" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<None Include="README.NuGet.md" Pack="true" PackagePath="" />

View File

@@ -1,3 +1,5 @@
#pragma warning disable CS0618 // ConfigureHttpMessageHandlerBuilder is obsolete - test validates legacy handler configuration
using System;
using System.Collections.Generic;
using System.Linq;
@@ -216,7 +218,6 @@ public class ServiceCollectionExtensionsTests
});
using var provider = services.BuildServiceProvider();
using StellaOps.TestKit;
var client = provider.GetRequiredService<IHttpClientFactory>().CreateClient("notify");
await client.GetAsync("https://notify.example/api");

View File

@@ -10,7 +10,7 @@
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Microsoft.Extensions.Http" />
</ItemGroup>
</Project>
</Project>

View File

@@ -331,6 +331,7 @@ public class StellaOpsTokenClientTests
var entry = new StellaOpsTokenCacheEntry(
"expired_token",
"Bearer",
timeProvider.GetUtcNow().AddMinutes(-5), // Already expired
["scanner.scan"]);

View File

@@ -30,13 +30,13 @@
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
<ProjectReference Include="..\..\..\AirGap\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Configuration/StellaOps.Configuration.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Messaging/StellaOps.Messaging.csproj" />
<ProjectReference Include="../../../Router/__Libraries/StellaOps.Messaging/StellaOps.Messaging.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="10.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitLab" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Microsoft.SourceLink.GitLab" PrivateAssets="All" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.15.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" />
</ItemGroup>
<ItemGroup>
<None Include="README.NuGet.md" Pack="true" PackagePath="" />

View File

@@ -1,877 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>StellaOps.Auth.Abstractions</name>
</assembly>
<members>
<member name="T:StellaOps.Auth.AuthorityTelemetry">
<summary>
Canonical telemetry metadata for the StellaOps Authority stack.
</summary>
</member>
<member name="F:StellaOps.Auth.AuthorityTelemetry.ServiceName">
<summary>
service.name resource attribute recorded by Authority components.
</summary>
</member>
<member name="F:StellaOps.Auth.AuthorityTelemetry.ServiceNamespace">
<summary>
service.namespace resource attribute aligning Authority with other StellaOps services.
</summary>
</member>
<member name="F:StellaOps.Auth.AuthorityTelemetry.ActivitySourceName">
<summary>
Activity source identifier used by Authority instrumentation.
</summary>
</member>
<member name="F:StellaOps.Auth.AuthorityTelemetry.MeterName">
<summary>
Meter name used by Authority instrumentation.
</summary>
</member>
<member name="M:StellaOps.Auth.AuthorityTelemetry.BuildDefaultResourceAttributes(System.Reflection.Assembly)">
<summary>
Builds the default set of resource attributes (service name/namespace/version).
</summary>
<param name="assembly">Optional assembly used to resolve the service version.</param>
</member>
<member name="M:StellaOps.Auth.AuthorityTelemetry.ResolveServiceVersion(System.Reflection.Assembly)">
<summary>
Resolves the service version string from the provided assembly (defaults to the Authority telemetry assembly).
</summary>
</member>
<member name="T:StellaOps.Auth.Abstractions.NetworkMask">
<summary>
Represents an IP network expressed in CIDR notation.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.NetworkMask.#ctor(System.Net.IPAddress,System.Int32)">
<summary>
Initialises a new <see cref="T:StellaOps.Auth.Abstractions.NetworkMask"/>.
</summary>
<param name="network">Canonical network address with host bits zeroed.</param>
<param name="prefixLength">Prefix length (0-32 for IPv4, 0-128 for IPv6).</param>
</member>
<member name="P:StellaOps.Auth.Abstractions.NetworkMask.Network">
<summary>
Canonical network address with host bits zeroed.
</summary>
</member>
<member name="P:StellaOps.Auth.Abstractions.NetworkMask.PrefixLength">
<summary>
Prefix length.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.NetworkMask.Parse(System.String)">
<summary>
Attempts to parse the supplied value as CIDR notation or a single IP address.
</summary>
<exception cref="T:System.FormatException">Thrown when the input is not recognised.</exception>
</member>
<member name="M:StellaOps.Auth.Abstractions.NetworkMask.TryParse(System.String,StellaOps.Auth.Abstractions.NetworkMask@)">
<summary>
Attempts to parse the supplied value as CIDR notation or a single IP address.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.NetworkMask.Contains(System.Net.IPAddress)">
<summary>
Determines whether the provided address belongs to this network.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.NetworkMask.ToString">
<inheritdoc />
</member>
<member name="T:StellaOps.Auth.Abstractions.NetworkMaskMatcher">
<summary>
Evaluates remote addresses against configured network masks.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.NetworkMaskMatcher.#ctor(System.Collections.Generic.IEnumerable{System.String})">
<summary>
Creates a matcher from raw CIDR strings.
</summary>
<param name="values">Sequence of CIDR entries or IP addresses.</param>
<exception cref="T:System.FormatException">Thrown when a value cannot be parsed.</exception>
</member>
<member name="M:StellaOps.Auth.Abstractions.NetworkMaskMatcher.#ctor(System.Collections.Generic.IEnumerable{StellaOps.Auth.Abstractions.NetworkMask})">
<summary>
Creates a matcher from already parsed masks.
</summary>
<param name="masks">Sequence of network masks.</param>
</member>
<member name="P:StellaOps.Auth.Abstractions.NetworkMaskMatcher.AllowAll">
<summary>
Gets a matcher that allows every address.
</summary>
</member>
<member name="P:StellaOps.Auth.Abstractions.NetworkMaskMatcher.DenyAll">
<summary>
Gets a matcher that denies every address (no masks configured).
</summary>
</member>
<member name="P:StellaOps.Auth.Abstractions.NetworkMaskMatcher.IsEmpty">
<summary>
Indicates whether this matcher has no masks configured and does not allow all.
</summary>
</member>
<member name="P:StellaOps.Auth.Abstractions.NetworkMaskMatcher.Masks">
<summary>
Returns the configured masks.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.NetworkMaskMatcher.IsAllowed(System.Net.IPAddress)">
<summary>
Checks whether the provided address matches any of the configured masks.
</summary>
<param name="address">Remote address to test.</param>
<returns><c>true</c> when the address is allowed.</returns>
</member>
<member name="T:StellaOps.Auth.Abstractions.StellaOpsAuthenticationDefaults">
<summary>
Default authentication constants used by StellaOps resource servers and clients.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsAuthenticationDefaults.AuthenticationScheme">
<summary>
Default authentication scheme for StellaOps bearer tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsAuthenticationDefaults.AuthenticationType">
<summary>
Logical authentication type attached to <see cref="T:System.Security.Claims.ClaimsIdentity"/>.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsAuthenticationDefaults.PolicyPrefix">
<summary>
Policy prefix applied to named authorization policies.
</summary>
</member>
<member name="T:StellaOps.Auth.Abstractions.StellaOpsClaimTypes">
<summary>
Canonical claim type identifiers used across StellaOps services.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.Subject">
<summary>
Subject identifier claim (maps to <c>sub</c> in JWTs).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.Tenant">
<summary>
StellaOps tenant identifier claim (multi-tenant deployments).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.Project">
<summary>
StellaOps project identifier claim (optional project scoping within a tenant).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.ClientId">
<summary>
OAuth2/OIDC client identifier claim (maps to <c>client_id</c>).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.ServiceAccount">
<summary>
Service account identifier associated with delegated tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.TokenId">
<summary>
Unique token identifier claim (maps to <c>jti</c>).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.AuthenticationMethod">
<summary>
Authentication method reference claim (<c>amr</c>).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.Scope">
<summary>
Space separated scope list (<c>scope</c>).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.ScopeItem">
<summary>
Individual scope items (<c>scp</c>).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.Audience">
<summary>
OAuth2 resource audiences (<c>aud</c>).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.IdentityProvider">
<summary>
Identity provider hint for downstream services.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.OperatorReason">
<summary>
Operator reason supplied when issuing orchestrator control tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.OperatorTicket">
<summary>
Operator ticket supplied when issuing orchestrator control tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.QuotaReason">
<summary>
Quota change reason supplied when issuing Orchestrator quota tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.QuotaTicket">
<summary>
Quota change ticket/incident reference supplied when issuing Orchestrator quota tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.BackfillReason">
<summary>
Backfill activation reason supplied when issuing orchestrator backfill tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.BackfillTicket">
<summary>
Backfill ticket/incident reference supplied when issuing orchestrator backfill tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.PolicyDigest">
<summary>
Digest of the policy package being published or promoted.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.PolicyTicket">
<summary>
Change management ticket supplied when issuing policy publish/promote tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.PolicyReason">
<summary>
Operator-provided justification supplied when issuing policy publish/promote tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.PackRunId">
<summary>
Pack run identifier supplied when issuing pack approval tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.PackGateId">
<summary>
Pack gate identifier supplied when issuing pack approval tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.PackPlanHash">
<summary>
Pack plan hash supplied when issuing pack approval tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.PolicyOperation">
<summary>
Operation discriminator indicating whether the policy token was issued for publish or promote.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.IncidentReason">
<summary>
Incident activation reason recorded when issuing observability incident tokens.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.VulnerabilityEnvironment">
<summary>
Attribute-based access control filter for vulnerability environment visibility.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.VulnerabilityOwner">
<summary>
Attribute-based access control filter for vulnerability ownership visibility.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.VulnerabilityBusinessTier">
<summary>
Attribute-based access control filter for vulnerability business tier visibility.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsClaimTypes.SessionId">
<summary>
Session identifier claim (<c>sid</c>).
</summary>
</member>
<member name="T:StellaOps.Auth.Abstractions.StellaOpsHttpHeaderNames">
<summary>
Shared HTTP header names used across StellaOps clients and services.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsHttpHeaderNames.Tenant">
<summary>
Header used to convey the tenant override when issuing requests to StellaOps APIs.
</summary>
</member>
<member name="T:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder">
<summary>
Fluent helper used to construct <see cref="T:System.Security.Claims.ClaimsPrincipal"/> instances that follow StellaOps conventions.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithSubject(System.String)">
<summary>
Adds or replaces the canonical subject identifier.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithClientId(System.String)">
<summary>
Adds or replaces the canonical client identifier.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithTenant(System.String)">
<summary>
Adds or replaces the tenant identifier claim.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithName(System.String)">
<summary>
Adds or replaces the user display name claim.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithIdentityProvider(System.String)">
<summary>
Adds or replaces the identity provider claim.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithSessionId(System.String)">
<summary>
Adds or replaces the session identifier claim.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithTokenId(System.String)">
<summary>
Adds or replaces the token identifier claim.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithAuthenticationMethod(System.String)">
<summary>
Adds or replaces the authentication method reference claim.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithNameClaimType(System.String)">
<summary>
Sets the name claim type appended when building the <see cref="T:System.Security.Claims.ClaimsIdentity"/>.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithRoleClaimType(System.String)">
<summary>
Sets the role claim type appended when building the <see cref="T:System.Security.Claims.ClaimsIdentity"/>.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithAuthenticationType(System.String)">
<summary>
Sets the authentication type stamped on the <see cref="T:System.Security.Claims.ClaimsIdentity"/>.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithScopes(System.Collections.Generic.IEnumerable{System.String})">
<summary>
Registers the supplied scopes (normalised to lower-case, deduplicated, sorted).
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithAudiences(System.Collections.Generic.IEnumerable{System.String})">
<summary>
Registers the supplied audiences (trimmed, deduplicated, sorted).
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithAudience(System.String)">
<summary>
Adds a single audience.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.AddClaim(System.String,System.String,System.String)">
<summary>
Adds an arbitrary claim (no deduplication is performed).
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.AddClaims(System.Collections.Generic.IEnumerable{System.Security.Claims.Claim})">
<summary>
Adds multiple claims (incoming claims are cloned to enforce value trimming).
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithIssuedAt(System.DateTimeOffset)">
<summary>
Adds an <c>iat</c> (issued at) claim using Unix time seconds.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithNotBefore(System.DateTimeOffset)">
<summary>
Adds an <c>nbf</c> (not before) claim using Unix time seconds.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.WithExpires(System.DateTimeOffset)">
<summary>
Adds an <c>exp</c> (expires) claim using Unix time seconds.
</summary>
</member>
<member name="P:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.NormalizedScopes">
<summary>
Returns the normalised scope list (deduplicated + sorted).
</summary>
</member>
<member name="P:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.Audiences">
<summary>
Returns the normalised audience list (deduplicated + sorted).
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsPrincipalBuilder.Build">
<summary>
Builds the immutable <see cref="T:System.Security.Claims.ClaimsPrincipal"/> instance based on the registered data.
</summary>
</member>
<member name="T:StellaOps.Auth.Abstractions.StellaOpsProblemResultFactory">
<summary>
Factory helpers for returning RFC 7807 problem responses using StellaOps conventions.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsProblemResultFactory.AuthenticationRequired(System.String,System.String)">
<summary>
Produces a 401 problem response indicating authentication is required.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsProblemResultFactory.InvalidToken(System.String,System.String)">
<summary>
Produces a 401 problem response for invalid, expired, or revoked tokens.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsProblemResultFactory.Forbidden(System.String,System.String)">
<summary>
Produces a 403 problem response when access is denied.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsProblemResultFactory.InsufficientScope(System.Collections.Generic.IReadOnlyCollection{System.String},System.Collections.Generic.IReadOnlyCollection{System.String},System.String)">
<summary>
Produces a 403 problem response for insufficient scopes.
</summary>
</member>
<member name="T:StellaOps.Auth.Abstractions.StellaOpsScopes">
<summary>
Canonical scope names supported by StellaOps services.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.ConcelierJobsTrigger">
<summary>
Scope required to trigger Concelier jobs.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.ConcelierMerge">
<summary>
Scope required to manage Concelier merge operations.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AuthorityUsersManage">
<summary>
Scope granting administrative access to Authority user management.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AuthorityClientsManage">
<summary>
Scope granting administrative access to Authority client registrations.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AuthorityAuditRead">
<summary>
Scope granting read-only access to Authority audit logs.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.Bypass">
<summary>
Synthetic scope representing trusted network bypass.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.UiRead">
<summary>
Scope granting read-only access to console UX features.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.ExceptionsApprove">
<summary>
Scope granting permission to approve exceptions.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AdvisoryRead">
<summary>
Scope granting read-only access to raw advisory ingestion data.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AdvisoryIngest">
<summary>
Scope granting write access for raw advisory ingestion.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AdvisoryAiView">
<summary>
Scope granting read-only access to Advisory AI artefacts (summaries, remediation exports).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AdvisoryAiOperate">
<summary>
Scope permitting Advisory AI inference requests and workflow execution.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AdvisoryAiAdmin">
<summary>
Scope granting administrative control over Advisory AI configuration and profiles.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.VexRead">
<summary>
Scope granting read-only access to raw VEX ingestion data.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.VexIngest">
<summary>
Scope granting write access for raw VEX ingestion.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AocVerify">
<summary>
Scope granting permission to execute aggregation-only contract verification.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.SignalsRead">
<summary>
Scope granting read-only access to reachability signals.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.SignalsWrite">
<summary>
Scope granting permission to write reachability signals.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.SignalsAdmin">
<summary>
Scope granting administrative access to reachability signal ingestion.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AirgapSeal">
<summary>
Scope granting permission to seal or unseal an installation in air-gapped mode.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AirgapImport">
<summary>
Scope granting permission to import offline bundles while in air-gapped mode.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AirgapStatusRead">
<summary>
Scope granting read-only access to air-gap status and sealing state endpoints.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyWrite">
<summary>
Scope granting permission to create or edit policy drafts.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyAuthor">
<summary>
Scope granting permission to author Policy Studio workspaces.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyEdit">
<summary>
Scope granting permission to edit policy configurations.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyRead">
<summary>
Scope granting read-only access to policy metadata.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyReview">
<summary>
Scope granting permission to review Policy Studio drafts.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicySubmit">
<summary>
Scope granting permission to submit drafts for review.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyApprove">
<summary>
Scope granting permission to approve or reject policies.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyOperate">
<summary>
Scope granting permission to operate Policy Studio promotions and runs.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyPublish">
<summary>
Scope granting permission to publish approved policy versions with attested artefacts.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyPromote">
<summary>
Scope granting permission to promote policy attestations between environments.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyAudit">
<summary>
Scope granting permission to audit Policy Studio activity.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyRun">
<summary>
Scope granting permission to trigger policy runs and activation workflows.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicyActivate">
<summary>
Scope granting permission to activate policies.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.FindingsRead">
<summary>
Scope granting read-only access to effective findings materialised by Policy Engine.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PolicySimulate">
<summary>
Scope granting permission to run Policy Studio simulations.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.EffectiveWrite">
<summary>
Scope granted to Policy Engine service identity for writing effective findings.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.GraphRead">
<summary>
Scope granting read-only access to graph queries and overlays.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.VulnRead">
<summary>
Scope granting read-only access to Vuln Explorer resources and permalinks.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.VulnView">
<summary>
Scope granting read-only access to Vuln Explorer findings, reports, and dashboards.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.VulnInvestigate">
<summary>
Scope permitting triage actions (assign, comment, annotate) within Vuln Explorer.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.VulnOperate">
<summary>
Scope permitting state-changing operations (status transitions, remediation workflows) within Vuln Explorer.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.VulnAudit">
<summary>
Scope permitting access to Vuln Explorer audit exports and immutable ledgers.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.ObservabilityRead">
<summary>
Scope granting read-only access to observability dashboards and overlays.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.TimelineRead">
<summary>
Scope granting read-only access to incident timelines and chronology data.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.TimelineWrite">
<summary>
Scope granting permission to append events to incident timelines.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.EvidenceCreate">
<summary>
Scope granting permission to create evidence packets in the evidence locker.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.EvidenceRead">
<summary>
Scope granting read-only access to stored evidence packets.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.EvidenceHold">
<summary>
Scope granting permission to place or release legal holds on evidence packets.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AttestRead">
<summary>
Scope granting read-only access to attestation records and observer feeds.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.ObservabilityIncident">
<summary>
Scope granting permission to activate or resolve observability incident mode controls.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.ExportViewer">
<summary>
Scope granting read-only access to export center runs and bundles.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.ExportOperator">
<summary>
Scope granting permission to operate export center scheduling and run execution.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.ExportAdmin">
<summary>
Scope granting administrative control over export center retention, encryption keys, and scheduling policies.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.NotifyViewer">
<summary>
Scope granting read-only access to notifier channels, rules, and delivery history.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.NotifyOperator">
<summary>
Scope permitting notifier rule management, delivery actions, and channel operations.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.NotifyAdmin">
<summary>
Scope granting administrative control over notifier secrets, escalations, and platform-wide settings.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.IssuerDirectoryRead">
<summary>
Scope granting read-only access to issuer directory catalogues.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.IssuerDirectoryWrite">
<summary>
Scope permitting creation and modification of issuer directory entries.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.IssuerDirectoryAdmin">
<summary>
Scope granting administrative control over issuer directory resources (delete, audit bypass).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.NotifyEscalate">
<summary>
Scope required to issue or honour escalation actions for notifications.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PacksRead">
<summary>
Scope granting read-only access to Task Packs catalogues and manifests.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PacksWrite">
<summary>
Scope permitting publication or updates to Task Packs in the registry.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PacksRun">
<summary>
Scope granting permission to execute Task Packs via CLI or Task Runner.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.PacksApprove">
<summary>
Scope granting permission to fulfil Task Pack approval gates.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.GraphWrite">
<summary>
Scope granting permission to enqueue or mutate graph build jobs.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.GraphExport">
<summary>
Scope granting permission to export graph artefacts (GraphML/JSONL/etc.).
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.GraphSimulate">
<summary>
Scope granting permission to trigger what-if simulations on graphs.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.OrchRead">
<summary>
Scope granting read-only access to Orchestrator job state and telemetry.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.OrchOperate">
<summary>
Scope granting permission to execute Orchestrator control actions.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.OrchQuota">
<summary>
Scope granting permission to manage Orchestrator quotas and elevated backfill tooling.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.OrchBackfill">
<summary>
Scope granting permission to initiate orchestrator-controlled backfill runs.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsScopes.AuthorityTenantsRead">
<summary>
Scope granting read-only access to Authority tenant catalog APIs.
</summary>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsScopes.Normalize(System.String)">
<summary>
Normalises a scope string (trim/convert to lower case).
</summary>
<param name="scope">Scope raw value.</param>
<returns>Normalised scope or <c>null</c> when the input is blank.</returns>
</member>
<member name="M:StellaOps.Auth.Abstractions.StellaOpsScopes.IsKnown(System.String)">
<summary>
Checks whether the provided scope is registered as a built-in StellaOps scope.
</summary>
</member>
<member name="P:StellaOps.Auth.Abstractions.StellaOpsScopes.All">
<summary>
Returns the full set of built-in scopes.
</summary>
</member>
<member name="T:StellaOps.Auth.Abstractions.StellaOpsServiceIdentities">
<summary>
Canonical identifiers for StellaOps service principals.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsServiceIdentities.PolicyEngine">
<summary>
Service identity used by Policy Engine when materialising effective findings.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsServiceIdentities.Cartographer">
<summary>
Service identity used by Cartographer when constructing and maintaining graph projections.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsServiceIdentities.VulnExplorer">
<summary>
Service identity used by Vuln Explorer when issuing scoped permalink requests.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsServiceIdentities.Signals">
<summary>
Service identity used by Signals components when managing reachability facts.
</summary>
</member>
<member name="T:StellaOps.Auth.Abstractions.StellaOpsTenancyDefaults">
<summary>
Shared tenancy default values used across StellaOps services.
</summary>
</member>
<member name="F:StellaOps.Auth.Abstractions.StellaOpsTenancyDefaults.AnyProject">
<summary>
Sentinel value indicating the token is not scoped to a specific project.
</summary>
</member>
</members>
</doc>

View File

@@ -1,410 +0,0 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v10.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v10.0": {
"StellaOps.Auth.Client/1.0.0-preview.1": {
"dependencies": {
"Microsoft.Extensions.Http.Polly": "10.0.0-rc.2.25502.107",
"Microsoft.IdentityModel.Tokens": "8.14.0",
"SharpCompress": "0.41.0",
"StellaOps.AirGap.Policy": "1.0.0",
"StellaOps.Auth.Abstractions": "1.0.0-preview.1",
"StellaOps.Configuration": "1.0.0"
},
"runtime": {
"StellaOps.Auth.Client.dll": {}
}
},
"BouncyCastle.Cryptography/2.5.1": {
"runtime": {
"lib/net6.0/BouncyCastle.Cryptography.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.5.1.28965"
}
}
},
"Konscious.Security.Cryptography.Argon2/1.3.1": {
"dependencies": {
"Konscious.Security.Cryptography.Blake2": "1.1.1"
},
"runtime": {
"lib/net8.0/Konscious.Security.Cryptography.Argon2.dll": {
"assemblyVersion": "1.3.1.0",
"fileVersion": "1.3.1.0"
}
}
},
"Konscious.Security.Cryptography.Blake2/1.1.1": {
"runtime": {
"lib/net8.0/Konscious.Security.Cryptography.Blake2.dll": {
"assemblyVersion": "1.1.1.0",
"fileVersion": "1.1.1.0"
}
}
},
"Microsoft.Extensions.Http.Polly/10.0.0-rc.2.25502.107": {
"dependencies": {
"Polly": "7.2.4",
"Polly.Extensions.Http": "3.0.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Http.Polly.dll": {
"assemblyVersion": "10.0.0.0",
"fileVersion": "10.0.25.50307"
}
}
},
"Microsoft.IdentityModel.Abstractions/8.14.0": {
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Microsoft.IdentityModel.Logging/8.14.0": {
"dependencies": {
"Microsoft.IdentityModel.Abstractions": "8.14.0"
},
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Logging.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"Microsoft.IdentityModel.Tokens/8.14.0": {
"dependencies": {
"Microsoft.IdentityModel.Logging": "8.14.0"
},
"runtime": {
"lib/net9.0/Microsoft.IdentityModel.Tokens.dll": {
"assemblyVersion": "8.14.0.0",
"fileVersion": "8.14.0.60815"
}
}
},
"NetEscapades.Configuration.Yaml/2.1.0": {
"dependencies": {
"YamlDotNet": "9.1.0"
},
"runtime": {
"lib/netstandard2.0/NetEscapades.Configuration.Yaml.dll": {
"assemblyVersion": "2.1.0.0",
"fileVersion": "2.1.0.0"
}
}
},
"Pkcs11Interop/4.1.0": {
"runtime": {
"lib/netstandard2.0/Pkcs11Interop.dll": {
"assemblyVersion": "4.1.0.0",
"fileVersion": "4.1.0.0"
}
}
},
"Polly/7.2.4": {
"runtime": {
"lib/netstandard2.0/Polly.dll": {
"assemblyVersion": "7.0.0.0",
"fileVersion": "7.2.4.982"
}
}
},
"Polly.Extensions.Http/3.0.0": {
"dependencies": {
"Polly": "7.2.4"
},
"runtime": {
"lib/netstandard2.0/Polly.Extensions.Http.dll": {
"assemblyVersion": "3.0.0.0",
"fileVersion": "3.0.0.0"
}
}
},
"SharpCompress/0.41.0": {
"dependencies": {
"ZstdSharp.Port": "0.8.6"
},
"runtime": {
"lib/net8.0/SharpCompress.dll": {
"assemblyVersion": "0.41.0.0",
"fileVersion": "0.41.0.0"
}
}
},
"YamlDotNet/9.1.0": {
"runtime": {
"lib/netstandard2.1/YamlDotNet.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.1.0.0"
}
}
},
"ZstdSharp.Port/0.8.6": {
"runtime": {
"lib/net9.0/ZstdSharp.dll": {
"assemblyVersion": "0.8.6.0",
"fileVersion": "0.8.6.0"
}
}
},
"StellaOps.AirGap.Policy/1.0.0": {
"dependencies": {
"SharpCompress": "0.41.0"
},
"runtime": {
"StellaOps.AirGap.Policy.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"StellaOps.Auth.Abstractions/1.0.0-preview.1": {
"dependencies": {
"SharpCompress": "0.41.0"
},
"runtime": {
"StellaOps.Auth.Abstractions.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"StellaOps.Authority.Plugins.Abstractions/1.0.0": {
"dependencies": {
"SharpCompress": "0.41.0",
"StellaOps.Auth.Abstractions": "1.0.0-preview.1",
"StellaOps.Cryptography": "1.0.0"
},
"runtime": {
"StellaOps.Authority.Plugins.Abstractions.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"StellaOps.Configuration/1.0.0": {
"dependencies": {
"NetEscapades.Configuration.Yaml": "2.1.0",
"SharpCompress": "0.41.0",
"StellaOps.Authority.Plugins.Abstractions": "1.0.0",
"StellaOps.Cryptography": "1.0.0",
"StellaOps.Cryptography.DependencyInjection": "1.0.0",
"StellaOps.Cryptography.Plugin.Pkcs11Gost": "1.0.0"
},
"runtime": {
"StellaOps.Configuration.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"StellaOps.Cryptography/1.0.0": {
"dependencies": {
"BouncyCastle.Cryptography": "2.5.1",
"Konscious.Security.Cryptography.Argon2": "1.3.1",
"Microsoft.IdentityModel.Tokens": "8.14.0",
"SharpCompress": "0.41.0"
},
"runtime": {
"StellaOps.Cryptography.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"StellaOps.Cryptography.DependencyInjection/1.0.0": {
"dependencies": {
"SharpCompress": "0.41.0",
"StellaOps.Cryptography": "1.0.0",
"StellaOps.Cryptography.Plugin.OpenSslGost": "1.0.0",
"StellaOps.Cryptography.Plugin.Pkcs11Gost": "1.0.0"
},
"runtime": {
"StellaOps.Cryptography.DependencyInjection.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"StellaOps.Cryptography.Plugin.OpenSslGost/1.0.0": {
"dependencies": {
"BouncyCastle.Cryptography": "2.5.1",
"SharpCompress": "0.41.0",
"StellaOps.Cryptography": "1.0.0"
},
"runtime": {
"StellaOps.Cryptography.Plugin.OpenSslGost.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"StellaOps.Cryptography.Plugin.Pkcs11Gost/1.0.0": {
"dependencies": {
"BouncyCastle.Cryptography": "2.5.1",
"Microsoft.IdentityModel.Tokens": "8.14.0",
"Pkcs11Interop": "4.1.0",
"SharpCompress": "0.41.0",
"StellaOps.Cryptography": "1.0.0"
},
"runtime": {
"StellaOps.Cryptography.Plugin.Pkcs11Gost.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
}
}
},
"libraries": {
"StellaOps.Auth.Client/1.0.0-preview.1": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"BouncyCastle.Cryptography/2.5.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-zy8TMeTP+1FH2NrLaNZtdRbBdq7u5MI+NFZQOBSM69u5RFkciinwzV2eveY6Kjf5MzgsYvvl6kTStsj3JrXqkg==",
"path": "bouncycastle.cryptography/2.5.1",
"hashPath": "bouncycastle.cryptography.2.5.1.nupkg.sha512"
},
"Konscious.Security.Cryptography.Argon2/1.3.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-T+OAGwzYYXftahpOxO7J4xA5K6urxwGnWQf3M+Jpi+76Azv/0T3M5SuN+h7/QvXuiqNw3ZEZ5QqVLI5ygDAylw==",
"path": "konscious.security.cryptography.argon2/1.3.1",
"hashPath": "konscious.security.cryptography.argon2.1.3.1.nupkg.sha512"
},
"Konscious.Security.Cryptography.Blake2/1.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-odwOyzj/J/lHJZNwFWJGU/LRecBShupAJ2S8TQqZfhUe9niHzu/voBYK5wuVKsvSpzbfupKQYZguVyIk1sgOkQ==",
"path": "konscious.security.cryptography.blake2/1.1.1",
"hashPath": "konscious.security.cryptography.blake2.1.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Http.Polly/10.0.0-rc.2.25502.107": {
"type": "package",
"serviceable": true,
"sha512": "sha512-aY5vLcrhdXCHsCjYI2lNwfat2vdSuiPs0FFZiy7IM6zcyqdxaefG8J8ezTKkZyiuAtznjVJJT70B660l/WlsxA==",
"path": "microsoft.extensions.http.polly/10.0.0-rc.2.25502.107",
"hashPath": "microsoft.extensions.http.polly.10.0.0-rc.2.25502.107.nupkg.sha512"
},
"Microsoft.IdentityModel.Abstractions/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==",
"path": "microsoft.identitymodel.abstractions/8.14.0",
"hashPath": "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512"
},
"Microsoft.IdentityModel.Logging/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==",
"path": "microsoft.identitymodel.logging/8.14.0",
"hashPath": "microsoft.identitymodel.logging.8.14.0.nupkg.sha512"
},
"Microsoft.IdentityModel.Tokens/8.14.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ySPkj429HrYHvwLVNoPZdQ/bKZZKSkuWKod68qxo+5/pLdXFimgflckKgAZclX9tuO9qWk/KFiIN65diMWgh+g==",
"path": "microsoft.identitymodel.tokens/8.14.0",
"hashPath": "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512"
},
"NetEscapades.Configuration.Yaml/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kNTX7kvRvbzBpLd3Vg9iu6t60tTyhVxsruAPgH6kl1GkAZIHLZw9cQysvjUenDU7JEnUgyxQnzfL8627ARDn+g==",
"path": "netescapades.configuration.yaml/2.1.0",
"hashPath": "netescapades.configuration.yaml.2.1.0.nupkg.sha512"
},
"Pkcs11Interop/4.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kgsNW2A/QK9fS86F1M3tHVOyb+dySajWNTWmSp+vWoaAtalF8GSvXj2nA/qSkWzB3UsdqRwYgtcoXgJIeuWVpw==",
"path": "pkcs11interop/4.1.0",
"hashPath": "pkcs11interop.4.1.0.nupkg.sha512"
},
"Polly/7.2.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-bw00Ck5sh6ekduDE3mnCo1ohzuad946uslCDEENu3091+6UKnBuKLo4e+yaNcCzXxOZCXWY2gV4a35+K1d4LDA==",
"path": "polly/7.2.4",
"hashPath": "polly.7.2.4.nupkg.sha512"
},
"Polly.Extensions.Http/3.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
"path": "polly.extensions.http/3.0.0",
"hashPath": "polly.extensions.http.3.0.0.nupkg.sha512"
},
"SharpCompress/0.41.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-z04dBVdTIAFTRKi38f0LkajaKA++bR+M8kYCbasXePILD2H+qs7CkLpyiippB24CSbTrWIgpBKm6BenZqkUwvw==",
"path": "sharpcompress/0.41.0",
"hashPath": "sharpcompress.0.41.0.nupkg.sha512"
},
"YamlDotNet/9.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-fuvGXU4Ec5HrsmEc+BiFTNPCRf1cGBI2kh/3RzMWgddM2M4ALhbSPoI3X3mhXZUD1qqQd9oSkFAtWjpz8z9eRg==",
"path": "yamldotnet/9.1.0",
"hashPath": "yamldotnet.9.1.0.nupkg.sha512"
},
"ZstdSharp.Port/0.8.6": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iP4jVLQoQmUjMU88g1WObiNr6YKZGvh4aOXn3yOJsHqZsflwRsxZPcIBvNXgjXO3vQKSLctXGLTpcBPLnWPS8A==",
"path": "zstdsharp.port/0.8.6",
"hashPath": "zstdsharp.port.0.8.6.nupkg.sha512"
},
"StellaOps.AirGap.Policy/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"StellaOps.Auth.Abstractions/1.0.0-preview.1": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"StellaOps.Authority.Plugins.Abstractions/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"StellaOps.Configuration/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"StellaOps.Cryptography/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"StellaOps.Cryptography.DependencyInjection/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"StellaOps.Cryptography.Plugin.OpenSslGost/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"StellaOps.Cryptography.Plugin.Pkcs11Gost/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Configuration;
@@ -34,7 +34,6 @@ public class ServiceCollectionExtensionsTests
using var provider = services.BuildServiceProvider();
using StellaOps.TestKit;
var resourceOptions = provider.GetRequiredService<IOptionsMonitor<StellaOpsResourceServerOptions>>().CurrentValue;
var jwtOptions = provider.GetRequiredService<IOptionsMonitor<JwtBearerOptions>>().Get(StellaOpsAuthenticationDefaults.AuthenticationScheme);

View File

@@ -9,4 +9,4 @@
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@@ -419,7 +419,7 @@ public class StellaOpsScopeAuthorizationHandlerTests
.WithScopes(new[] { StellaOpsScopes.PacksApprove })
.AddClaim(StellaOpsClaimTypes.PackRunId, "run-123")
.AddClaim(StellaOpsClaimTypes.PackGateId, "security-review")
.AddClaim(StellaOpsClaimTypes.PackPlanHash, new string(a, 64))
.AddClaim(StellaOpsClaimTypes.PackPlanHash, new string('a', 64))
.AddClaim(OpenIddictConstants.Claims.AuthenticationTime, staleAuthTime.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture))
.Build();
@@ -456,7 +456,7 @@ public class StellaOpsScopeAuthorizationHandlerTests
.WithScopes(new[] { StellaOpsScopes.PacksApprove })
.AddClaim(StellaOpsClaimTypes.PackRunId, "run-456")
.AddClaim(StellaOpsClaimTypes.PackGateId, "security-review")
.AddClaim(StellaOpsClaimTypes.PackPlanHash, new string(b, 64))
.AddClaim(StellaOpsClaimTypes.PackPlanHash, new string('b', 64))
.AddClaim(OpenIddictConstants.Claims.AuthenticationTime, freshAuthTime.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture))
.Build();
@@ -471,7 +471,7 @@ public class StellaOpsScopeAuthorizationHandlerTests
Assert.Equal("true", GetPropertyValue(record, "pack.fresh_auth_satisfied"));
Assert.Equal("run-456", GetPropertyValue(record, "pack.run_id"));
Assert.Equal("security-review", GetPropertyValue(record, "pack.gate_id"));
Assert.Equal(new string(b, 64), GetPropertyValue(record, "pack.plan_hash"));
Assert.Equal(new string('b', 64), GetPropertyValue(record, "pack.plan_hash"));
}
private static (StellaOpsScopeAuthorizationHandler Handler, IHttpContextAccessor Accessor, RecordingAuthEventSink Sink) CreateHandler(IOptionsMonitor<StellaOpsResourceServerOptions> optionsMonitor, IPAddress remoteAddress, TimeProvider? timeProvider = null)

View File

@@ -34,9 +34,9 @@
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitLab" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="OpenIddict.Abstractions" Version="6.4.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Microsoft.SourceLink.GitLab" PrivateAssets="All" />
<PackageReference Include="OpenIddict.Abstractions" />
</ItemGroup>
<ItemGroup>
<None Include="README.NuGet.md" Pack="true" PackagePath="" />

View File

@@ -9,9 +9,9 @@ using StellaOps.Authority.Plugin.Ldap.Connections;
using StellaOps.Authority.Plugin.Ldap.Tests.Fakes;
using StellaOps.Authority.Plugin.Ldap.Tests.TestHelpers;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Auth.Abstractions;
using Xunit;

View File

@@ -10,9 +10,9 @@ using StellaOps.Authority.Plugin.Ldap.Monitoring;
using StellaOps.Authority.Plugin.Ldap.Tests.TestHelpers;
using StellaOps.Authority.Plugin.Ldap.Tests.Fakes;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using Xunit;
namespace StellaOps.Authority.Plugin.Ldap.Tests.Credentials;

View File

@@ -11,14 +11,14 @@
<ItemGroup>
<ProjectReference Include="..\StellaOps.Authority.Plugin.Ldap\StellaOps.Authority.Plugin.Ldap.csproj" />
<ProjectReference Include="..\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="..\\..\\__Libraries\\StellaOps.Authority.Storage.Postgres\\StellaOps.Authority.Storage.Postgres.csproj" />
<ProjectReference Include="..\\..\\__Libraries\\StellaOps.Authority.Persistence\\StellaOps.Authority.Persistence.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="FluentAssertions" />
<PackageReference Include="xunit.runner.visualstudio" >
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
</Project>

View File

@@ -1,7 +1,7 @@
using System.Collections.Concurrent;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
namespace StellaOps.Authority.Plugin.Ldap.Tests.TestHelpers;

View File

@@ -9,8 +9,8 @@ using StellaOps.Authority.InMemoryDriver;
using StellaOps.Authority.Plugin.Ldap.Connections;
using StellaOps.Authority.Plugin.Ldap.Security;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Auth.Abstractions;
namespace StellaOps.Authority.Plugin.Ldap.ClientProvisioning;

View File

@@ -11,8 +11,8 @@ using StellaOps.Authority.Plugin.Ldap.ClientProvisioning;
using StellaOps.Authority.Plugin.Ldap.Connections;
using StellaOps.Authority.Plugin.Ldap.Monitoring;
using StellaOps.Authority.Plugin.Ldap.Security;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Cryptography.Audit;
namespace StellaOps.Authority.Plugin.Ldap.Credentials;

View File

@@ -9,7 +9,7 @@ using StellaOps.Authority.Plugin.Ldap.Connections;
using StellaOps.Authority.Plugin.Ldap.Credentials;
using StellaOps.Authority.Plugin.Ldap.Monitoring;
using StellaOps.Authority.Plugin.Ldap.Security;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.InMemory.Stores;
namespace StellaOps.Authority.Plugin.Ldap;

View File

@@ -9,18 +9,17 @@
<IsAuthorityPlugin>true</IsAuthorityPlugin>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.0" />
<PackageReference Include="System.DirectoryServices.Protocols" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" />
<PackageReference Include="System.DirectoryServices.Protocols" />
<!-- Storage now uses PostgreSQL -->
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\\StellaOps.Authority.Plugins.Abstractions\\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="..\\StellaOps.Auth.Abstractions\\StellaOps.Auth.Abstractions.csproj" />
<ProjectReference Include="..\\StellaOps.Authority.Storage.InMemory\\StellaOps.Authority.Storage.InMemory.csproj" />
<ProjectReference Include="..\\..\\__Libraries\\StellaOps.Authority.Persistence\\StellaOps.Authority.Persistence.csproj" />
<ProjectReference Include="..\\..\\..\\__Libraries\\StellaOps.Plugin\\StellaOps.Plugin.csproj" />
<ProjectReference Include="..\\..\\__Libraries\\StellaOps.Authority.Storage.Postgres\\StellaOps.Authority.Storage.Postgres.csproj" />
<ProjectReference Include="..\\..\\..\\__Libraries\\StellaOps.Messaging\\StellaOps.Messaging.csproj" />
<ProjectReference Include="..\\..\\..\\Router\\__Libraries\\StellaOps.Messaging\\StellaOps.Messaging.csproj" />
</ItemGroup>
</Project>

View File

@@ -468,8 +468,8 @@ public sealed class OidcConnectorSecurityTests
var user = new AuthorityUserDescriptor(
subjectId: subClaim.Value,
username: null,
displayName: null,
username: null!,
displayName: null!,
requiresPasswordReset: false,
roles: Array.Empty<string>(),
attributes: new Dictionary<string, string?>());
@@ -509,8 +509,8 @@ public sealed class OidcConnectorSecurityTests
var subClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == "sub");
var user = new AuthorityUserDescriptor(
subjectId: subClaim?.Value ?? "unknown",
username: null,
displayName: null,
username: null!,
displayName: null!,
requiresPasswordReset: false,
roles: Array.Empty<string>(),
attributes: new Dictionary<string, string?>());

View File

@@ -14,13 +14,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1" />
</ItemGroup>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Moq" />
</ItemGroup>
<ItemGroup>
<None Update="Fixtures\**\*.json">
@@ -30,5 +27,4 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
</Project>

View File

@@ -15,11 +15,11 @@
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.10.0" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.10.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" />
<PackageReference Include="Microsoft.Extensions.Http" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Options" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RootNamespace>StellaOps.Authority.Plugin.Oidc</RootNamespace>
<Description>StellaOps Authority OIDC Identity Provider Plugin</Description>
<IsAuthorityPlugin>true</IsAuthorityPlugin>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.10.0" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.10.0" />
</ItemGroup>
</Project>

View File

@@ -391,8 +391,8 @@ public sealed class SamlConnectorResilienceTests
var user = new AuthorityUserDescriptor(
subjectId: nameId,
username: null,
displayName: null,
username: null!,
displayName: null!,
requiresPasswordReset: false,
roles: Array.Empty<string>(),
attributes: new System.Collections.Generic.Dictionary<string, string?> { ["issuer"] = issuer });

View File

@@ -446,8 +446,8 @@ public sealed class SamlConnectorSecurityTests
var user = new AuthorityUserDescriptor(
subjectId: nameId,
username: null,
displayName: null,
username: null!,
displayName: null!,
requiresPasswordReset: false,
roles: Array.Empty<string>(),
attributes: new Dictionary<string, string?> { ["issuer"] = issuer });

View File

@@ -14,13 +14,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1" />
</ItemGroup>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Moq" />
</ItemGroup>
<ItemGroup>
<None Update="Fixtures\**\*.xml">
@@ -30,5 +27,4 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
</Project>

View File

@@ -15,10 +15,10 @@
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens.Saml" Version="8.10.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" />
<PackageReference Include="Microsoft.Extensions.Http" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Options" />
<PackageReference Include="Microsoft.IdentityModel.Tokens.Saml" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RootNamespace>StellaOps.Authority.Plugin.Saml</RootNamespace>
<Description>StellaOps Authority SAML Identity Provider Plugin</Description>
<IsAuthorityPlugin>true</IsAuthorityPlugin>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens.Saml" Version="8.10.0" />
</ItemGroup>
</Project>

View File

@@ -6,9 +6,11 @@ using System.Threading.Tasks;
using StellaOps.Authority.InMemoryDriver;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Plugin.Standard.Storage;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using Xunit;
using Xunit.Abstractions;
using StellaOps.TestKit;
namespace StellaOps.Authority.Plugin.Standard.Tests;
@@ -179,8 +181,8 @@ public class StandardClientProvisioningStoreTests
return ValueTask.CompletedTask;
}
public ValueTask<bool> RemoveAsync(string category, string revocationId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
=> ValueTask.FromResult(true);
public ValueTask RemoveAsync(string category, string revocationId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
=> ValueTask.CompletedTask;
public ValueTask<IReadOnlyList<AuthorityRevocationDocument>> GetActiveAsync(DateTimeOffset asOf, CancellationToken cancellationToken, IClientSessionHandle? session = null)
=> ValueTask.FromResult<IReadOnlyList<AuthorityRevocationDocument>>(Array.Empty<AuthorityRevocationDocument>());

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
@@ -13,8 +13,9 @@ using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Plugin.Standard;
using StellaOps.Authority.Plugin.Standard.Bootstrap;
using StellaOps.Authority.Plugin.Standard.Storage;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Cryptography.Audit;
@@ -238,7 +239,6 @@ public class StandardPluginRegistrarTests
registrar.Register(new AuthorityPluginRegistrationContext(services, pluginContext, configuration));
using var provider = services.BuildServiceProvider();
using StellaOps.TestKit;
var optionsMonitor = provider.GetRequiredService<IOptionsMonitor<StandardPluginOptions>>();
var options = optionsMonitor.Get("standard");
@@ -303,8 +303,8 @@ internal sealed class StubRevocationStore : IAuthorityRevocationStore
public ValueTask UpsertAsync(AuthorityRevocationDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
=> ValueTask.CompletedTask;
public ValueTask<bool> RemoveAsync(string category, string revocationId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
=> ValueTask.FromResult(false);
public ValueTask RemoveAsync(string category, string revocationId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
=> ValueTask.CompletedTask;
public ValueTask<IReadOnlyList<AuthorityRevocationDocument>> GetActiveAsync(DateTimeOffset asOf, CancellationToken cancellationToken, IClientSessionHandle? session = null)
=> ValueTask.FromResult<IReadOnlyList<AuthorityRevocationDocument>>(Array.Empty<AuthorityRevocationDocument>());

View File

@@ -5,7 +5,9 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using StellaOps.Authority.InMemoryDriver;
using StellaOps.Authority.Persistence.Postgres.Repositories;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Plugin.Standard.Security;
using StellaOps.Authority.Plugin.Standard.Storage;
@@ -21,6 +23,7 @@ public class StandardUserCredentialStoreTests : IAsyncLifetime
private readonly StandardPluginOptions options;
private readonly StandardUserCredentialStore store;
private readonly TestAuditLogger auditLogger;
private readonly Mock<IUserRepository> userRepositoryMock;
public StandardUserCredentialStoreTests()
{
@@ -52,9 +55,11 @@ public class StandardUserCredentialStoreTests : IAsyncLifetime
};
var cryptoProvider = new DefaultCryptoProvider();
auditLogger = new TestAuditLogger();
userRepositoryMock = new Mock<IUserRepository>();
store = new StandardUserCredentialStore(
"standard",
database,
"test-tenant",
userRepositoryMock.Object,
options,
new CryptoPasswordHasher(options, cryptoProvider),
auditLogger,

View File

@@ -5,10 +5,14 @@
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MongoDB.Driver" />
<PackageReference Include="Moq" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StellaOps.Authority.Plugin.Standard\StellaOps.Authority.Plugin.Standard.csproj" />
<ProjectReference Include="..\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
<!-- Storage now uses PostgreSQL via Plugin.Standard project reference -->
</Project>
</Project>

View File

@@ -7,8 +7,8 @@ using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Plugin.Standard.Bootstrap;
using StellaOps.Authority.Plugin.Standard.Security;
using StellaOps.Authority.Plugin.Standard.Storage;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Repositories;
using StellaOps.Cryptography;
using StellaOps.Cryptography.DependencyInjection;

View File

@@ -9,17 +9,16 @@
<IsAuthorityPlugin>true</IsAuthorityPlugin>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
<ProjectReference Include="..\StellaOps.Authority.Storage.InMemory\StellaOps.Authority.Storage.InMemory.csproj" />
<ProjectReference Include="../../__Libraries/StellaOps.Authority.Persistence/StellaOps.Authority.Persistence.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Plugin/StellaOps.Plugin.csproj" />
<ProjectReference Include="../../__Libraries/StellaOps.Authority.Storage.Postgres/StellaOps.Authority.Storage.Postgres.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography.DependencyInjection/StellaOps.Cryptography.DependencyInjection.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Linq;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
namespace StellaOps.Authority.Plugin.Standard.Storage;

View File

@@ -8,8 +8,8 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Plugin.Standard.Security;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Cryptography.Audit;
namespace StellaOps.Authority.Plugin.Standard.Storage;

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
@@ -9,4 +9,4 @@
<ProjectReference Include="..\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@@ -15,9 +15,9 @@
<WriteLinesToFile File="$(IntermediateOutputPath)$(MSBuildProjectName).GeneratedMSBuildEditorConfig.editorconfig" Lines="" Overwrite="false" />
</Target>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<GenerateMSBuildEditorConfigFile>false</GenerateMSBuildEditorConfigFile>
</PropertyGroup>
<ItemGroup>
<EditorConfigFiles Remove="$(IntermediateOutputPath)$(MSBuildProjectName).GeneratedMSBuildEditorConfig.editorconfig" />
</ItemGroup>
<Target Name="EnsureGeneratedEditorConfig" BeforeTargets="ResolveEditorConfigFiles">
<WriteLinesToFile File="$(IntermediateOutputPath)$(MSBuildProjectName).GeneratedMSBuildEditorConfig.editorconfig" Lines="" Overwrite="false" />
</Target>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Plugin/StellaOps.Plugin.csproj" />
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,287 +0,0 @@
namespace StellaOps.Authority.Storage.Documents;
/// <summary>
/// Represents a bootstrap invite document.
/// </summary>
public sealed class AuthorityBootstrapInviteDocument
{
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string Token { get; set; } = string.Empty;
public string Type { get; set; } = string.Empty;
public string? Provider { get; set; }
public string? Target { get; set; }
public DateTimeOffset ExpiresAt { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset IssuedAt { get; set; }
public string? IssuedBy { get; set; }
public DateTimeOffset? ReservedUntil { get; set; }
public string? ReservedBy { get; set; }
public bool Consumed { get; set; }
public string Status { get; set; } = AuthorityBootstrapInviteStatuses.Pending;
public Dictionary<string, string?>? Metadata { get; set; }
}
public static class AuthorityBootstrapInviteStatuses
{
public const string Pending = "pending";
public const string Reserved = "reserved";
public const string Consumed = "consumed";
public const string Expired = "expired";
}
public enum BootstrapInviteReservationStatus
{
NotFound,
Reserved,
Expired,
AlreadyUsed
}
public sealed record BootstrapInviteReservationResult(BootstrapInviteReservationStatus Status, AuthorityBootstrapInviteDocument? Invite);
/// <summary>
/// Represents a service account document.
/// </summary>
public sealed class AuthorityServiceAccountDocument
{
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string AccountId { get; set; } = string.Empty;
public string Tenant { get; set; } = string.Empty;
public string DisplayName { get; set; } = string.Empty;
public string? Description { get; set; }
public bool Enabled { get; set; } = true;
public List<string> AllowedScopes { get; set; } = new();
public List<string> AuthorizedClients { get; set; } = new();
public Dictionary<string, List<string>> Attributes { get; set; } = new(StringComparer.OrdinalIgnoreCase);
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset UpdatedAt { get; set; }
}
/// <summary>
/// Represents a client document.
/// </summary>
public sealed class AuthorityClientDocument
{
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string ClientId { get; set; } = string.Empty;
public string? ClientSecret { get; set; }
public string? SecretHash { get; set; }
public string? DisplayName { get; set; }
public string? Description { get; set; }
public string? Plugin { get; set; }
public string? SenderConstraint { get; set; }
public bool Enabled { get; set; } = true;
public List<string> RedirectUris { get; set; } = new();
public List<string> PostLogoutRedirectUris { get; set; } = new();
public List<string> AllowedScopes { get; set; } = new();
public List<string> AllowedGrantTypes { get; set; } = new();
public bool RequireClientSecret { get; set; } = true;
public bool RequirePkce { get; set; }
public bool AllowPlainTextPkce { get; set; }
public string? ClientType { get; set; }
public Dictionary<string, string> Properties { get; set; } = new();
public List<AuthorityClientCertificateBinding> CertificateBindings { get; set; } = new();
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset UpdatedAt { get; set; }
public bool Disabled { get; set; }
}
/// <summary>
/// Represents a revocation document.
/// </summary>
public sealed class AuthorityRevocationDocument
{
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string Category { get; set; } = string.Empty;
public string RevocationId { get; set; } = string.Empty;
public string SubjectId { get; set; } = string.Empty;
public string? ClientId { get; set; }
public string? TokenId { get; set; }
public string? TokenType { get; set; }
public string Reason { get; set; } = string.Empty;
public string? ReasonDescription { get; set; }
public DateTimeOffset RevokedAt { get; set; }
public DateTimeOffset? EffectiveAt { get; set; }
public DateTimeOffset? ExpiresAt { get; set; }
public List<string>? Scopes { get; set; }
public string? Fingerprint { get; set; }
public Dictionary<string, string?> Metadata { get; set; } = new();
}
/// <summary>
/// Represents a login attempt document.
/// </summary>
public sealed class AuthorityLoginAttemptDocument
{
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string? CorrelationId { get; set; }
public string? SubjectId { get; set; }
public string? Username { get; set; }
public string? ClientId { get; set; }
public string? Plugin { get; set; }
public string EventType { get; set; } = string.Empty;
public string Outcome { get; set; } = string.Empty;
public bool Successful { get; set; }
public string? Reason { get; set; }
public string? RemoteAddress { get; set; }
public string? IpAddress { get; set; }
public string? UserAgent { get; set; }
public string? Tenant { get; set; }
public List<string> Scopes { get; set; } = new();
public DateTimeOffset OccurredAt { get; set; }
public List<AuthorityLoginAttemptPropertyDocument> Properties { get; set; } = new();
}
/// <summary>
/// Represents a property in a login attempt document.
/// </summary>
public sealed class AuthorityLoginAttemptPropertyDocument
{
public string Name { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
public bool Sensitive { get; set; }
public string Classification { get; set; } = "none";
}
/// <summary>
/// Represents a token document.
/// </summary>
public sealed class AuthorityTokenDocument
{
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string TokenId { get; set; } = string.Empty;
public string? SubjectId { get; set; }
public string? ClientId { get; set; }
public string TokenType { get; set; } = string.Empty;
public string Type
{
get => TokenType;
set => TokenType = value;
}
public string? ReferenceId { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset? ExpiresAt { get; set; }
public DateTimeOffset? RedeemedAt { get; set; }
public string? Payload { get; set; }
public List<string> Scope { get; set; } = new();
public string Status { get; set; } = "valid";
public string? Tenant { get; set; }
public string? Project { get; set; }
public string? SenderConstraint { get; set; }
public string? SenderNonce { get; set; }
public string? SenderCertificateHex { get; set; }
public string? SenderKeyThumbprint { get; set; }
public string? ServiceAccountId { get; set; }
public string? TokenKind { get; set; }
public string? VulnerabilityEnvironment { get; set; }
public string? VulnerabilityOwner { get; set; }
public string? VulnerabilityBusinessTier { get; set; }
public List<string> ActorChain { get; set; } = new();
public string? IncidentReason { get; set; }
public List<string> Devices { get; set; } = new();
public Dictionary<string, string> Properties { get; set; } = new();
public DateTimeOffset? RevokedAt { get; set; }
public string? RevokedReason { get; set; }
public string? RevokedReasonDescription { get; set; }
public IReadOnlyDictionary<string, string?>? RevokedMetadata { get; set; }
}
/// <summary>
/// Represents a refresh token document.
/// </summary>
public sealed class AuthorityRefreshTokenDocument
{
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string TokenId { get; set; } = string.Empty;
public string? SubjectId { get; set; }
public string? ClientId { get; set; }
public string? Handle { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset? ExpiresAt { get; set; }
public DateTimeOffset? ConsumedAt { get; set; }
public string? Payload { get; set; }
}
/// <summary>
/// Represents an airgap audit document.
/// </summary>
public sealed class AuthorityAirgapAuditDocument
{
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string? Tenant { get; set; }
public string? SubjectId { get; set; }
public string? Username { get; set; }
public string? DisplayName { get; set; }
public string? ClientId { get; set; }
public string? BundleId { get; set; }
public string? Status { get; set; }
public string EventType { get; set; } = string.Empty;
public string? OperatorId { get; set; }
public string? ComponentId { get; set; }
public string Outcome { get; set; } = string.Empty;
public string? Reason { get; set; }
public string? TraceId { get; set; }
public DateTimeOffset OccurredAt { get; set; }
public List<AuthorityAirgapAuditPropertyDocument> Properties { get; set; } = new();
}
/// <summary>
/// Represents a property in an airgap audit document.
/// </summary>
public sealed class AuthorityAirgapAuditPropertyDocument
{
public string Name { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
}
/// <summary>
/// Query parameters for airgap audit search.
/// </summary>
public sealed class AuthorityAirgapAuditQuery
{
public string? Tenant { get; set; }
public string? BundleId { get; set; }
public string? Status { get; set; }
public string? TraceId { get; set; }
public string? AfterId { get; set; }
public int Limit { get; set; } = 50;
}
public sealed class AuthorityAirgapAuditQueryResult
{
public AuthorityAirgapAuditQueryResult(IReadOnlyList<AuthorityAirgapAuditDocument> items, string? nextCursor)
{
Items = items ?? throw new ArgumentNullException(nameof(items));
NextCursor = nextCursor;
}
public IReadOnlyList<AuthorityAirgapAuditDocument> Items { get; }
public string? NextCursor { get; }
}
/// <summary>
/// Tracks the last exported revocation bundle metadata.
/// </summary>
public sealed class AuthorityRevocationExportStateDocument
{
public long Sequence { get; set; }
public string? BundleId { get; set; }
public DateTimeOffset? IssuedAt { get; set; }
}
/// <summary>
/// Represents a certificate binding for client authentication.
/// </summary>
public sealed class AuthorityClientCertificateBinding
{
public string? Thumbprint { get; set; }
public string? SerialNumber { get; set; }
public string? Subject { get; set; }
public string? Issuer { get; set; }
public List<string> SubjectAlternativeNames { get; set; } = new();
public DateTimeOffset? NotBefore { get; set; }
public DateTimeOffset? NotAfter { get; set; }
public string? Label { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset UpdatedAt { get; set; }
}

View File

@@ -1,17 +0,0 @@
namespace StellaOps.Authority.Storage.Documents;
/// <summary>
/// Result status for token usage recording.
/// </summary>
public enum TokenUsageUpdateStatus
{
Recorded,
MissingMetadata,
NotFound,
SuspectedReplay
}
/// <summary>
/// Represents the outcome of recording token usage.
/// </summary>
public sealed record TokenUsageUpdateResult(TokenUsageUpdateStatus Status, string? RemoteAddress, string? UserAgent);

View File

@@ -1,153 +0,0 @@
using System.Linq.Expressions;
namespace StellaOps.Authority.InMemoryDriver;
/// <summary>
/// Compatibility shim for collection interface.
/// Provides an in-memory implementation.
/// </summary>
public interface ICollection<TDocument>
{
IDatabase Database { get; }
string CollectionNamespace { get; }
Task<TDocument?> FindOneAsync(Expression<Func<TDocument, bool>> filter, CancellationToken cancellationToken = default);
Task<IReadOnlyList<TDocument>> FindAsync(Expression<Func<TDocument, bool>> filter, CancellationToken cancellationToken = default);
Task InsertOneAsync(TDocument document, CancellationToken cancellationToken = default);
Task ReplaceOneAsync(Expression<Func<TDocument, bool>> filter, TDocument replacement, bool isUpsert = false, CancellationToken cancellationToken = default);
Task DeleteOneAsync(Expression<Func<TDocument, bool>> filter, CancellationToken cancellationToken = default);
Task<long> CountDocumentsAsync(Expression<Func<TDocument, bool>> filter, CancellationToken cancellationToken = default);
}
/// <summary>
/// Compatibility shim for database interface.
/// </summary>
public interface IDatabase
{
string DatabaseNamespace { get; }
ICollection<TDocument> GetCollection<TDocument>(string name);
}
/// <summary>
/// Compatibility shim for client interface.
/// </summary>
public interface IClient
{
IDatabase GetDatabase(string name);
}
/// <summary>
/// In-memory implementation of ICollection for compatibility.
/// </summary>
public class InMemoryCollection<TDocument> : ICollection<TDocument>
{
private readonly List<TDocument> _documents = new();
private readonly IDatabase _database;
private readonly string _name;
public InMemoryCollection(IDatabase database, string name)
{
_database = database;
_name = name;
}
public IDatabase Database => _database;
public string CollectionNamespace => _name;
public Task<TDocument?> FindOneAsync(Expression<Func<TDocument, bool>> filter, CancellationToken cancellationToken = default)
{
var compiled = filter.Compile();
var result = _documents.FirstOrDefault(compiled);
return Task.FromResult(result);
}
public Task<IReadOnlyList<TDocument>> FindAsync(Expression<Func<TDocument, bool>> filter, CancellationToken cancellationToken = default)
{
var compiled = filter.Compile();
IReadOnlyList<TDocument> result = _documents.Where(compiled).ToList();
return Task.FromResult(result);
}
public Task InsertOneAsync(TDocument document, CancellationToken cancellationToken = default)
{
_documents.Add(document);
return Task.CompletedTask;
}
public Task ReplaceOneAsync(Expression<Func<TDocument, bool>> filter, TDocument replacement, bool isUpsert = false, CancellationToken cancellationToken = default)
{
var compiled = filter.Compile();
var index = _documents.FindIndex(d => compiled(d));
if (index >= 0)
{
_documents[index] = replacement;
}
else if (isUpsert)
{
_documents.Add(replacement);
}
return Task.CompletedTask;
}
public Task DeleteOneAsync(Expression<Func<TDocument, bool>> filter, CancellationToken cancellationToken = default)
{
var compiled = filter.Compile();
var item = _documents.FirstOrDefault(compiled);
if (item != null)
{
_documents.Remove(item);
}
return Task.CompletedTask;
}
public Task<long> CountDocumentsAsync(Expression<Func<TDocument, bool>> filter, CancellationToken cancellationToken = default)
{
var compiled = filter.Compile();
var count = _documents.Count(compiled);
return Task.FromResult((long)count);
}
}
/// <summary>
/// In-memory implementation of IDatabase for compatibility.
/// </summary>
public class InMemoryDatabase : IDatabase
{
private readonly Dictionary<string, object> _collections = new();
private readonly string _name;
public InMemoryDatabase(string name)
{
_name = name;
}
public string DatabaseNamespace => _name;
public ICollection<TDocument> GetCollection<TDocument>(string name)
{
if (!_collections.TryGetValue(name, out var collection))
{
collection = new InMemoryCollection<TDocument>(this, name);
_collections[name] = collection;
}
return (ICollection<TDocument>)collection;
}
}
/// <summary>
/// In-memory implementation of IClient for compatibility.
/// </summary>
public class InMemoryClient : IClient
{
private readonly Dictionary<string, IDatabase> _databases = new();
public IDatabase GetDatabase(string name)
{
if (!_databases.TryGetValue(name, out var database))
{
database = new InMemoryDatabase(name);
_databases[name] = database;
}
return database;
}
}

View File

@@ -1,67 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using StellaOps.Authority.InMemoryDriver;
using StellaOps.Authority.Storage.InMemory.Initialization;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
namespace StellaOps.Authority.Storage.Extensions;
/// <summary>
/// Compatibility shim storage options. In PostgreSQL mode, these are largely unused.
/// </summary>
public sealed class AuthorityStorageOptions
{
public string ConnectionString { get; set; } = string.Empty;
public string DatabaseName { get; set; } = "authority";
public TimeSpan CommandTimeout { get; set; } = TimeSpan.FromSeconds(30);
}
/// <summary>
/// Extension methods for configuring Authority storage compatibility storage services.
/// In PostgreSQL mode, this registers in-memory implementations for the storage interfaces.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds Authority storage compatibility storage services (in-memory implementations).
/// For production PostgreSQL storage, use AddAuthorityPostgresStorage from StellaOps.Authority.Storage.Postgres.
/// </summary>
public static IServiceCollection AddAuthorityInMemoryStorage(
this IServiceCollection services,
Action<AuthorityStorageOptions> configureOptions)
{
var options = new AuthorityStorageOptions();
configureOptions(options);
services.AddSingleton(options);
RegisterInMemoryServices(services, options);
return services;
}
private static void RegisterInMemoryServices(IServiceCollection services, AuthorityStorageOptions options)
{
// Register the initializer (no-op for Postgres mode)
services.AddSingleton<AuthorityStorageInitializer>();
// Register null session accessor
services.AddSingleton<IAuthoritySessionAccessor, NullAuthoritySessionAccessor>();
// Register in-memory shims for compatibility
var inMemoryClient = new InMemoryClient();
var inMemoryDatabase = inMemoryClient.GetDatabase(options.DatabaseName);
services.AddSingleton<IClient>(inMemoryClient);
services.AddSingleton<IDatabase>(inMemoryDatabase);
// Register in-memory store implementations
// These should be replaced by Postgres-backed implementations over time
services.AddSingleton<IAuthorityBootstrapInviteStore, InMemoryBootstrapInviteStore>();
services.AddSingleton<IAuthorityServiceAccountStore, InMemoryServiceAccountStore>();
services.AddSingleton<IAuthorityClientStore, InMemoryClientStore>();
services.AddSingleton<IAuthorityRevocationStore, InMemoryRevocationStore>();
services.AddSingleton<IAuthorityLoginAttemptStore, InMemoryLoginAttemptStore>();
services.AddSingleton<IAuthorityTokenStore, InMemoryTokenStore>();
services.AddSingleton<IAuthorityRefreshTokenStore, InMemoryRefreshTokenStore>();
services.AddSingleton<IAuthorityAirgapAuditStore, InMemoryAirgapAuditStore>();
services.AddSingleton<IAuthorityRevocationExportStateStore, InMemoryRevocationExportStateStore>();
}
}

View File

@@ -1,17 +0,0 @@
namespace StellaOps.Authority.Storage.InMemory.Initialization;
/// <summary>
/// Compatibility shim for storage initializer. In PostgreSQL mode, this is a no-op.
/// The actual initialization is handled by PostgreSQL migrations.
/// </summary>
public sealed class AuthorityStorageInitializer
{
/// <summary>
/// Initializes the database. In PostgreSQL mode, this is a no-op as migrations handle setup.
/// </summary>
public Task InitialiseAsync(object database, CancellationToken cancellationToken)
{
// No-op for PostgreSQL mode - migrations handle schema setup
return Task.CompletedTask;
}
}

View File

@@ -1,60 +0,0 @@
using StellaOps.Storage.Documents;
namespace StellaOps.Storage.Serialization.Attributes;
/// <summary>
/// Compatibility shim for storage Id attribute.
/// In PostgreSQL mode, this attribute is ignored but allows code to compile.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class StorageIdAttribute : Attribute
{
}
/// <summary>
/// Compatibility shim for storage Element attribute.
/// In PostgreSQL mode, this attribute is ignored but allows code to compile.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class StorageElementAttribute : Attribute
{
public string ElementName { get; }
public StorageElementAttribute(string elementName)
{
ElementName = elementName;
}
}
/// <summary>
/// Compatibility shim for storage Ignore attribute.
/// In PostgreSQL mode, this attribute is ignored but allows code to compile.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class StorageIgnoreAttribute : Attribute
{
}
/// <summary>
/// Compatibility shim for storage IgnoreIfNull attribute.
/// In PostgreSQL mode, this attribute is ignored but allows code to compile.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class StorageIgnoreIfNullAttribute : Attribute
{
}
/// <summary>
/// Compatibility shim for storage Representation attribute.
/// In PostgreSQL mode, this attribute is ignored but allows code to compile.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class StorageRepresentationAttribute : Attribute
{
public StorageType Representation { get; }
public StorageRepresentationAttribute(StorageType representation)
{
Representation = representation;
}
}

View File

@@ -1,79 +0,0 @@
namespace StellaOps.Storage.Documents;
/// <summary>
/// Compatibility shim for storage ObjectId.
/// In PostgreSQL mode, this wraps a GUID string.
/// </summary>
public readonly struct ObjectId : IEquatable<ObjectId>, IComparable<ObjectId>
{
private readonly string _value;
public static readonly ObjectId Empty = new(string.Empty);
public ObjectId(string value)
{
_value = value ?? string.Empty;
}
public static ObjectId GenerateNewId()
{
return new ObjectId(Guid.NewGuid().ToString("N"));
}
public static ObjectId Parse(string s)
{
return new ObjectId(s);
}
public static bool TryParse(string s, out ObjectId result)
{
result = new ObjectId(s);
return true;
}
public override string ToString() => _value;
public bool Equals(ObjectId other) => _value == other._value;
public override bool Equals(object? obj) => obj is ObjectId other && Equals(other);
public override int GetHashCode() => _value?.GetHashCode() ?? 0;
public int CompareTo(ObjectId other) => string.Compare(_value, other._value, StringComparison.Ordinal);
public static bool operator ==(ObjectId left, ObjectId right) => left.Equals(right);
public static bool operator !=(ObjectId left, ObjectId right) => !left.Equals(right);
public static implicit operator string(ObjectId id) => id._value;
public static implicit operator ObjectId(string value) => new(value);
}
/// <summary>
/// Compatibility shim for storage document type enum.
/// </summary>
public enum StorageType
{
EndOfDocument = 0,
Double = 1,
String = 2,
Document = 3,
Array = 4,
Binary = 5,
Undefined = 6,
ObjectId = 7,
Boolean = 8,
DateTime = 9,
Null = 10,
RegularExpression = 11,
JavaScript = 13,
Symbol = 14,
JavaScriptWithScope = 15,
Int32 = 16,
Timestamp = 17,
Int64 = 18,
Decimal128 = 19,
MinKey = -1,
MaxKey = 127
}

View File

@@ -1,28 +0,0 @@
namespace StellaOps.Authority.Storage.Sessions;
/// <summary>
/// Compatibility shim for database session handle. In PostgreSQL mode, this is unused.
/// </summary>
public interface IClientSessionHandle : IDisposable
{
}
/// <summary>
/// Compatibility shim for database session accessor. In PostgreSQL mode, this returns null.
/// </summary>
public interface IAuthoritySessionAccessor
{
IClientSessionHandle? CurrentSession { get; }
ValueTask<IClientSessionHandle?> GetSessionAsync(CancellationToken cancellationToken);
}
/// <summary>
/// In-memory implementation that always returns null session.
/// </summary>
public sealed class NullAuthoritySessionAccessor : IAuthoritySessionAccessor
{
public IClientSessionHandle? CurrentSession => null;
public ValueTask<IClientSessionHandle?> GetSessionAsync(CancellationToken cancellationToken)
=> ValueTask.FromResult<IClientSessionHandle?>(null);
}

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RootNamespace>StellaOps.Authority.Storage.InMemory</RootNamespace>
<Description>In-memory storage shim for Authority - provides in-memory implementations for storage interfaces while PostgreSQL migration is in progress</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
</ItemGroup>
</Project>

View File

@@ -1,110 +0,0 @@
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
namespace StellaOps.Authority.Storage.InMemory.Stores;
/// <summary>
/// Store interface for bootstrap invites.
/// </summary>
public interface IAuthorityBootstrapInviteStore
{
ValueTask<AuthorityBootstrapInviteDocument?> FindByTokenAsync(string token, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<AuthorityBootstrapInviteDocument> CreateAsync(AuthorityBootstrapInviteDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<BootstrapInviteReservationResult> TryReserveAsync(string token, string expectedType, DateTimeOffset now, string? reservedBy, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<bool> ReleaseAsync(string token, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<bool> MarkConsumedAsync(string token, string? consumedBy, DateTimeOffset consumedAt, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityBootstrapInviteDocument>> ExpireAsync(DateTimeOffset asOf, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}
/// <summary>
/// Store interface for service accounts.
/// </summary>
public interface IAuthorityServiceAccountStore
{
ValueTask<AuthorityServiceAccountDocument?> FindByAccountIdAsync(string accountId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityServiceAccountDocument>> ListAsync(string? tenant = null, CancellationToken cancellationToken = default, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityServiceAccountDocument>> ListByTenantAsync(string tenant, CancellationToken cancellationToken = default, IClientSessionHandle? session = null);
ValueTask UpsertAsync(AuthorityServiceAccountDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<bool> DeleteAsync(string accountId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}
/// <summary>
/// Store interface for clients.
/// </summary>
public interface IAuthorityClientStore
{
ValueTask<AuthorityClientDocument?> FindByClientIdAsync(string clientId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask UpsertAsync(AuthorityClientDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<bool> DeleteByClientIdAsync(string clientId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}
/// <summary>
/// Store interface for revocations.
/// </summary>
public interface IAuthorityRevocationStore
{
ValueTask UpsertAsync(AuthorityRevocationDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityRevocationDocument>> GetActiveAsync(DateTimeOffset asOf, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask RemoveAsync(string category, string revocationId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}
/// <summary>
/// Store interface for login attempts.
/// </summary>
public interface IAuthorityLoginAttemptStore
{
ValueTask InsertAsync(AuthorityLoginAttemptDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityLoginAttemptDocument>> ListRecentAsync(string subjectId, int limit, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}
/// <summary>
/// Store interface for tokens.
/// </summary>
public interface IAuthorityTokenStore
{
ValueTask<AuthorityTokenDocument?> FindByTokenIdAsync(string tokenId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<AuthorityTokenDocument?> FindByReferenceIdAsync(string referenceId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListBySubjectAsync(string subjectId, int limit, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListByScopeAsync(string scope, string tenant, DateTimeOffset? issuedAfter, int limit, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListRevokedAsync(string? tenant, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<long> CountActiveDelegationTokensAsync(string tenant, string? serviceAccountId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListActiveDelegationTokensAsync(string tenant, string? serviceAccountId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask InsertAsync(AuthorityTokenDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask UpsertAsync(AuthorityTokenDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask UpdateStatusAsync(string tokenId, string status, DateTimeOffset? revokedAt, string? reason, string? reasonDescription, IReadOnlyDictionary<string, string?>? metadata, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<bool> RevokeAsync(string tokenId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<int> RevokeBySubjectAsync(string subjectId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<TokenUsageUpdateResult> RecordUsageAsync(string tokenId, string? remoteAddress, string? userAgent, DateTimeOffset observedAt, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<int> RevokeByClientAsync(string clientId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}
/// <summary>
/// Store interface for refresh tokens.
/// </summary>
public interface IAuthorityRefreshTokenStore
{
ValueTask<AuthorityRefreshTokenDocument?> FindByTokenIdAsync(string tokenId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<AuthorityRefreshTokenDocument?> FindByHandleAsync(string handle, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask UpsertAsync(AuthorityRefreshTokenDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<bool> ConsumeAsync(string tokenId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<int> RevokeBySubjectAsync(string subjectId, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}
/// <summary>
/// Store interface for airgap audit entries.
/// </summary>
public interface IAuthorityAirgapAuditStore
{
ValueTask InsertAsync(AuthorityAirgapAuditDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<IReadOnlyList<AuthorityAirgapAuditDocument>> ListAsync(int limit, int offset, CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask<AuthorityAirgapAuditQueryResult> QueryAsync(AuthorityAirgapAuditQuery query, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}
/// <summary>
/// Tracks revocation export state to enforce monotonic bundle sequencing.
/// </summary>
public interface IAuthorityRevocationExportStateStore
{
ValueTask<AuthorityRevocationExportStateDocument?> GetAsync(CancellationToken cancellationToken, IClientSessionHandle? session = null);
ValueTask UpdateAsync(long expectedSequence, long newSequence, string bundleId, DateTimeOffset issuedAt, CancellationToken cancellationToken, IClientSessionHandle? session = null);
}

View File

@@ -1,547 +0,0 @@
using System.Collections.Concurrent;
using System.Threading;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
namespace StellaOps.Authority.Storage.InMemory.Stores;
/// <summary>
/// In-memory implementation of bootstrap invite store for development/testing.
/// </summary>
public sealed class InMemoryBootstrapInviteStore : IAuthorityBootstrapInviteStore
{
private readonly ConcurrentDictionary<string, AuthorityBootstrapInviteDocument> _invites = new(StringComparer.OrdinalIgnoreCase);
public ValueTask<AuthorityBootstrapInviteDocument?> FindByTokenAsync(string token, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_invites.TryGetValue(token, out var doc);
return ValueTask.FromResult(doc);
}
public ValueTask<AuthorityBootstrapInviteDocument> CreateAsync(AuthorityBootstrapInviteDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
document.CreatedAt = document.CreatedAt == default ? DateTimeOffset.UtcNow : document.CreatedAt;
document.IssuedAt = document.IssuedAt == default ? document.CreatedAt : document.IssuedAt;
document.Status = AuthorityBootstrapInviteStatuses.Pending;
_invites[document.Token] = document;
return ValueTask.FromResult(document);
}
public ValueTask<BootstrapInviteReservationResult> TryReserveAsync(string token, string expectedType, DateTimeOffset now, string? reservedBy, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
if (!_invites.TryGetValue(token, out var doc))
{
return ValueTask.FromResult(new BootstrapInviteReservationResult(BootstrapInviteReservationStatus.NotFound, null));
}
if (!string.Equals(doc.Type, expectedType, StringComparison.OrdinalIgnoreCase))
{
return ValueTask.FromResult(new BootstrapInviteReservationResult(BootstrapInviteReservationStatus.NotFound, null));
}
if (doc.ExpiresAt <= now)
{
doc.Status = AuthorityBootstrapInviteStatuses.Expired;
return ValueTask.FromResult(new BootstrapInviteReservationResult(BootstrapInviteReservationStatus.Expired, doc));
}
if (doc.Consumed || string.Equals(doc.Status, AuthorityBootstrapInviteStatuses.Consumed, StringComparison.OrdinalIgnoreCase))
{
return ValueTask.FromResult(new BootstrapInviteReservationResult(BootstrapInviteReservationStatus.AlreadyUsed, doc));
}
doc.Status = AuthorityBootstrapInviteStatuses.Reserved;
doc.ReservedBy = reservedBy;
doc.ReservedUntil = now.AddMinutes(15);
_invites[token] = doc;
return ValueTask.FromResult(new BootstrapInviteReservationResult(BootstrapInviteReservationStatus.Reserved, doc));
}
public ValueTask<bool> ReleaseAsync(string token, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
if (_invites.TryGetValue(token, out var doc) && string.Equals(doc.Status, AuthorityBootstrapInviteStatuses.Reserved, StringComparison.OrdinalIgnoreCase))
{
doc.Status = AuthorityBootstrapInviteStatuses.Pending;
doc.ReservedBy = null;
doc.ReservedUntil = null;
_invites[token] = doc;
return ValueTask.FromResult(true);
}
return ValueTask.FromResult(false);
}
public ValueTask<bool> MarkConsumedAsync(string token, string? consumedBy, DateTimeOffset consumedAt, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
if (_invites.TryGetValue(token, out var doc))
{
doc.Consumed = true;
doc.Status = AuthorityBootstrapInviteStatuses.Consumed;
doc.ReservedUntil = consumedAt;
doc.ReservedBy = consumedBy;
_invites[token] = doc;
return ValueTask.FromResult(true);
}
return ValueTask.FromResult(false);
}
public ValueTask<IReadOnlyList<AuthorityBootstrapInviteDocument>> ExpireAsync(DateTimeOffset asOf, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var expired = _invites.Values
.Where(i => !i.Consumed && i.ExpiresAt <= asOf)
.ToList();
foreach (var item in expired)
{
item.Status = AuthorityBootstrapInviteStatuses.Expired;
_invites.TryRemove(item.Token, out _);
}
return ValueTask.FromResult<IReadOnlyList<AuthorityBootstrapInviteDocument>>(expired);
}
}
/// <summary>
/// In-memory implementation of service account store for development/testing.
/// </summary>
public sealed class InMemoryServiceAccountStore : IAuthorityServiceAccountStore
{
private readonly ConcurrentDictionary<string, AuthorityServiceAccountDocument> _accounts = new(StringComparer.OrdinalIgnoreCase);
public ValueTask<AuthorityServiceAccountDocument?> FindByAccountIdAsync(string accountId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_accounts.TryGetValue(accountId, out var doc);
return ValueTask.FromResult(doc);
}
public ValueTask<IReadOnlyList<AuthorityServiceAccountDocument>> ListAsync(string? tenant = null, CancellationToken cancellationToken = default, IClientSessionHandle? session = null)
{
var results = tenant is null
? _accounts.Values.ToList()
: _accounts.Values.Where(a => a.Tenant == tenant).ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityServiceAccountDocument>>(results);
}
public ValueTask<IReadOnlyList<AuthorityServiceAccountDocument>> ListByTenantAsync(string tenant, CancellationToken cancellationToken = default, IClientSessionHandle? session = null)
{
var results = _accounts.Values.Where(a => string.Equals(a.Tenant, tenant, StringComparison.Ordinal)).ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityServiceAccountDocument>>(results);
}
public ValueTask UpsertAsync(AuthorityServiceAccountDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
document.UpdatedAt = DateTimeOffset.UtcNow;
_accounts[document.AccountId] = document;
return ValueTask.CompletedTask;
}
public ValueTask<bool> DeleteAsync(string accountId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
return ValueTask.FromResult(_accounts.TryRemove(accountId, out _));
}
}
/// <summary>
/// In-memory implementation of client store for development/testing.
/// </summary>
public sealed class InMemoryClientStore : IAuthorityClientStore
{
private readonly ConcurrentDictionary<string, AuthorityClientDocument> _clients = new(StringComparer.OrdinalIgnoreCase);
public ValueTask<AuthorityClientDocument?> FindByClientIdAsync(string clientId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_clients.TryGetValue(clientId, out var doc);
return ValueTask.FromResult(doc);
}
public ValueTask UpsertAsync(AuthorityClientDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
document.UpdatedAt = DateTimeOffset.UtcNow;
_clients[document.ClientId] = document;
return ValueTask.CompletedTask;
}
public ValueTask<bool> DeleteByClientIdAsync(string clientId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
return ValueTask.FromResult(_clients.TryRemove(clientId, out _));
}
}
/// <summary>
/// In-memory implementation of revocation store for development/testing.
/// </summary>
public sealed class InMemoryRevocationStore : IAuthorityRevocationStore
{
private readonly ConcurrentDictionary<string, AuthorityRevocationDocument> _revocations = new(StringComparer.OrdinalIgnoreCase);
public ValueTask UpsertAsync(AuthorityRevocationDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var key = $"{document.Category}:{document.RevocationId}";
_revocations[key] = document;
return ValueTask.CompletedTask;
}
public ValueTask<IReadOnlyList<AuthorityRevocationDocument>> GetActiveAsync(DateTimeOffset asOf, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var active = _revocations.Values
.Where(r => r.ExpiresAt is null || r.ExpiresAt > asOf)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityRevocationDocument>>(active);
}
public ValueTask RemoveAsync(string category, string revocationId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var key = $"{category}:{revocationId}";
_revocations.TryRemove(key, out _);
return ValueTask.CompletedTask;
}
}
/// <summary>
/// In-memory implementation of login attempt store for development/testing.
/// </summary>
public sealed class InMemoryLoginAttemptStore : IAuthorityLoginAttemptStore
{
private readonly ConcurrentBag<AuthorityLoginAttemptDocument> _attempts = new();
public ValueTask InsertAsync(AuthorityLoginAttemptDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_attempts.Add(document);
return ValueTask.CompletedTask;
}
public ValueTask<IReadOnlyList<AuthorityLoginAttemptDocument>> ListRecentAsync(string subjectId, int limit, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var results = _attempts
.Where(a => a.SubjectId == subjectId)
.OrderByDescending(a => a.OccurredAt)
.Take(limit)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityLoginAttemptDocument>>(results);
}
}
/// <summary>
/// In-memory implementation of token store for development/testing.
/// </summary>
public sealed class InMemoryTokenStore : IAuthorityTokenStore
{
private readonly ConcurrentDictionary<string, AuthorityTokenDocument> _tokens = new(StringComparer.OrdinalIgnoreCase);
public ValueTask<AuthorityTokenDocument?> FindByTokenIdAsync(string tokenId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_tokens.TryGetValue(tokenId, out var doc);
return ValueTask.FromResult(doc);
}
public ValueTask<AuthorityTokenDocument?> FindByReferenceIdAsync(string referenceId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var doc = _tokens.Values.FirstOrDefault(t => t.ReferenceId == referenceId);
return ValueTask.FromResult(doc);
}
public ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListBySubjectAsync(string subjectId, int limit, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var results = _tokens.Values
.Where(t => t.SubjectId == subjectId)
.OrderByDescending(t => t.CreatedAt)
.Take(limit)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityTokenDocument>>(results);
}
public ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListByScopeAsync(string scope, string tenant, DateTimeOffset? issuedAfter, int limit, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var normalizedScope = scope?.Trim();
var results = _tokens.Values
.Where(t => string.Equals(t.Tenant, tenant, StringComparison.Ordinal))
.Where(t => issuedAfter is null || t.CreatedAt >= issuedAfter.Value)
.Where(t => t.Scope.Any(s => string.Equals(s, normalizedScope, StringComparison.Ordinal)))
.OrderByDescending(t => t.CreatedAt)
.Take(limit)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityTokenDocument>>(results);
}
public ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListRevokedAsync(string? tenant, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var results = _tokens.Values
.Where(t => string.Equals(t.Status, "revoked", StringComparison.OrdinalIgnoreCase))
.Where(t => string.IsNullOrWhiteSpace(tenant) || string.Equals(t.Tenant, tenant, StringComparison.Ordinal))
.OrderBy(t => t.TokenId, StringComparer.Ordinal)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityTokenDocument>>(results);
}
public ValueTask<long> CountActiveDelegationTokensAsync(string tenant, string? serviceAccountId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var now = DateTimeOffset.UtcNow;
var count = _tokens.Values
.Where(t => string.Equals(t.Tenant, tenant, StringComparison.Ordinal))
.Where(t => string.IsNullOrWhiteSpace(serviceAccountId) || string.Equals(t.ServiceAccountId, serviceAccountId, StringComparison.Ordinal))
.Where(t => !string.Equals(t.Status, "revoked", StringComparison.OrdinalIgnoreCase))
.Where(t => t.ExpiresAt is null || t.ExpiresAt > now)
.LongCount();
return ValueTask.FromResult(count);
}
public ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListActiveDelegationTokensAsync(string tenant, string? serviceAccountId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var now = DateTimeOffset.UtcNow;
var items = _tokens.Values
.Where(t => string.Equals(t.Tenant, tenant, StringComparison.Ordinal))
.Where(t => string.IsNullOrWhiteSpace(serviceAccountId) || string.Equals(t.ServiceAccountId, serviceAccountId, StringComparison.Ordinal))
.Where(t => !string.Equals(t.Status, "revoked", StringComparison.OrdinalIgnoreCase))
.Where(t => t.ExpiresAt is null || t.ExpiresAt > now)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityTokenDocument>>(items);
}
public ValueTask InsertAsync(AuthorityTokenDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
=> UpsertAsync(document, cancellationToken, session);
public ValueTask UpsertAsync(AuthorityTokenDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_tokens[document.TokenId] = document;
return ValueTask.CompletedTask;
}
public ValueTask UpdateStatusAsync(string tokenId, string status, DateTimeOffset? revokedAt, string? reason, string? reasonDescription, IReadOnlyDictionary<string, string?>? metadata, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
if (_tokens.TryGetValue(tokenId, out var doc))
{
doc.Status = status;
doc.RevokedAt = revokedAt;
doc.RevokedReason = reason;
}
return ValueTask.CompletedTask;
}
public ValueTask<bool> RevokeAsync(string tokenId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
if (_tokens.TryGetValue(tokenId, out var doc))
{
doc.Status = "revoked";
doc.RevokedAt = DateTimeOffset.UtcNow;
return ValueTask.FromResult(true);
}
return ValueTask.FromResult(false);
}
public ValueTask<int> RevokeBySubjectAsync(string subjectId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var now = DateTimeOffset.UtcNow;
var revoked = 0;
foreach (var token in _tokens.Values.Where(t => t.SubjectId == subjectId))
{
token.Status = "revoked";
token.RevokedAt = now;
revoked++;
}
return ValueTask.FromResult(revoked);
}
public ValueTask<int> RevokeByClientAsync(string clientId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var now = DateTimeOffset.UtcNow;
var revoked = 0;
foreach (var token in _tokens.Values.Where(t => t.ClientId == clientId))
{
token.Status = "revoked";
token.RevokedAt = now;
revoked++;
}
return ValueTask.FromResult(revoked);
}
public ValueTask<TokenUsageUpdateResult> RecordUsageAsync(string tokenId, string? remoteAddress, string? userAgent, DateTimeOffset observedAt, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
if (!_tokens.TryGetValue(tokenId, out var document))
{
return ValueTask.FromResult(new TokenUsageUpdateResult(TokenUsageUpdateStatus.NotFound, remoteAddress, userAgent));
}
if (string.IsNullOrWhiteSpace(remoteAddress) && string.IsNullOrWhiteSpace(userAgent))
{
return ValueTask.FromResult(new TokenUsageUpdateResult(TokenUsageUpdateStatus.MissingMetadata, remoteAddress, userAgent));
}
var fingerprint = $"{remoteAddress}|{userAgent}";
if (document.Devices.All(d => d != fingerprint))
{
document.Devices.Add(fingerprint);
}
var status = document.Devices.Count > 1 ? TokenUsageUpdateStatus.SuspectedReplay : TokenUsageUpdateStatus.Recorded;
return ValueTask.FromResult(new TokenUsageUpdateResult(status, remoteAddress, userAgent));
}
}
/// <summary>
/// In-memory implementation of refresh token store for development/testing.
/// </summary>
public sealed class InMemoryRefreshTokenStore : IAuthorityRefreshTokenStore
{
private readonly ConcurrentDictionary<string, AuthorityRefreshTokenDocument> _tokens = new(StringComparer.OrdinalIgnoreCase);
public ValueTask<AuthorityRefreshTokenDocument?> FindByTokenIdAsync(string tokenId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_tokens.TryGetValue(tokenId, out var doc);
return ValueTask.FromResult(doc);
}
public ValueTask<AuthorityRefreshTokenDocument?> FindByHandleAsync(string handle, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var doc = _tokens.Values.FirstOrDefault(t => t.Handle == handle);
return ValueTask.FromResult(doc);
}
public ValueTask UpsertAsync(AuthorityRefreshTokenDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_tokens[document.TokenId] = document;
return ValueTask.CompletedTask;
}
public ValueTask<bool> ConsumeAsync(string tokenId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
if (_tokens.TryGetValue(tokenId, out var doc))
{
doc.ConsumedAt = DateTimeOffset.UtcNow;
return ValueTask.FromResult(true);
}
return ValueTask.FromResult(false);
}
public ValueTask<int> RevokeBySubjectAsync(string subjectId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var toRemove = _tokens.Where(kv => kv.Value.SubjectId == subjectId).Select(kv => kv.Key).ToList();
foreach (var key in toRemove)
{
_tokens.TryRemove(key, out _);
}
return ValueTask.FromResult(toRemove.Count);
}
}
/// <summary>
/// In-memory implementation of airgap audit store for development/testing.
/// </summary>
public sealed class InMemoryAirgapAuditStore : IAuthorityAirgapAuditStore
{
private readonly ConcurrentBag<AuthorityAirgapAuditDocument> _entries = new();
public ValueTask InsertAsync(AuthorityAirgapAuditDocument document, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_entries.Add(document);
return ValueTask.CompletedTask;
}
public ValueTask<IReadOnlyList<AuthorityAirgapAuditDocument>> ListAsync(int limit, int offset, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
var results = _entries
.OrderByDescending(e => e.OccurredAt)
.Skip(offset)
.Take(limit)
.ToList();
return ValueTask.FromResult<IReadOnlyList<AuthorityAirgapAuditDocument>>(results);
}
public ValueTask<AuthorityAirgapAuditQueryResult> QueryAsync(AuthorityAirgapAuditQuery query, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
ArgumentNullException.ThrowIfNull(query);
var filtered = _entries.AsEnumerable();
if (!string.IsNullOrWhiteSpace(query.Tenant))
{
filtered = filtered.Where(e => string.Equals(e.Tenant, query.Tenant, StringComparison.Ordinal));
}
if (!string.IsNullOrWhiteSpace(query.BundleId))
{
filtered = filtered.Where(e => string.Equals(e.BundleId, query.BundleId, StringComparison.Ordinal));
}
if (!string.IsNullOrWhiteSpace(query.Status))
{
filtered = filtered.Where(e => string.Equals(e.Status, query.Status, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrWhiteSpace(query.TraceId))
{
filtered = filtered.Where(e => string.Equals(e.TraceId, query.TraceId, StringComparison.OrdinalIgnoreCase));
}
filtered = filtered.OrderByDescending(e => e.OccurredAt).ThenBy(e => e.Id, StringComparer.Ordinal);
if (!string.IsNullOrWhiteSpace(query.AfterId))
{
filtered = filtered.SkipWhile(e => !string.Equals(e.Id, query.AfterId, StringComparison.Ordinal)).Skip(1);
}
var take = query.Limit <= 0 ? 50 : query.Limit;
var items = filtered.Take(take + 1).ToList();
var nextCursor = items.Count > take ? items[^1].Id : null;
if (items.Count > take)
{
items.RemoveAt(items.Count - 1);
}
return ValueTask.FromResult(new AuthorityAirgapAuditQueryResult(items, nextCursor));
}
}
/// <summary>
/// In-memory implementation of the revocation export state store.
/// </summary>
public sealed class InMemoryRevocationExportStateStore : IAuthorityRevocationExportStateStore
{
private readonly SemaphoreSlim gate = new(1, 1);
private AuthorityRevocationExportStateDocument state = new() { Sequence = 0 };
public async ValueTask<AuthorityRevocationExportStateDocument?> GetAsync(CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
await gate.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
return state;
}
finally
{
gate.Release();
}
}
public async ValueTask UpdateAsync(long expectedSequence, long newSequence, string bundleId, DateTimeOffset issuedAt, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
await gate.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
if (state.Sequence != expectedSequence)
{
throw new InvalidOperationException($"Revocation export sequence mismatch. Expected {expectedSequence}, current {state.Sequence}.");
}
state = new AuthorityRevocationExportStateDocument
{
Sequence = newSequence,
BundleId = bundleId,
IssuedAt = issuedAt
};
}
finally
{
gate.Release();
}
}
}

View File

@@ -9,9 +9,9 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.Auth.Abstractions;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Tests.Infrastructure;
using StellaOps.Configuration;
using Xunit;

View File

@@ -13,9 +13,9 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Time.Testing;
using StellaOps.Auth.Abstractions;
using StellaOps.Authority.Airgap;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Tests.Infrastructure;
using Xunit;

View File

@@ -1,10 +1,10 @@
using System.Linq;
using Microsoft.Extensions.Logging;
using StellaOps.Authority.Audit;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Cryptography.Audit;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Persistence.Sessions;
namespace StellaOps.Authority.Tests.Audit;
@@ -171,7 +171,7 @@ public class AuthorityAuditSinkTests
public List<IReadOnlyCollection<KeyValuePair<string, object?>>> Scopes { get; } = new();
public IDisposable BeginScope<TState>(TState state)
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
if (state is IReadOnlyCollection<KeyValuePair<string, object?>> scope)
{

View File

@@ -17,7 +17,6 @@ using FluentAssertions;
using Microsoft.IdentityModel.Tokens;
using StellaOps.Authority.Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
namespace StellaOps.Authority.Tests.Auth;

View File

@@ -6,9 +6,9 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Time.Testing;
using StellaOps.Authority.Bootstrap;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Cryptography.Audit;
using Xunit;

View File

@@ -17,9 +17,9 @@ using StellaOps.Auth.Abstractions;
using Microsoft.AspNetCore.Routing;
using StellaOps.Configuration;
using StellaOps.Authority.OpenIddict;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Tests.Infrastructure;
using StellaOps.Cryptography.Audit;
using Xunit;
@@ -142,7 +142,7 @@ public sealed class ServiceAccountAdminEndpointsTests : IClassFixture<AuthorityW
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountResponse[]>(default);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountResponse[]>(cancellationToken: CancellationToken.None);
Assert.NotNull(payload);
var serviceAccount = Assert.Single(payload!);
@@ -200,7 +200,7 @@ public sealed class ServiceAccountAdminEndpointsTests : IClassFixture<AuthorityW
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountTokenResponse[]>(default);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountTokenResponse[]>(cancellationToken: CancellationToken.None);
Assert.NotNull(payload);
var token = Assert.Single(payload!);
@@ -291,7 +291,7 @@ public sealed class ServiceAccountAdminEndpointsTests : IClassFixture<AuthorityW
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountRevokeResponse>(default);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountRevokeResponse>(cancellationToken: CancellationToken.None);
Assert.NotNull(payload);
Assert.Equal(2, payload!.RevokedCount);
Assert.Equal(tokenIds.OrderBy(id => id, StringComparer.Ordinal), payload.TokenIds.OrderBy(id => id, StringComparer.Ordinal));
@@ -424,7 +424,7 @@ public sealed class ServiceAccountAdminEndpointsTests : IClassFixture<AuthorityW
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountRevokeResponse>(default);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountRevokeResponse>(cancellationToken: CancellationToken.None);
Assert.NotNull(payload);
Assert.Equal(0, payload!.RevokedCount);
Assert.Empty(payload.TokenIds);
@@ -494,7 +494,7 @@ public sealed class ServiceAccountAdminEndpointsTests : IClassFixture<AuthorityW
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountRevokeResponse>(default);
var payload = await response.Content.ReadFromJsonAsync<ServiceAccountRevokeResponse>(cancellationToken: CancellationToken.None);
Assert.NotNull(payload);
Assert.Equal(1, payload!.RevokedCount);
Assert.Equal(new[] { "token-active" }, payload.TokenIds);

View File

@@ -17,7 +17,6 @@ using System.Threading.Tasks;
using FluentAssertions;
using StellaOps.Authority.Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
namespace StellaOps.Authority.Tests.Contract;

View File

@@ -13,7 +13,6 @@ using System.Security.Cryptography;
using FluentAssertions;
using Microsoft.IdentityModel.Tokens;
using Xunit;
using Xunit.Abstractions;
namespace StellaOps.Authority.Tests.Errors;

View File

@@ -37,7 +37,7 @@ public class AuthorityIdentityProviderRegistryTests
Assert.True(registry.AggregateCapabilities.SupportsClientProvisioning);
Assert.True(registry.AggregateCapabilities.SupportsBootstrap);
await using var handle = await registry.AcquireAsync("standard", default);
await using var handle = await registry.AcquireAsync("standard", cancellationToken: CancellationToken.None);
Assert.Same(providers[0], handle.Provider);
}
@@ -57,7 +57,7 @@ public class AuthorityIdentityProviderRegistryTests
Assert.Single(registry.Providers);
Assert.Equal("standard", registry.Providers.First().Name);
Assert.True(registry.TryGet("standard", out var provider));
await using var handle = await registry.AcquireAsync("standard", default);
await using var handle = await registry.AcquireAsync("standard", cancellationToken: CancellationToken.None);
Assert.Same(providers[0], handle.Provider);
Assert.Equal("standard", provider!.Name);
}
@@ -84,8 +84,8 @@ public class AuthorityIdentityProviderRegistryTests
using var serviceProvider = services.BuildServiceProvider();
var registry = new AuthorityIdentityProviderRegistry(serviceProvider, NullLogger<AuthorityIdentityProviderRegistry>.Instance);
await using var first = await registry.AcquireAsync("scoped", default);
await using var second = await registry.AcquireAsync("scoped", default);
await using var first = await registry.AcquireAsync("scoped", cancellationToken: CancellationToken.None);
await using var second = await registry.AcquireAsync("scoped", cancellationToken: CancellationToken.None);
var firstPlugin = Assert.IsType<ScopedIdentityProviderPlugin>(first.Provider);
var secondPlugin = Assert.IsType<ScopedIdentityProviderPlugin>(second.Provider);

View File

@@ -9,10 +9,10 @@ using Microsoft.Extensions.Hosting;
using Xunit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using StellaOps.Authority.Storage.InMemory.Extensions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.Postgres;
using StellaOps.Authority.Persistence.Extensions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.Postgres;
namespace StellaOps.Authority.Tests.Infrastructure;

View File

@@ -1,7 +1,7 @@
using System.Collections.Concurrent;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
namespace StellaOps.Authority.Tests.Infrastructure;

View File

@@ -16,7 +16,6 @@ using System.Threading.Tasks;
using FluentAssertions;
using StellaOps.Authority.Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
namespace StellaOps.Authority.Tests.Negative;

View File

@@ -48,12 +48,12 @@ public sealed class AuthorityAckTokenIssuerTests
Metadata = new() { ["priority"] = "high" }
};
var result = await issuer.IssueAsync(request, requesterHasEscalateScope: false, cancellationToken: default);
var result = await issuer.IssueAsync(request, requesterHasEscalateScope: false, cancellationToken: CancellationToken.None);
Assert.Equal("application/vnd.stellaops.notify-ack-token+json", result.Envelope.PayloadType);
Assert.NotNull(result.Envelope.Payload);
Assert.Single(result.Envelope.Signatures);
var verification = await verifier.VerifyAsync(result.Envelope, "ack", request.Tenant, default);
var verification = await verifier.VerifyAsync(result.Envelope, "ack", request.Tenant, cancellationToken: CancellationToken.None);
Assert.Equal(request.Tenant, verification.Payload.Tenant);
Assert.Equal(request.NotificationId, verification.Payload.NotificationId);
Assert.Contains("ack", verification.Payload.Actions);
@@ -99,8 +99,8 @@ public sealed class AuthorityAckTokenIssuerTests
Actions = new[] { "ack" }
};
var result = await issuer.IssueAsync(request, requesterHasEscalateScope: false, cancellationToken: default);
await Assert.ThrowsAsync<InvalidOperationException>(() => verifier.VerifyAsync(result.Envelope, "escalate", request.Tenant, default));
var result = await issuer.IssueAsync(request, requesterHasEscalateScope: false, cancellationToken: CancellationToken.None);
await Assert.ThrowsAsync<InvalidOperationException>(() => verifier.VerifyAsync(result.Envelope, "escalate", request.Tenant, cancellationToken: CancellationToken.None));
}
finally
{

View File

@@ -14,7 +14,6 @@ using System.Threading.Tasks;
using FluentAssertions;
using StellaOps.Authority.Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
namespace StellaOps.Authority.Tests.Observability;

View File

@@ -30,9 +30,9 @@ using StellaOps.Authority.Airgap;
using StellaOps.Authority.OpenIddict;
using StellaOps.Authority.OpenIddict.Handlers;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.RateLimiting;
using StellaOps.Cryptography.Audit;
using Xunit;

View File

@@ -23,9 +23,9 @@ using StellaOps.Authority.OpenIddict.Handlers;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.RateLimiting;
using StellaOps.Authority.Airgap;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Cryptography.Audit;
using StellaOps.Configuration;
using StellaOps.Auth.Abstractions;

View File

@@ -5,9 +5,9 @@ using Microsoft.Extensions.Time.Testing;
using OpenIddict.Abstractions;
using OpenIddict.Server;
using StellaOps.Authority.OpenIddict.Handlers;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using Xunit;
namespace StellaOps.Authority.Tests.OpenIddict;

View File

@@ -69,7 +69,7 @@ public sealed class VulnPermalinkServiceTests
var expectedNow = fakeTime.GetUtcNow();
var response = await service.CreateAsync(request, default);
var response = await service.CreateAsync(request, cancellationToken: CancellationToken.None);
Assert.NotNull(response.Token);
Assert.Equal(expectedNow, response.IssuedAt);

View File

@@ -13,7 +13,6 @@ using System.Text;
using FluentAssertions;
using Microsoft.IdentityModel.Tokens;
using Xunit;
using Xunit.Abstractions;
namespace StellaOps.Authority.Tests.Signing;
@@ -82,12 +81,14 @@ public sealed class TokenSignVerifyRoundtripTests
// Assert
principal.Should().NotBeNull();
validatedToken.Should().NotBeNull();
validatedToken.SignatureAlgorithm.Should().Be(SecurityAlgorithms.RsaSha256);
var jwtToken = validatedToken as JwtSecurityToken;
jwtToken.Should().NotBeNull();
jwtToken!.SignatureAlgorithm.Should().Be(SecurityAlgorithms.RsaSha256);
var subClaim = principal.FindFirst("sub")?.Value;
subClaim.Should().Be("user-12345");
_output.WriteLine("RSA RS256 sign/verify roundtrip succeeded");
_output.WriteLine("RSA RS256 sign/verify roundtrip succeeded");
}
[Theory]
@@ -124,9 +125,11 @@ public sealed class TokenSignVerifyRoundtripTests
var principal = handler.ValidateToken(tokenString, validationParams, out var validatedToken);
// Assert
validatedToken.SignatureAlgorithm.Should().Be(algorithm);
var jwtToken = validatedToken as JwtSecurityToken;
jwtToken.Should().NotBeNull();
jwtToken!.SignatureAlgorithm.Should().Be(algorithm);
_output.WriteLine($"Algorithm {algorithm} works correctly");
_output.WriteLine($"Algorithm {algorithm} works correctly");
}
#endregion
@@ -175,9 +178,11 @@ public sealed class TokenSignVerifyRoundtripTests
// Assert
principal.Should().NotBeNull();
validatedToken.SignatureAlgorithm.Should().Be(SecurityAlgorithms.EcdsaSha256);
var jwtToken = validatedToken as JwtSecurityToken;
jwtToken.Should().NotBeNull();
jwtToken!.SignatureAlgorithm.Should().Be(SecurityAlgorithms.EcdsaSha256);
_output.WriteLine("ECDSA ES256 sign/verify roundtrip succeeded");
_output.WriteLine("ECDSA ES256 sign/verify roundtrip succeeded");
}
#endregion
@@ -216,9 +221,11 @@ public sealed class TokenSignVerifyRoundtripTests
// Assert
principal.Should().NotBeNull();
validatedToken.SignatureAlgorithm.Should().Be(SecurityAlgorithms.HmacSha256);
var jwtToken = validatedToken as JwtSecurityToken;
jwtToken.Should().NotBeNull();
jwtToken!.SignatureAlgorithm.Should().Be(SecurityAlgorithms.HmacSha256);
_output.WriteLine("HMAC HS256 sign/verify roundtrip succeeded");
_output.WriteLine("HMAC HS256 sign/verify roundtrip succeeded");
}
#endregion

View File

@@ -2,18 +2,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<Using Include="Xunit.Abstractions" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" />
<PackageReference Include="Moq" />
<PackageReference Include="xunit.runner.visualstudio" >
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StellaOps.Authority\StellaOps.Authority.csproj" />
<ProjectReference Include="..\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Auth.Security/StellaOps.Auth.Security.csproj" />
<ProjectReference Include="../../__Libraries/StellaOps.Authority.Persistence/StellaOps.Authority.Persistence.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
<!-- Storage now uses PostgreSQL via Authority project reference -->
<ItemGroup>
<Compile Include="../../../../tests/shared/OpenSslLegacyShim.cs" Link="Infrastructure/OpenSslLegacyShim.cs" />
<None Include="../../../../tests/native/openssl-1.1/linux-x64/*" Link="native/linux-x64/%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
<Compile Include="../../../__Tests/shared/OpenSslLegacyShim.cs" Link="Infrastructure/OpenSslLegacyShim.cs" />
<None Include="../../../__Tests/native/openssl-1.1/linux-x64/*" Link="native/linux-x64/%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Project>
</Project>

View File

@@ -1,398 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority", "StellaOps.Authority\StellaOps.Authority.csproj", "{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions", "StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj", "{B4E5DC28-0693-4708-8B07-5206053CACDB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugin.Standard", "StellaOps.Authority.Plugin.Standard\StellaOps.Authority.Plugin.Standard.csproj", "{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions", "StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj", "{A399A886-B7B7-4ACE-811E-3F4B7051A725}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.ServerIntegration", "StellaOps.Auth.ServerIntegration\StellaOps.Auth.ServerIntegration.csproj", "{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client", "StellaOps.Auth.Client\StellaOps.Auth.Client.csproj", "{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Configuration.Tests", "..\StellaOps.Configuration.Tests\StellaOps.Configuration.Tests.csproj", "{A33529C5-1552-4216-B080-B621F077BE10}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Plugin", "..\StellaOps.Plugin\StellaOps.Plugin.csproj", "{C8F10390-5ED3-4638-A27E-F53F07583745}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "..\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{D3FCB965-348C-4050-B4F7-7E065A562E2C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Configuration", "..\StellaOps.Configuration\StellaOps.Configuration.csproj", "{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions.Tests", "StellaOps.Authority.Plugins.Abstractions.Tests\StellaOps.Authority.Plugins.Abstractions.Tests.csproj", "{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Testing", "..\StellaOps.Concelier.Testing\StellaOps.Concelier.Testing.csproj", "{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Common", "..\StellaOps.Concelier.Connector.Common\StellaOps.Concelier.Connector.Common.csproj", "{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Core", "..\StellaOps.Concelier.Core\StellaOps.Concelier.Core.csproj", "{17829125-C0F5-47E6-A16C-EC142BD58220}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Models", "..\StellaOps.Concelier.Models\StellaOps.Concelier.Models.csproj", "{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Normalization", "..\StellaOps.Concelier.Normalization\StellaOps.Concelier.Normalization.csproj", "{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Tests", "StellaOps.Authority.Tests\StellaOps.Authority.Tests.csproj", "{D719B01C-2424-4DAB-94B9-C9B6004F450B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugin.Standard.Tests", "StellaOps.Authority.Plugin.Standard.Tests\StellaOps.Authority.Plugin.Standard.Tests.csproj", "{0C222CD9-96B1-4152-BD29-65FFAE27C880}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions.Tests", "StellaOps.Auth.Abstractions.Tests\StellaOps.Auth.Abstractions.Tests.csproj", "{4A5D29B8-959A-4EAC-A827-979CD058EC16}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.ServerIntegration.Tests", "StellaOps.Auth.ServerIntegration.Tests\StellaOps.Auth.ServerIntegration.Tests.csproj", "{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client.Tests", "StellaOps.Auth.Client.Tests\StellaOps.Auth.Client.Tests.csproj", "{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography", "..\StellaOps.Cryptography\StellaOps.Cryptography.csproj", "{35D22E43-729A-4D43-A289-5A0E96BA0199}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Tests", "..\StellaOps.Cryptography.Tests\StellaOps.Cryptography.Tests.csproj", "{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.DependencyInjection", "..\StellaOps.Cryptography.DependencyInjection\StellaOps.Cryptography.DependencyInjection.csproj", "{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Security", "..\StellaOps.Auth.Security\StellaOps.Auth.Security.csproj", "{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugin.Ldap", "StellaOps.Authority.Plugin.Ldap\StellaOps.Authority.Plugin.Ldap.csproj", "{8B07FB7E-6C49-49F9-8919-5708E3C39907}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugin.Ldap.Tests", "StellaOps.Authority.Plugin.Ldap.Tests\StellaOps.Authority.Plugin.Ldap.Tests.csproj", "{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Debug|x64.ActiveCfg = Debug|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Debug|x64.Build.0 = Debug|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Debug|x86.ActiveCfg = Debug|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Debug|x86.Build.0 = Debug|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Release|Any CPU.Build.0 = Release|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Release|x64.ActiveCfg = Release|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Release|x64.Build.0 = Release|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Release|x86.ActiveCfg = Release|Any CPU
{93CEF308-E217-41F3-BBF3-AFC1D32D9B4C}.Release|x86.Build.0 = Release|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Debug|x64.ActiveCfg = Debug|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Debug|x64.Build.0 = Debug|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Debug|x86.ActiveCfg = Debug|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Debug|x86.Build.0 = Debug|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Release|Any CPU.Build.0 = Release|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Release|x64.ActiveCfg = Release|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Release|x64.Build.0 = Release|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Release|x86.ActiveCfg = Release|Any CPU
{B4E5DC28-0693-4708-8B07-5206053CACDB}.Release|x86.Build.0 = Release|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Debug|x64.ActiveCfg = Debug|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Debug|x64.Build.0 = Debug|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Debug|x86.ActiveCfg = Debug|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Debug|x86.Build.0 = Debug|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Release|Any CPU.Build.0 = Release|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Release|x64.ActiveCfg = Release|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Release|x64.Build.0 = Release|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Release|x86.ActiveCfg = Release|Any CPU
{753A4FF4-BE1D-4361-9FE5-F2FF7CBDE3E3}.Release|x86.Build.0 = Release|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Debug|x64.ActiveCfg = Debug|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Debug|x64.Build.0 = Debug|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Debug|x86.ActiveCfg = Debug|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Debug|x86.Build.0 = Debug|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Release|Any CPU.Build.0 = Release|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Release|x64.ActiveCfg = Release|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Release|x64.Build.0 = Release|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Release|x86.ActiveCfg = Release|Any CPU
{A399A886-B7B7-4ACE-811E-3F4B7051A725}.Release|x86.Build.0 = Release|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Debug|x64.ActiveCfg = Debug|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Debug|x64.Build.0 = Debug|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Debug|x86.ActiveCfg = Debug|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Debug|x86.Build.0 = Debug|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Release|Any CPU.Build.0 = Release|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Release|x64.ActiveCfg = Release|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Release|x64.Build.0 = Release|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Release|x86.ActiveCfg = Release|Any CPU
{0BA36155-0024-42D9-9DC9-8F85A72F9CA6}.Release|x86.Build.0 = Release|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Debug|x64.ActiveCfg = Debug|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Debug|x64.Build.0 = Debug|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Debug|x86.ActiveCfg = Debug|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Debug|x86.Build.0 = Debug|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Release|Any CPU.Build.0 = Release|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Release|x64.ActiveCfg = Release|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Release|x64.Build.0 = Release|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Release|x86.ActiveCfg = Release|Any CPU
{9C8918FA-626F-41DE-8B89-4E216DCBF2A8}.Release|x86.Build.0 = Release|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Debug|x64.ActiveCfg = Debug|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Debug|x64.Build.0 = Debug|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Debug|x86.ActiveCfg = Debug|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Debug|x86.Build.0 = Debug|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Release|Any CPU.Build.0 = Release|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Release|x64.ActiveCfg = Release|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Release|x64.Build.0 = Release|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Release|x86.ActiveCfg = Release|Any CPU
{A33529C5-1552-4216-B080-B621F077BE10}.Release|x86.Build.0 = Release|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Debug|x64.ActiveCfg = Debug|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Debug|x64.Build.0 = Debug|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Debug|x86.ActiveCfg = Debug|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Debug|x86.Build.0 = Debug|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Release|Any CPU.Build.0 = Release|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Release|x64.ActiveCfg = Release|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Release|x64.Build.0 = Release|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Release|x86.ActiveCfg = Release|Any CPU
{C8F10390-5ED3-4638-A27E-F53F07583745}.Release|x86.Build.0 = Release|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Debug|x64.ActiveCfg = Debug|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Debug|x64.Build.0 = Debug|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Debug|x86.ActiveCfg = Debug|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Debug|x86.Build.0 = Debug|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Release|Any CPU.Build.0 = Release|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Release|x64.ActiveCfg = Release|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Release|x64.Build.0 = Release|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Release|x86.ActiveCfg = Release|Any CPU
{D3FCB965-348C-4050-B4F7-7E065A562E2C}.Release|x86.Build.0 = Release|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Debug|x64.ActiveCfg = Debug|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Debug|x64.Build.0 = Debug|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Debug|x86.ActiveCfg = Debug|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Debug|x86.Build.0 = Debug|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Release|Any CPU.Build.0 = Release|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Release|x64.ActiveCfg = Release|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Release|x64.Build.0 = Release|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Release|x86.ActiveCfg = Release|Any CPU
{3CB099C3-F41F-46AD-B81D-DB31C4EF643A}.Release|x86.Build.0 = Release|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Debug|x64.ActiveCfg = Debug|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Debug|x64.Build.0 = Debug|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Debug|x86.ActiveCfg = Debug|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Debug|x86.Build.0 = Debug|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Release|Any CPU.Build.0 = Release|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Release|x64.ActiveCfg = Release|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Release|x64.Build.0 = Release|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Release|x86.ActiveCfg = Release|Any CPU
{EE97137B-22AF-4A84-9F65-9B4C6468B3CF}.Release|x86.Build.0 = Release|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Debug|x64.ActiveCfg = Debug|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Debug|x64.Build.0 = Debug|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Debug|x86.ActiveCfg = Debug|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Debug|x86.Build.0 = Debug|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Release|Any CPU.Build.0 = Release|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Release|x64.ActiveCfg = Release|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Release|x64.Build.0 = Release|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Release|x86.ActiveCfg = Release|Any CPU
{D48E48BF-80C8-43DA-8BE6-E2B9E769C49E}.Release|x86.Build.0 = Release|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Debug|x64.ActiveCfg = Debug|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Debug|x64.Build.0 = Debug|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Debug|x86.ActiveCfg = Debug|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Debug|x86.Build.0 = Debug|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Release|Any CPU.Build.0 = Release|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Release|x64.ActiveCfg = Release|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Release|x64.Build.0 = Release|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Release|x86.ActiveCfg = Release|Any CPU
{E0B9CD7A-C4FF-44EB-BE04-9B998C1C4166}.Release|x86.Build.0 = Release|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Debug|x64.ActiveCfg = Debug|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Debug|x64.Build.0 = Debug|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Debug|x86.ActiveCfg = Debug|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Debug|x86.Build.0 = Debug|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Release|Any CPU.Build.0 = Release|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Release|x64.ActiveCfg = Release|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Release|x64.Build.0 = Release|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Release|x86.ActiveCfg = Release|Any CPU
{17829125-C0F5-47E6-A16C-EC142BD58220}.Release|x86.Build.0 = Release|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Debug|x64.ActiveCfg = Debug|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Debug|x64.Build.0 = Debug|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Debug|x86.ActiveCfg = Debug|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Debug|x86.Build.0 = Debug|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Release|Any CPU.Build.0 = Release|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Release|x64.ActiveCfg = Release|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Release|x64.Build.0 = Release|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Release|x86.ActiveCfg = Release|Any CPU
{9B4BA030-C979-4191-8B4F-7E2AD9F88A94}.Release|x86.Build.0 = Release|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Debug|x64.ActiveCfg = Debug|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Debug|x64.Build.0 = Debug|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Debug|x86.ActiveCfg = Debug|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Debug|x86.Build.0 = Debug|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Release|Any CPU.Build.0 = Release|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Release|x64.ActiveCfg = Release|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Release|x64.Build.0 = Release|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Release|x86.ActiveCfg = Release|Any CPU
{26B58A9B-DB0B-4E3D-9827-3722859E5FB4}.Release|x86.Build.0 = Release|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Debug|x64.ActiveCfg = Debug|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Debug|x64.Build.0 = Debug|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Debug|x86.ActiveCfg = Debug|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Debug|x86.Build.0 = Debug|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Release|Any CPU.Build.0 = Release|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Release|x64.ActiveCfg = Release|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Release|x64.Build.0 = Release|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Release|x86.ActiveCfg = Release|Any CPU
{D719B01C-2424-4DAB-94B9-C9B6004F450B}.Release|x86.Build.0 = Release|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Debug|x64.ActiveCfg = Debug|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Debug|x64.Build.0 = Debug|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Debug|x86.ActiveCfg = Debug|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Debug|x86.Build.0 = Debug|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Release|Any CPU.Build.0 = Release|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Release|x64.ActiveCfg = Release|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Release|x64.Build.0 = Release|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Release|x86.ActiveCfg = Release|Any CPU
{0C222CD9-96B1-4152-BD29-65FFAE27C880}.Release|x86.Build.0 = Release|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Debug|x64.ActiveCfg = Debug|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Debug|x64.Build.0 = Debug|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Debug|x86.ActiveCfg = Debug|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Debug|x86.Build.0 = Debug|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Release|Any CPU.Build.0 = Release|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Release|x64.ActiveCfg = Release|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Release|x64.Build.0 = Release|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Release|x86.ActiveCfg = Release|Any CPU
{4A5D29B8-959A-4EAC-A827-979CD058EC16}.Release|x86.Build.0 = Release|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Debug|x64.ActiveCfg = Debug|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Debug|x64.Build.0 = Debug|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Debug|x86.ActiveCfg = Debug|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Debug|x86.Build.0 = Debug|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Release|Any CPU.Build.0 = Release|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Release|x64.ActiveCfg = Release|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Release|x64.Build.0 = Release|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Release|x86.ActiveCfg = Release|Any CPU
{CB7FD547-1EC7-4A6F-87FE-F73003512AFE}.Release|x86.Build.0 = Release|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Debug|x64.ActiveCfg = Debug|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Debug|x64.Build.0 = Debug|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Debug|x86.ActiveCfg = Debug|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Debug|x86.Build.0 = Debug|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Release|Any CPU.Build.0 = Release|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Release|x64.ActiveCfg = Release|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Release|x64.Build.0 = Release|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Release|x86.ActiveCfg = Release|Any CPU
{2DB48E45-BEFE-40FC-8E7D-1697A8EB0749}.Release|x86.Build.0 = Release|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Debug|x64.ActiveCfg = Debug|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Debug|x64.Build.0 = Debug|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Debug|x86.ActiveCfg = Debug|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Debug|x86.Build.0 = Debug|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Release|Any CPU.Build.0 = Release|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Release|x64.ActiveCfg = Release|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Release|x64.Build.0 = Release|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Release|x86.ActiveCfg = Release|Any CPU
{35D22E43-729A-4D43-A289-5A0E96BA0199}.Release|x86.Build.0 = Release|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Debug|Any CPU.Build.0 = Debug|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Debug|x64.ActiveCfg = Debug|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Debug|x64.Build.0 = Debug|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Debug|x86.ActiveCfg = Debug|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Debug|x86.Build.0 = Debug|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Release|Any CPU.ActiveCfg = Release|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Release|Any CPU.Build.0 = Release|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Release|x64.ActiveCfg = Release|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Release|x64.Build.0 = Release|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Release|x86.ActiveCfg = Release|Any CPU
{84AEC0C8-EE60-4AB1-A59B-B8E7CCFC0A25}.Release|x86.Build.0 = Release|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Debug|x64.ActiveCfg = Debug|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Debug|x64.Build.0 = Debug|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Debug|x86.ActiveCfg = Debug|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Debug|x86.Build.0 = Debug|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Release|Any CPU.Build.0 = Release|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Release|x64.ActiveCfg = Release|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Release|x64.Build.0 = Release|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Release|x86.ActiveCfg = Release|Any CPU
{159A9B4E-61F8-4A82-8F6E-D01E3FB7E18F}.Release|x86.Build.0 = Release|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Debug|x64.ActiveCfg = Debug|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Debug|x64.Build.0 = Debug|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Debug|x86.ActiveCfg = Debug|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Debug|x86.Build.0 = Debug|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Release|Any CPU.Build.0 = Release|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Release|x64.ActiveCfg = Release|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Release|x64.Build.0 = Release|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Release|x86.ActiveCfg = Release|Any CPU
{ACEFD2D2-D4B9-47FB-91F2-1EA94C28D93C}.Release|x86.Build.0 = Release|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Debug|x64.ActiveCfg = Debug|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Debug|x64.Build.0 = Debug|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Debug|x86.ActiveCfg = Debug|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Debug|x86.Build.0 = Debug|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Release|Any CPU.Build.0 = Release|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Release|x64.ActiveCfg = Release|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Release|x64.Build.0 = Release|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Release|x86.ActiveCfg = Release|Any CPU
{8B07FB7E-6C49-49F9-8919-5708E3C39907}.Release|x86.Build.0 = Release|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Debug|x64.ActiveCfg = Debug|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Debug|x64.Build.0 = Debug|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Debug|x86.ActiveCfg = Debug|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Debug|x86.Build.0 = Debug|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Release|Any CPU.Build.0 = Release|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Release|x64.ActiveCfg = Release|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Release|x64.Build.0 = Release|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Release|x86.ActiveCfg = Release|Any CPU
{3C2B782A-19F7-4B2A-8FD1-9DEF0059FA2F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
namespace StellaOps.Authority.Airgap;
@@ -93,13 +93,13 @@ internal sealed class AuthorityAirgapAuditService : IAuthorityAirgapAuditService
return new AirgapAuditEntry(
document.Id,
document.Tenant,
document.Tenant ?? string.Empty,
document.SubjectId,
document.Username,
document.DisplayName,
document.ClientId,
document.BundleId,
document.Status,
document.BundleId ?? string.Empty,
document.Status ?? string.Empty,
document.Reason,
document.TraceId,
document.OccurredAt,

View File

@@ -5,8 +5,8 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Cryptography.Audit;
namespace StellaOps.Authority.Audit;

View File

@@ -3,8 +3,8 @@ using System.Collections.Generic;
using System.Globalization;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Cryptography.Audit;
namespace StellaOps.Authority.Bootstrap;

View File

@@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Http;
using OpenIddict.Abstractions;
using StellaOps.Auth.Abstractions;
using StellaOps.Auth.ServerIntegration;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Tenants;
using StellaOps.Cryptography.Audit;

View File

@@ -10,8 +10,8 @@ using Microsoft.AspNetCore.Mvc;
using StellaOps.Auth.Abstractions;
using StellaOps.Auth.ServerIntegration;
using StellaOps.Authority.Console;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
namespace StellaOps.Authority.Observability;

View File

@@ -17,9 +17,9 @@ using StellaOps.Auth.Abstractions;
using StellaOps.Authority.Airgap;
using StellaOps.Authority.OpenIddict;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.RateLimiting;
using StellaOps.Authority.Security;
using StellaOps.Configuration;
@@ -1826,7 +1826,7 @@ internal sealed class HandleClientCredentialsHandler : IOpenIddictServerHandler<
}
var session = await sessionAccessor.GetSessionAsync(context.CancellationToken).ConfigureAwait(false);
await PersistTokenAsync(context, document, tokenId, grantedScopes, session, activity).ConfigureAwait(false);
await PersistTokenAsync(context, document, tokenId, grantedScopes, session!, activity).ConfigureAwait(false);
context.Principal = principal;
context.HandleRequest();

View File

@@ -19,8 +19,8 @@ using StellaOps.Authority.OpenIddict;
using StellaOps.Auth.Abstractions;
using StellaOps.Authority.RateLimiting;
using StellaOps.Authority.Security;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Cryptography.Audit;
using Microsoft.IdentityModel.Tokens;

View File

@@ -15,8 +15,8 @@ using StellaOps.Authority.Airgap;
using StellaOps.Authority.OpenIddict;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.RateLimiting;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Cryptography.Audit;
namespace StellaOps.Authority.OpenIddict.Handlers;

View File

@@ -11,8 +11,8 @@ using OpenIddict.Server;
using StellaOps.Auth.Abstractions;
using StellaOps.Authority.Airgap;
using StellaOps.Authority.Security;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
namespace StellaOps.Authority.OpenIddict.Handlers;

View File

@@ -6,8 +6,8 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
using OpenIddict.Server;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
namespace StellaOps.Authority.OpenIddict.Handlers;

View File

@@ -11,9 +11,9 @@ using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
using OpenIddict.Extensions;
using OpenIddict.Server;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Auth.Abstractions;
namespace StellaOps.Authority.OpenIddict.Handlers;
@@ -58,22 +58,22 @@ internal sealed class PersistTokensHandler : IOpenIddictServerHandler<OpenIddict
if (context.AccessTokenPrincipal is ClaimsPrincipal accessPrincipal)
{
await PersistAsync(accessPrincipal, OpenIddictConstants.TokenTypeHints.AccessToken, issuedAt, session, context.CancellationToken).ConfigureAwait(false);
await PersistAsync(accessPrincipal, OpenIddictConstants.TokenTypeHints.AccessToken, issuedAt, session!, context.CancellationToken).ConfigureAwait(false);
}
if (context.RefreshTokenPrincipal is ClaimsPrincipal refreshPrincipal)
{
await PersistAsync(refreshPrincipal, OpenIddictConstants.TokenTypeHints.RefreshToken, issuedAt, session, context.CancellationToken).ConfigureAwait(false);
await PersistAsync(refreshPrincipal, OpenIddictConstants.TokenTypeHints.RefreshToken, issuedAt, session!, context.CancellationToken).ConfigureAwait(false);
}
if (context.AuthorizationCodePrincipal is ClaimsPrincipal authorizationPrincipal)
{
await PersistAsync(authorizationPrincipal, OpenIddictConstants.TokenTypeHints.AuthorizationCode, issuedAt, session, context.CancellationToken).ConfigureAwait(false);
await PersistAsync(authorizationPrincipal, OpenIddictConstants.TokenTypeHints.AuthorizationCode, issuedAt, session!, context.CancellationToken).ConfigureAwait(false);
}
if (context.DeviceCodePrincipal is ClaimsPrincipal devicePrincipal)
{
await PersistAsync(devicePrincipal, OpenIddictConstants.TokenTypeHints.DeviceCode, issuedAt, session, context.CancellationToken).ConfigureAwait(false);
await PersistAsync(devicePrincipal, OpenIddictConstants.TokenTypeHints.DeviceCode, issuedAt, session!, context.CancellationToken).ConfigureAwait(false);
}
}

View File

@@ -15,9 +15,9 @@ using StellaOps.Auth.Abstractions;
using StellaOps.Authority.OpenIddict;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Authority.RateLimiting;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Cryptography.Audit;
using StellaOps.Authority.Security;
@@ -213,7 +213,7 @@ internal sealed class ValidateAccessTokenHandler : IOpenIddictServerHandler<Open
if (!context.IsRejected && tokenDocument is not null)
{
await TrackTokenUsageAsync(context, tokenDocument, context.Principal, session).ConfigureAwait(false);
await TrackTokenUsageAsync(context, tokenDocument, context.Principal, session!).ConfigureAwait(false);
}
var clientId = context.Principal.GetClaim(OpenIddictConstants.Claims.ClientId);

View File

@@ -1,3 +1,3 @@
public partial class Program
file sealed partial class Program
{
}

View File

@@ -33,11 +33,11 @@ using StellaOps.Authority.Plugins;
using StellaOps.Authority.Bootstrap;
using StellaOps.Authority.Console;
using StellaOps.Authority.Console.Admin;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.Postgres;
using StellaOps.Authority.Storage.PostgresAdapters;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.Postgres;
using StellaOps.Authority.Persistence.PostgresAdapters;
using StellaOps.Authority.RateLimiting;
using StellaOps.Configuration;
using StellaOps.Plugin.DependencyInjection;
@@ -55,7 +55,7 @@ using System.Text;
using StellaOps.Authority.Signing;
using StellaOps.Cryptography;
using StellaOps.Cryptography.Kms;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Security;
using StellaOps.Authority.OpenApi;
using StellaOps.Auth.Abstractions;
@@ -3144,11 +3144,14 @@ app.Run();
static PluginHostOptions BuildPluginHostOptions(StellaOpsAuthorityOptions options, string basePath)
{
var pluginDirectory = options.PluginDirectories.FirstOrDefault();
// Authority project is 4 levels deep: src/Authority/StellaOps.Authority/StellaOps.Authority/
// Navigate up to repo root, then into plugins/authority
var repoRoot = Path.GetFullPath(Path.Combine(basePath, "..", "..", "..", ".."));
var hostOptions = new PluginHostOptions
{
BaseDirectory = basePath,
BaseDirectory = repoRoot,
PluginsDirectory = string.IsNullOrWhiteSpace(pluginDirectory)
? "StellaOps.Authority.PluginBinaries"
? Path.Combine("plugins", "authority")
: pluginDirectory,
PrimaryPrefix = "StellaOps.Authority"
};

View File

@@ -10,8 +10,8 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Configuration;
namespace StellaOps.Authority.Revocation;

View File

@@ -1,5 +1,5 @@
using System;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Persistence.Documents;
namespace StellaOps.Authority.Security;

View File

@@ -9,7 +9,7 @@ using System.Formats.Asn1;
using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Configuration;
using Microsoft.IdentityModel.Tokens;

View File

@@ -1,7 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Persistence.Documents;
namespace StellaOps.Authority.Security;

View File

@@ -9,21 +9,20 @@
<DefineConstants>$(DefineConstants);STELLAOPS_AUTH_SECURITY</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenIddict.Abstractions" Version="6.4.0" />
<PackageReference Include="OpenIddict.Server" Version="6.4.0" />
<PackageReference Include="OpenIddict.Server.AspNetCore" Version="6.4.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="StackExchange.Redis" Version="2.8.37" />
<PackageReference Include="YamlDotNet" Version="13.7.1" />
<PackageReference Include="OpenIddict.Abstractions" />
<PackageReference Include="OpenIddict.Server" />
<PackageReference Include="OpenIddict.Server.AspNetCore" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
<PackageReference Include="Serilog.AspNetCore" />
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="StackExchange.Redis" />
<PackageReference Include="YamlDotNet" />
<ProjectReference Include="..\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj" />
<ProjectReference Include="..\StellaOps.Authority.Plugin.Standard\StellaOps.Authority.Plugin.Standard.csproj" />
<ProjectReference Include="..\StellaOps.Authority.Storage.InMemory\StellaOps.Authority.Storage.InMemory.csproj" />
<ProjectReference Include="..\..\__Libraries\StellaOps.Authority.Storage.Postgres\StellaOps.Authority.Storage.Postgres.csproj" />
<ProjectReference Include="..\..\__Libraries\StellaOps.Authority.Persistence\StellaOps.Authority.Persistence.csproj" />
<ProjectReference Include="..\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
<ProjectReference Include="..\StellaOps.Auth.ServerIntegration\StellaOps.Auth.ServerIntegration.csproj" />
<ProjectReference Include="..\StellaOps.Auth.Client\StellaOps.Auth.Client.csproj" />

View File

@@ -1,10 +1,10 @@
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
namespace StellaOps.Authority.Storage.PostgresAdapters;
namespace StellaOps.Authority.Persistence.PostgresAdapters;
/// <summary>
/// PostgreSQL-backed implementation of <see cref="IAuthorityAirgapAuditStore"/>.

View File

@@ -1,10 +1,10 @@
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
namespace StellaOps.Authority.Storage.PostgresAdapters;
namespace StellaOps.Authority.Persistence.PostgresAdapters;
/// <summary>
/// PostgreSQL-backed implementation of <see cref="IAuthorityBootstrapInviteStore"/>.

View File

@@ -1,10 +1,10 @@
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
namespace StellaOps.Authority.Storage.PostgresAdapters;
namespace StellaOps.Authority.Persistence.PostgresAdapters;
/// <summary>
/// PostgreSQL-backed implementation of <see cref="IAuthorityClientStore"/>.

View File

@@ -1,11 +1,11 @@
using System.Globalization;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
namespace StellaOps.Authority.Storage.PostgresAdapters;
namespace StellaOps.Authority.Persistence.PostgresAdapters;
/// <summary>
/// PostgreSQL-backed implementation of <see cref="IAuthorityLoginAttemptStore"/>.

View File

@@ -1,10 +1,10 @@
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
namespace StellaOps.Authority.Storage.PostgresAdapters;
namespace StellaOps.Authority.Persistence.PostgresAdapters;
internal sealed class PostgresRevocationExportStateStore : IAuthorityRevocationExportStateStore
{

View File

@@ -1,10 +1,10 @@
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
namespace StellaOps.Authority.Storage.PostgresAdapters;
namespace StellaOps.Authority.Persistence.PostgresAdapters;
/// <summary>
/// PostgreSQL-backed implementation of <see cref="IAuthorityRevocationStore"/>.

View File

@@ -1,10 +1,10 @@
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
namespace StellaOps.Authority.Storage.PostgresAdapters;
namespace StellaOps.Authority.Persistence.PostgresAdapters;
/// <summary>
/// PostgreSQL-backed implementation of <see cref="IAuthorityServiceAccountStore"/>.

View File

@@ -1,12 +1,12 @@
using System.Collections.Concurrent;
using System.Text.Json;
using StellaOps.Authority.Storage.Documents;
using StellaOps.Authority.Storage.Sessions;
using StellaOps.Authority.Storage.InMemory.Stores;
using StellaOps.Authority.Storage.Postgres.Models;
using StellaOps.Authority.Storage.Postgres.Repositories;
using StellaOps.Authority.Persistence.Documents;
using StellaOps.Authority.Persistence.Sessions;
using StellaOps.Authority.Persistence.InMemory.Stores;
using StellaOps.Authority.Persistence.Postgres.Models;
using StellaOps.Authority.Persistence.Postgres.Repositories;
namespace StellaOps.Authority.Storage.PostgresAdapters;
namespace StellaOps.Authority.Persistence.PostgresAdapters;
/// <summary>
/// PostgreSQL-backed implementation of <see cref="IAuthorityTokenStore"/> and <see cref="IAuthorityRefreshTokenStore"/>.
@@ -314,10 +314,10 @@ internal sealed class PostgresTokenStore : IAuthorityTokenStore, IAuthorityRefre
private static Dictionary<string, string> BuildProperties(AuthorityTokenDocument document)
{
var properties = new Dictionary<string, string>(document.Properties, StringComparer.OrdinalIgnoreCase)
{
["status"] = string.IsNullOrWhiteSpace(document.Status) ? "valid" : document.Status
};
var properties = document.Properties
.Where(kv => kv.Value is not null)
.ToDictionary(kv => kv.Key, kv => kv.Value!, StringComparer.OrdinalIgnoreCase);
properties["status"] = string.IsNullOrWhiteSpace(document.Status) ? "valid" : document.Status;
if (!string.IsNullOrWhiteSpace(document.Tenant))
{