using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MongoDB.Driver; 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.Mongo.Stores; using StellaOps.Cryptography; using StellaOps.Cryptography.DependencyInjection; namespace StellaOps.Authority.Plugin.Standard; internal sealed class StandardPluginRegistrar : IAuthorityPluginRegistrar { public string PluginType => "standard"; public void Register(AuthorityPluginRegistrationContext context) { if (context is null) { throw new ArgumentNullException(nameof(context)); } var pluginName = context.Plugin.Manifest.Name; context.Services.AddSingleton(); context.Services.AddSingleton(sp => sp.GetRequiredService()); context.Services.AddStellaOpsCrypto(); var configPath = context.Plugin.Manifest.ConfigPath; context.Services.AddOptions(pluginName) .Bind(context.Plugin.Configuration) .PostConfigure(options => { options.Normalize(configPath); options.Validate(pluginName); }) .ValidateOnStart(); context.Services.AddSingleton(sp => { var database = sp.GetRequiredService(); var optionsMonitor = sp.GetRequiredService>(); var pluginOptions = optionsMonitor.Get(pluginName); var cryptoProvider = sp.GetRequiredService(); var passwordHasher = new CryptoPasswordHasher(pluginOptions, cryptoProvider); var loggerFactory = sp.GetRequiredService(); return new StandardUserCredentialStore( pluginName, database, pluginOptions, passwordHasher, loggerFactory.CreateLogger()); }); context.Services.AddSingleton(sp => { var clientStore = sp.GetRequiredService(); var revocationStore = sp.GetRequiredService(); var timeProvider = sp.GetRequiredService(); return new StandardClientProvisioningStore(pluginName, clientStore, revocationStore, timeProvider); }); context.Services.AddSingleton(sp => { var store = sp.GetRequiredService(); var clientProvisioningStore = sp.GetRequiredService(); var loggerFactory = sp.GetRequiredService(); return new StandardIdentityProviderPlugin( context.Plugin, store, clientProvisioningStore, sp.GetRequiredService(), loggerFactory.CreateLogger()); }); context.Services.AddSingleton(sp => sp.GetRequiredService()); context.Services.AddSingleton(sp => new StandardPluginBootstrapper( pluginName, sp.GetRequiredService>(), sp.GetRequiredService(), sp.GetRequiredService>())); } }