using Elsa.ExternalAuthentication.Contracts; using Elsa.ExternalAuthentication.Options; using Elsa.ExternalAuthentication.Permissions; using Elsa.ExternalAuthentication.Policies; using Elsa.ExternalAuthentication.Providers; using Elsa.ExternalAuthentication.Services; using Elsa.ExternalAuthentication.Stores.InMemory; using Elsa.ExternalAuthentication.Validation; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.RateLimiting; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { /// Adds the explicit, non-readiness External Authentication health bridge. public static IHealthChecksBuilder AddExternalAuthenticationHealthCheck(this IServiceCollection services, string name = "external-authentication", IEnumerable? tags = null) => services.AddHealthChecks().AddCheck(name, HealthStatus.Degraded, tags ?? ["external-authentication", "optional"]); /// /// Adds the protocol-neutral External Authentication foundation and its single-node defaults. /// Hosts requiring durable, multi-node state may replace the store registrations. /// public static IServiceCollection AddExternalAuthenticationServices(this IServiceCollection services, Action? configureOptions = null) { var options = services.AddOptions().ValidateOnStart(); if (configureOptions != null) options.Configure(configureOptions); services.AddExternalAuthenticationExtension(ExternalAuthenticationExtensionKind.UnlinkedIdentityPolicy, RejectUnlinkedIdentityPolicy.PolicyType); services.AddExternalAuthenticationExtension(ExternalAuthenticationExtensionKind.UnlinkedIdentityPolicy, CreateUserUnlinkedIdentityPolicy.PolicyType); services.AddExternalAuthenticationExtension(ExternalAuthenticationExtensionKind.PermissionGrantSource, ElsaRolePermissionGrantSource.SourceType); services.AddExternalAuthenticationExtension(ExternalAuthenticationExtensionKind.PermissionGrantSource, ClaimMappingPermissionGrantSource.SourceType); services.AddExternalAuthenticationExtension(ExternalAuthenticationExtensionKind.PermissionGrantSource, GroupMappingPermissionGrantSource.SourceType); services.AddExternalAuthenticationExtension(ExternalAuthenticationExtensionKind.PermissionGrantSource, ClaimPassThroughPermissionGrantSource.SourceType); services.TryAddEnumerable(ServiceDescriptor.Singleton, ExternalAuthenticationOptionsValidator>()); services.AddDataProtection(); services.AddRateLimiter(_ => { }); services.TryAddEnumerable(ServiceDescriptor.Singleton, ConfigureExternalAuthenticationRateLimiterOptions>()); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddEnumerable(ServiceDescriptor.Singleton()); services.TryAddSingleton(); services.TryAddEnumerable(ServiceDescriptor.Singleton()); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddScoped(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddScoped(); services.TryAddScoped(serviceProvider => serviceProvider.GetRequiredService()); services.TryAddScoped(serviceProvider => serviceProvider.GetRequiredService()); services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddEnumerable(ServiceDescriptor.Singleton()); services.TryAddEnumerable(ServiceDescriptor.Singleton()); services.TryAddEnumerable(ServiceDescriptor.Scoped()); services.TryAddEnumerable(ServiceDescriptor.Scoped()); services.TryAddEnumerable(ServiceDescriptor.Scoped()); services.TryAddEnumerable(ServiceDescriptor.Scoped()); services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddEnumerable(ServiceDescriptor.Singleton()); return services; } /// /// Registers the stable identifier of a trusted deployment-installed extension /// for startup selection validation. /// public static IServiceCollection AddExternalAuthenticationExtension( this IServiceCollection services, ExternalAuthenticationExtensionKind kind, string type) { ArgumentException.ThrowIfNullOrWhiteSpace(type); services.Configure(options => options.Registrations.Add(new ExternalAuthenticationExtensionRegistration(kind, type))); return services; } }