using System; using System.Collections.Generic; namespace StellaOps.Signals.Options; /// /// Authority configuration for the Signals service. /// public sealed class SignalsAuthorityOptions { /// /// Enables Authority-backed authentication. /// public bool Enabled { get; set; } /// /// Allows header-based development fallback when Authority is disabled. /// public bool AllowAnonymousFallback { get; set; } = true; /// /// Authority issuer URL. /// public string Issuer { get; set; } = string.Empty; /// /// Indicates whether HTTPS metadata is required. /// public bool RequireHttpsMetadata { get; set; } = true; /// /// Optional metadata address override. /// public string? MetadataAddress { get; set; } /// /// Back-channel timeout (seconds). /// public int BackchannelTimeoutSeconds { get; set; } = 30; /// /// Token clock skew allowance (seconds). /// public int TokenClockSkewSeconds { get; set; } = 60; /// /// Accepted token audiences. /// public IList Audiences { get; } = new List(); /// /// Required scopes. /// public IList RequiredScopes { get; } = new List(); /// /// Required tenants. /// public IList RequiredTenants { get; } = new List(); /// /// Networks allowed to bypass scope enforcement. /// public IList BypassNetworks { get; } = new List(); /// /// Validates the configured options. /// public void Validate() { if (!Enabled) { return; } if (string.IsNullOrWhiteSpace(Issuer)) { throw new InvalidOperationException("Signals Authority issuer must be configured when Authority integration is enabled."); } if (!Uri.TryCreate(Issuer.Trim(), UriKind.Absolute, out var issuerUri)) { throw new InvalidOperationException("Signals Authority issuer must be an absolute URI."); } if (RequireHttpsMetadata && !issuerUri.IsLoopback && !string.Equals(issuerUri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Signals Authority issuer must use HTTPS unless running on loopback."); } if (BackchannelTimeoutSeconds <= 0) { throw new InvalidOperationException("Signals Authority back-channel timeout must be greater than zero seconds."); } if (TokenClockSkewSeconds < 0 || TokenClockSkewSeconds > 300) { throw new InvalidOperationException("Signals Authority token clock skew must be between 0 and 300 seconds."); } } }