< Summary

Information
Class: Elsa.Identity.Features.IdentityFeature
Assembly: Elsa.Identity
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Features/IdentityFeature.cs
Line coverage
83%
Covered lines: 74
Uncovered lines: 15
Coverable lines: 89
Total lines: 227
Line coverage: 83.1%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Features/IdentityFeature.cs

#LineLine coverage
 1using AspNetCore.Authentication.ApiKey;
 2using Elsa.Common.Features;
 3using Elsa.Common.Multitenancy;
 4using Elsa.Extensions;
 5using Elsa.Features.Abstractions;
 6using Elsa.Features.Attributes;
 7using Elsa.Features.Services;
 8using Elsa.Identity.Contracts;
 9using Elsa.Identity.Entities;
 10using Elsa.Identity.Multitenancy;
 11using Elsa.Identity.Options;
 12using Elsa.Identity.Providers;
 13using Elsa.Identity.Services;
 14using JetBrains.Annotations;
 15using Microsoft.Extensions.DependencyInjection;
 16
 17namespace Elsa.Identity.Features;
 18
 19/// <summary>
 20/// Provides identity feature to authenticate &amp; authorize API requests.
 21/// </summary>
 22[DependsOn(typeof(SystemClockFeature))]
 23[PublicAPI]
 24public class IdentityFeature : FeatureBase
 25{
 26    /// <inheritdoc />
 327    public IdentityFeature(IModule module) : base(module)
 28    {
 329    }
 30
 31    /// <summary>
 32    /// Gets or sets the <see cref="IdentityTokenOptions"/>.
 33    /// </summary>
 1534    public Action<IdentityTokenOptions> TokenOptions { get; set; } = _ => { };
 35
 36    /// <summary>
 37    /// Gets or sets the <see cref="ApiKeyOptions"/>.
 38    /// </summary>
 639    public Action<ApiKeyOptions> ApiKeyOptions { get; set; } = options =>
 340    {
 141        options.Realm = "Elsa Workflows";
 142        options.KeyName = "ApiKey";
 443    };
 44
 45    /// <summary>
 46    /// A delegate that configures the <see cref="UsersOptions"/>.
 47    /// </summary>
 1248    public Action<UsersOptions> UsersOptions { get; set; } = _ => { };
 49
 50    /// <summary>
 51    /// A delegate that configures the <see cref="ApplicationsOptions"/>.
 52    /// </summary>
 1253    public Action<ApplicationsOptions> ApplicationsOptions { get; set; } = _ => { };
 54
 55    /// <summary>
 56    /// A delegate that configures the <see cref="RolesOptions"/>.
 57    /// </summary>
 1258    public Action<RolesOptions> RolesOptions { get; set; } = _ => { };
 59
 60    /// <summary>
 61    /// A delegate that creates an instance of an implementation of <see cref="IUserStore"/>.
 62    /// </summary>
 963    public Func<IServiceProvider, IUserStore> UserStore { get; set; } = sp => sp.GetRequiredService<MemoryUserStore>();
 64
 65    /// <summary>
 66    /// A delegate that creates an instance of an implementation of <see cref="IApplicationStore"/>.
 67    /// </summary>
 968    public Func<IServiceProvider, IApplicationStore> ApplicationStore { get; set; } = sp => sp.GetRequiredService<Memory
 69
 70    /// <summary>
 71    /// A delegate that creates an instance of an implementation of <see cref="IRoleStore"/>.
 72    /// </summary>
 973    public Func<IServiceProvider, IRoleStore> RoleStore { get; set; } = sp => sp.GetRequiredService<MemoryRoleStore>();
 74
 75    /// <summary>
 76    /// A delegate that creates an instance of an implementation of <see cref="IUserProvider"/>.
 77    /// </summary>
 978    public Func<IServiceProvider, IUserProvider> UserProvider { get; set; } = sp => sp.GetRequiredService<StoreBasedUser
 79
 80    /// <summary>
 81    /// A delegate that creates an instance of an implementation of <see cref="IApplicationProvider"/>.
 82    /// </summary>
 983    public Func<IServiceProvider, IApplicationProvider> ApplicationProvider { get; set; } = sp => sp.GetRequiredService<
 84
 85    /// <summary>
 86    /// A delegate that creates an instance of an implementation of <see cref="IRoleProvider"/>.
 87    /// </summary>
 988    public Func<IServiceProvider, IRoleProvider> RoleProvider { get; set; } = sp => sp.GetRequiredService<StoreBasedRole
 89
 90    /// <summary>
 91    /// Configures the feature to use <see cref="ConfigurationBasedUserProvider"/>.
 92    /// </summary>
 093    public void UseStoreBasedUserProvider() => UserProvider = sp => sp.GetRequiredService<StoreBasedUserProvider>();
 94
 95    /// <summary>
 96    /// Configures the feature to use <see cref="ConfigurationBasedUserProvider"/>.
 97    /// </summary>
 98    public void UseConfigurationBasedUserProvider(Action<UsersOptions> configure)
 99    {
 6100        UserProvider = sp => sp.GetRequiredService<ConfigurationBasedUserProvider>();
 3101        UsersOptions += configure;
 3102    }
 103
 104    /// <summary>
 105    /// Configures the feature to use <see cref="AdminUserProvider"/>. The provider denies all users unless configured.
 106    /// </summary>
 107    public void UseAdminUserProvider()
 108    {
 0109        UserProvider = sp => sp.GetRequiredService<AdminUserProvider>();
 0110        RoleProvider = sp => sp.GetRequiredService<AdminRoleProvider>();
 0111    }
 112
 113    /// <summary>
 114    /// Configures the feature to use <see cref="AdminUserProvider"/> with an explicit admin user.
 115    /// </summary>
 116    public void UseAdminUserProvider(Action<AdminUserProviderOptions> configure)
 117    {
 0118        UseAdminUserProvider();
 0119        Services.Configure(configure);
 0120    }
 121
 122    /// <summary>
 123    /// Configures the feature to use the development admin user. Do not use in production.
 124    /// </summary>
 0125    public void UseDevelopmentAdminUserProvider() => UseAdminUserProvider(options =>
 0126    {
 0127        options.UserName = "admin";
 0128        options.Password = "password";
 0129    });
 130
 131    /// <summary>
 132    /// Configures the feature to use <see cref="StoreBasedApplicationProvider"/>.
 133    /// </summary>
 0134    public void UseStoreBasedApplicationProvider() => ApplicationProvider = sp => sp.GetRequiredService<StoreBasedApplic
 135
 136    /// <summary>
 137    /// Configures the feature to use <see cref="ConfigurationBasedApplicationProvider"/>.
 138    /// </summary>
 139    public void UseConfigurationBasedApplicationProvider(Action<ApplicationsOptions> configure)
 140    {
 6141        ApplicationProvider = sp => sp.GetRequiredService<ConfigurationBasedApplicationProvider>();
 3142        ApplicationsOptions += configure;
 3143    }
 144
 145    /// <summary>
 146    /// Configures the feature to use <see cref="StoreBasedRoleProvider"/>.
 147    /// </summary>
 0148    public void UseStoreBasedRoleProvider() => RoleProvider = sp => sp.GetRequiredService<StoreBasedRoleProvider>();
 149
 150    /// <summary>
 151    /// Configures the feature to use <see cref="ConfigurationBasedRoleProvider"/>.
 152    /// </summary>
 153    public void UseConfigurationBasedRoleProvider(Action<RolesOptions> configure)
 154    {
 6155        RoleProvider = sp => sp.GetRequiredService<ConfigurationBasedRoleProvider>();
 3156        RolesOptions += configure;
 3157    }
 158
 159    /// <inheritdoc />
 160    public override void Configure()
 161    {
 3162        Module.AddFastEndpointsAssembly(GetType());
 3163    }
 164
 165    /// <inheritdoc />
 166    public override void Apply()
 167    {
 3168        Services.Configure(TokenOptions);
 3169        Services.Configure(ApiKeyDefaults.AuthenticationScheme, ApiKeyOptions);
 3170        Services.Configure<AdminUserProviderOptions>(_ => { });
 3171        Services.Configure(UsersOptions);
 3172        Services.Configure(ApplicationsOptions);
 3173        Services.Configure(RolesOptions);
 174
 175        // Memory stores.
 3176        Services
 3177            .AddMemoryStore<User, MemoryUserStore>()
 3178            .AddMemoryStore<Application, MemoryApplicationStore>()
 3179            .AddMemoryStore<Role, MemoryRoleStore>();
 180
 181        // User providers.
 3182        Services
 3183            .AddScoped<AdminUserProvider>()
 3184            .AddScoped<StoreBasedUserProvider>()
 3185            .AddScoped<ConfigurationBasedUserProvider>();
 186
 187        // Application providers.
 3188        Services
 3189            .AddScoped<StoreBasedApplicationProvider>()
 3190            .AddScoped<ConfigurationBasedApplicationProvider>();
 191
 192        // Role providers.
 3193        Services
 3194            .AddScoped<AdminRoleProvider>()
 3195            .AddScoped<StoreBasedRoleProvider>()
 3196            .AddScoped<ConfigurationBasedRoleProvider>();
 197
 198        // Tenant resolution strategies.
 3199        Services
 3200            .AddScoped<ITenantResolver, ClaimsTenantResolver>()
 3201            .AddScoped<ITenantResolver, CurrentUserTenantResolver>();
 202
 203        // Services.
 3204        Services
 3205            .AddScoped(UserStore)
 3206            .AddScoped(ApplicationStore)
 3207            .AddScoped(RoleStore)
 3208            .AddScoped(UserProvider)
 3209            .AddScoped(ApplicationProvider)
 3210            .AddScoped(RoleProvider)
 3211            .AddScoped<IUserManager, UserManager>()
 3212            .AddScoped<IRoleManager, RoleManager>()
 3213            .AddScoped<IRoleAuthorizationService, RoleAuthorizationService>()
 3214            .AddScoped<ISecretHasher, DefaultSecretHasher>()
 3215            .AddScoped<IAccessTokenIssuer, DefaultAccessTokenIssuer>()
 3216            .AddScoped<IUserCredentialsValidator, DefaultUserCredentialsValidator>()
 3217            .AddScoped<IApplicationCredentialsValidator, DefaultApplicationCredentialsValidator>()
 3218            .AddScoped<IApiKeyGenerator>(sp => sp.GetRequiredService<DefaultApiKeyGeneratorAndParser>())
 0219            .AddScoped<IApiKeyParser>(sp => sp.GetRequiredService<DefaultApiKeyGeneratorAndParser>())
 3220            .AddScoped<IClientIdGenerator, DefaultClientIdGenerator>()
 3221            .AddScoped<ISecretGenerator, DefaultSecretGenerator>()
 3222            .AddScoped<IRandomStringGenerator, DefaultRandomStringGenerator>()
 3223            .AddScoped<DefaultApiKeyGeneratorAndParser>()
 3224            .AddHttpContextAccessor()
 3225            ;
 3226    }
 227}