up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
This commit is contained in:
@@ -1,117 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace StellaOps.Authority.Plugins.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Well-known Authority plugin capability identifiers.
|
||||
/// </summary>
|
||||
public static class AuthorityPluginCapabilities
|
||||
{
|
||||
public const string Password = "password";
|
||||
public const string Bootstrap = "bootstrap";
|
||||
public const string Mfa = "mfa";
|
||||
public const string ClientProvisioning = "clientProvisioning";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immutable description of an Authority plugin loaded from configuration.
|
||||
/// </summary>
|
||||
/// <param name="Name">Logical name derived from configuration key.</param>
|
||||
/// <param name="Type">Plugin type identifier (used for capability routing).</param>
|
||||
/// <param name="Enabled">Whether the plugin is enabled.</param>
|
||||
/// <param name="AssemblyName">Assembly name without extension.</param>
|
||||
/// <param name="AssemblyPath">Explicit assembly path override.</param>
|
||||
/// <param name="Capabilities">Capability hints exposed by the plugin.</param>
|
||||
/// <param name="Metadata">Additional metadata forwarded to plugin implementations.</param>
|
||||
/// <param name="ConfigPath">Absolute path to the plugin configuration manifest.</param>
|
||||
public sealed record AuthorityPluginManifest(
|
||||
string Name,
|
||||
string Type,
|
||||
bool Enabled,
|
||||
string? AssemblyName,
|
||||
string? AssemblyPath,
|
||||
IReadOnlyList<string> Capabilities,
|
||||
IReadOnlyDictionary<string, string?> Metadata,
|
||||
string ConfigPath)
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the manifest declares the specified capability.
|
||||
/// </summary>
|
||||
/// <param name="capability">Capability identifier to check.</param>
|
||||
public bool HasCapability(string capability)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(capability))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var entry in Capabilities)
|
||||
{
|
||||
if (string.Equals(entry, capability, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runtime context combining plugin manifest metadata and its bound configuration.
|
||||
/// </summary>
|
||||
/// <param name="Manifest">Manifest describing the plugin.</param>
|
||||
/// <param name="Configuration">Root configuration built from the plugin YAML manifest.</param>
|
||||
public sealed record AuthorityPluginContext(
|
||||
AuthorityPluginManifest Manifest,
|
||||
IConfiguration Configuration);
|
||||
|
||||
/// <summary>
|
||||
/// Registry exposing the set of Authority plugins loaded at runtime.
|
||||
/// </summary>
|
||||
public interface IAuthorityPluginRegistry
|
||||
{
|
||||
IReadOnlyCollection<AuthorityPluginContext> Plugins { get; }
|
||||
|
||||
bool TryGet(string name, [NotNullWhen(true)] out AuthorityPluginContext? context);
|
||||
|
||||
AuthorityPluginContext GetRequired(string name)
|
||||
{
|
||||
if (TryGet(name, out var context))
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
throw new KeyNotFoundException($"Authority plugin '{name}' is not registered.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registry exposing loaded identity provider plugins and their capabilities.
|
||||
/// </summary>
|
||||
public interface IAuthorityIdentityProviderRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets metadata for all registered identity provider plugins.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<AuthorityIdentityProviderMetadata> Providers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets metadata for identity providers that advertise password support.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<AuthorityIdentityProviderMetadata> PasswordProviders { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets metadata for identity providers that advertise multi-factor authentication support.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<AuthorityIdentityProviderMetadata> MfaProviders { get; }
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace StellaOps.Authority.Plugins.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Well-known Authority plugin capability identifiers.
|
||||
/// </summary>
|
||||
public static class AuthorityPluginCapabilities
|
||||
{
|
||||
public const string Password = "password";
|
||||
public const string Bootstrap = "bootstrap";
|
||||
public const string Mfa = "mfa";
|
||||
public const string ClientProvisioning = "clientProvisioning";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immutable description of an Authority plugin loaded from configuration.
|
||||
/// </summary>
|
||||
/// <param name="Name">Logical name derived from configuration key.</param>
|
||||
/// <param name="Type">Plugin type identifier (used for capability routing).</param>
|
||||
/// <param name="Enabled">Whether the plugin is enabled.</param>
|
||||
/// <param name="AssemblyName">Assembly name without extension.</param>
|
||||
/// <param name="AssemblyPath">Explicit assembly path override.</param>
|
||||
/// <param name="Capabilities">Capability hints exposed by the plugin.</param>
|
||||
/// <param name="Metadata">Additional metadata forwarded to plugin implementations.</param>
|
||||
/// <param name="ConfigPath">Absolute path to the plugin configuration manifest.</param>
|
||||
public sealed record AuthorityPluginManifest(
|
||||
string Name,
|
||||
string Type,
|
||||
bool Enabled,
|
||||
string? AssemblyName,
|
||||
string? AssemblyPath,
|
||||
IReadOnlyList<string> Capabilities,
|
||||
IReadOnlyDictionary<string, string?> Metadata,
|
||||
string ConfigPath)
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the manifest declares the specified capability.
|
||||
/// </summary>
|
||||
/// <param name="capability">Capability identifier to check.</param>
|
||||
public bool HasCapability(string capability)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(capability))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var entry in Capabilities)
|
||||
{
|
||||
if (string.Equals(entry, capability, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runtime context combining plugin manifest metadata and its bound configuration.
|
||||
/// </summary>
|
||||
/// <param name="Manifest">Manifest describing the plugin.</param>
|
||||
/// <param name="Configuration">Root configuration built from the plugin YAML manifest.</param>
|
||||
public sealed record AuthorityPluginContext(
|
||||
AuthorityPluginManifest Manifest,
|
||||
IConfiguration Configuration);
|
||||
|
||||
/// <summary>
|
||||
/// Registry exposing the set of Authority plugins loaded at runtime.
|
||||
/// </summary>
|
||||
public interface IAuthorityPluginRegistry
|
||||
{
|
||||
IReadOnlyCollection<AuthorityPluginContext> Plugins { get; }
|
||||
|
||||
bool TryGet(string name, [NotNullWhen(true)] out AuthorityPluginContext? context);
|
||||
|
||||
AuthorityPluginContext GetRequired(string name)
|
||||
{
|
||||
if (TryGet(name, out var context))
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
throw new KeyNotFoundException($"Authority plugin '{name}' is not registered.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registry exposing loaded identity provider plugins and their capabilities.
|
||||
/// </summary>
|
||||
public interface IAuthorityIdentityProviderRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets metadata for all registered identity provider plugins.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<AuthorityIdentityProviderMetadata> Providers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets metadata for identity providers that advertise password support.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<AuthorityIdentityProviderMetadata> PasswordProviders { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets metadata for identity providers that advertise multi-factor authentication support.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<AuthorityIdentityProviderMetadata> MfaProviders { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets metadata for identity providers that advertise client provisioning support.
|
||||
/// </summary>
|
||||
@@ -126,91 +126,91 @@ public interface IAuthorityIdentityProviderRegistry
|
||||
/// Aggregate capability flags across all registered providers.
|
||||
/// </summary>
|
||||
AuthorityIdentityProviderCapabilities AggregateCapabilities { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to resolve identity provider metadata by name.
|
||||
/// </summary>
|
||||
bool TryGet(string name, [NotNullWhen(true)] out AuthorityIdentityProviderMetadata? metadata);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves identity provider metadata by name or throws when not found.
|
||||
/// </summary>
|
||||
AuthorityIdentityProviderMetadata GetRequired(string name)
|
||||
{
|
||||
if (TryGet(name, out var metadata))
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
||||
throw new KeyNotFoundException($"Identity provider plugin '{name}' is not registered.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Acquires a scoped handle to the specified identity provider.
|
||||
/// </summary>
|
||||
/// <param name="name">Logical provider name.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Handle managing the provider instance lifetime.</returns>
|
||||
ValueTask<AuthorityIdentityProviderHandle> AcquireAsync(string name, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immutable metadata describing a registered identity provider.
|
||||
/// </summary>
|
||||
/// <param name="Name">Logical provider name from the manifest.</param>
|
||||
/// <param name="Type">Provider type identifier.</param>
|
||||
/// <param name="Capabilities">Capability flags advertised by the provider.</param>
|
||||
public sealed record AuthorityIdentityProviderMetadata(
|
||||
string Name,
|
||||
string Type,
|
||||
AuthorityIdentityProviderCapabilities Capabilities);
|
||||
|
||||
/// <summary>
|
||||
/// Represents a scoped identity provider instance and manages its disposal.
|
||||
/// </summary>
|
||||
public sealed class AuthorityIdentityProviderHandle : IAsyncDisposable, IDisposable
|
||||
{
|
||||
private readonly AsyncServiceScope scope;
|
||||
private bool disposed;
|
||||
|
||||
public AuthorityIdentityProviderHandle(AsyncServiceScope scope, AuthorityIdentityProviderMetadata metadata, IIdentityProviderPlugin provider)
|
||||
{
|
||||
this.scope = scope;
|
||||
Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
|
||||
Provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the metadata associated with the provider instance.
|
||||
/// </summary>
|
||||
public AuthorityIdentityProviderMetadata Metadata { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active provider instance.
|
||||
/// </summary>
|
||||
public IIdentityProviderPlugin Provider { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
scope.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
await scope.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to resolve identity provider metadata by name.
|
||||
/// </summary>
|
||||
bool TryGet(string name, [NotNullWhen(true)] out AuthorityIdentityProviderMetadata? metadata);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves identity provider metadata by name or throws when not found.
|
||||
/// </summary>
|
||||
AuthorityIdentityProviderMetadata GetRequired(string name)
|
||||
{
|
||||
if (TryGet(name, out var metadata))
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
||||
throw new KeyNotFoundException($"Identity provider plugin '{name}' is not registered.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Acquires a scoped handle to the specified identity provider.
|
||||
/// </summary>
|
||||
/// <param name="name">Logical provider name.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Handle managing the provider instance lifetime.</returns>
|
||||
ValueTask<AuthorityIdentityProviderHandle> AcquireAsync(string name, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immutable metadata describing a registered identity provider.
|
||||
/// </summary>
|
||||
/// <param name="Name">Logical provider name from the manifest.</param>
|
||||
/// <param name="Type">Provider type identifier.</param>
|
||||
/// <param name="Capabilities">Capability flags advertised by the provider.</param>
|
||||
public sealed record AuthorityIdentityProviderMetadata(
|
||||
string Name,
|
||||
string Type,
|
||||
AuthorityIdentityProviderCapabilities Capabilities);
|
||||
|
||||
/// <summary>
|
||||
/// Represents a scoped identity provider instance and manages its disposal.
|
||||
/// </summary>
|
||||
public sealed class AuthorityIdentityProviderHandle : IAsyncDisposable, IDisposable
|
||||
{
|
||||
private readonly AsyncServiceScope scope;
|
||||
private bool disposed;
|
||||
|
||||
public AuthorityIdentityProviderHandle(AsyncServiceScope scope, AuthorityIdentityProviderMetadata metadata, IIdentityProviderPlugin provider)
|
||||
{
|
||||
this.scope = scope;
|
||||
Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
|
||||
Provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the metadata associated with the provider instance.
|
||||
/// </summary>
|
||||
public AuthorityIdentityProviderMetadata Metadata { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active provider instance.
|
||||
/// </summary>
|
||||
public IIdentityProviderPlugin Provider { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
scope.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
await scope.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user