diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml index 5e6e3a0c54..deb24accc8 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml @@ -1,13 +1,23 @@ -@page +@page @using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.Extensions.Options @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using Volo.Abp.FeatureManagement.Localization @using Volo.Abp.Validation.StringValues @using Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement +@using Volo.Abp.Localization @model FeatureManagementModal @inject IHtmlLocalizer L +@inject IHtmlLocalizerFactory HtmlLocalizerFactory +@inject IOptions LocalizationOptions @{ Layout = null; + + IHtmlLocalizer CreateHtmlLocalizer(string resourceName) + { + var resource = LocalizationOptions.Value.Resources.Values.FirstOrDefault(x => x.ResourceName == resourceName); + return HtmlLocalizerFactory.Create(resource != null ? resource.ResourceType : LocalizationOptions.Value.DefaultResourceType); + } }
@@ -48,11 +58,11 @@ { if (item.Value == feature.Value) { - + } else { - + } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj index 06cef29fc3..e1df61cbce 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj @@ -23,6 +23,7 @@ + diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/AbpIdentityDomainSharedModule.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/AbpIdentityDomainSharedModule.cs index 4bff33d58a..e14ce5e3f4 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/AbpIdentityDomainSharedModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/AbpIdentityDomainSharedModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Identity.Localization; +using Volo.Abp.Features; +using Volo.Abp.Identity.Localization; using Volo.Abp.Localization; using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; @@ -11,7 +12,8 @@ namespace Volo.Abp.Identity { [DependsOn( typeof(AbpUsersDomainSharedModule), - typeof(AbpValidationModule) + typeof(AbpValidationModule), + typeof(AbpFeaturesModule) )] public class AbpIdentityDomainSharedModule : AbpModule { diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeature.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeature.cs new file mode 100644 index 0000000000..a51a3c11f7 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeature.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Identity.Features +{ + public class IdentityFeature + { + public const string GroupName = "Identity"; + + public const string TwoFactor = GroupName + ".TwoFactor"; + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureCheckerExtensions.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureCheckerExtensions.cs new file mode 100644 index 0000000000..988b381643 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureCheckerExtensions.cs @@ -0,0 +1,23 @@ +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Features; + +namespace Volo.Abp.Identity.Features +{ + public static class IdentityFeatureCheckerExtensions + { + public static async Task GetIdentityTwoFactorBehaviour([NotNull] this IFeatureChecker featureChecker) + { + Check.NotNull(featureChecker, nameof(featureChecker)); + + var value = await featureChecker.GetOrNullAsync(IdentityFeature.TwoFactor); + if (value.IsNullOrWhiteSpace() || !Enum.TryParse(value, out var behaviour)) + { + throw new AbpException($"{IdentityFeature.TwoFactor} feature value is invalid"); + } + + return behaviour; + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureDefinitionProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureDefinitionProvider.cs new file mode 100644 index 0000000000..d26cc17b92 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureDefinitionProvider.cs @@ -0,0 +1,51 @@ +using System; +using Volo.Abp.Features; +using Volo.Abp.Identity.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Validation.StringValues; + +namespace Volo.Abp.Identity.Features +{ + public class IdentityFeatureDefinitionProvider : FeatureDefinitionProvider + { + public override void Define(IFeatureDefinitionContext context) + { + var group = context.AddGroup(IdentityFeature.GroupName, L("Feature:IdentityGroup")); + + group.AddFeature(IdentityFeature.TwoFactor, + IdentityTwoFactorBehaviour.Optional.ToString(), + L("Feature:TwoFactor"), + L("Feature:TwoFactorDescription"), + new SelectionStringValueType + { + ItemSource = new StaticSelectionStringValueItemSource( + new LocalizableSelectionStringValueItem + { + Value = IdentityTwoFactorBehaviour.Optional.ToString(), + DisplayText = GetTwoFactorBehaviourLocalizableStringInfo("Feature:TwoFactor.Optional") + }, + new LocalizableSelectionStringValueItem + { + Value = IdentityTwoFactorBehaviour.Disabled.ToString(), + DisplayText = GetTwoFactorBehaviourLocalizableStringInfo("Feature:TwoFactor.Disabled") + }, + new LocalizableSelectionStringValueItem + { + Value = IdentityTwoFactorBehaviour.Forced.ToString(), + DisplayText = GetTwoFactorBehaviourLocalizableStringInfo("Feature:TwoFactor.Forced") + } + ) + }); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + + private static LocalizableStringInfo GetTwoFactorBehaviourLocalizableStringInfo(string key) + { + return new LocalizableStringInfo(LocalizationResourceNameAttribute.GetName(typeof(IdentityResource)), key); + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviour.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviour.cs new file mode 100644 index 0000000000..4e415a7cfb --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviour.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.Identity.Features +{ + public enum IdentityTwoFactorBehaviour + { + Optional, + + Disabled, + + Forced + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json index 9fe464ae96..166433c5eb 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json @@ -76,6 +76,12 @@ "Permission:ChangePermissions": "Change permissions", "Permission:UserManagement": "User management", "Permission:UserLookup": "User lookup", + "Feature:IdentityGroup": "Identity", + "Feature:TwoFactor": "Two Factor", + "Feature:TwoFactorDescription": "Two Factor", + "Feature:TwoFactor.Optional": "Optional", + "Feature:TwoFactor.Disabled": "Disabled", + "Feature:TwoFactor.Forced": "Forced", "DisplayName:Abp.Identity.Password.RequiredLength": "Required length", "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Required unique characters number", "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Required non-alphanumeric character", @@ -103,6 +109,10 @@ "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Whether the phoneNumber can be confirmed by the user.", "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Whether a confirmed telephone number is required to sign in.", "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Whether the username can be updated by the user.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Whether the email can be updated by the user." + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Whether the email can be updated by the user.", + "DisplayName:Abp.Identity.TwoFactorBehaviour": "Two Factor behaviour", + "Description:Abp.Identity.TwoFactorBehaviour": "Two Factor behaviour", + "DisplayName:Abp.Identity.UsersCanChange": "Allow users to change their Two Factor.", + "Description:Abp.Identity.UsersCanChange": "Allow users to change their Two Factor." } -} +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json index 2ad19c80f4..97dc56b417 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json @@ -76,6 +76,12 @@ "Permission:ChangePermissions": "İzinleri değiştirme", "Permission:UserManagement": "Kullanıcı yönetimi", "Permission:UserLookup": "Kullanıcı sorgulama", + "Feature:IdentityGroup": "Kimlik", + "Feature:TwoFactor": "İki faktörlü kimlik doğrulama", + "Feature:TwoFactorDescription": "İki faktörlü kimlik doğrulama", + "Feature:TwoFactor.Optional": "İsteğe bağlı", + "Feature:TwoFactor.Disabled": "Devre dışı", + "Feature:TwoFactor.Forced": "Zorla etkinleştirildi", "DisplayName:Abp.Identity.Password.RequiredLength": "Uzunluk gerekli", "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Tekil karakter gerekli", "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Alfasayısal olmayan karakter gerekli", @@ -103,6 +109,10 @@ "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Oturum açmak için telefon numarası gerekli", "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Oturum açmak için onaylanmış bir telefon numarasının gerekli olup olmadığı.", "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Kullanıcı adının, kullanıcının kendisi tarafından güncellenebilirliği.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "E-posta alanının, kullanıcının kendisi tarafından güncellenebilirliği" + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "E-posta alanının, kullanıcının kendisi tarafından güncellenebilirliği", + "DisplayName:Abp.Identity.TwoFactorBehaviour": "İki faktörlü kimlik doğrulama davranışı", + "Description:Abp.Identity.TwoFactorBehaviour": "İki faktörlü kimlik doğrulama davranışı", + "DisplayName:Abp.Identity.UsersCanChange": "Kullanıcıların faktör kimlik doğrulamasını değiştirmesine izin verin.", + "Description:Abp.Identity.UsersCanChange": "Kullanıcıların faktör kimlik doğrulamasını değiştirmesine izin verin." } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json index 5494581c6a..8e8c8cbccf 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json @@ -73,6 +73,12 @@ "Permission:ChangePermissions": "更改权限", "Permission:UserManagement": "用户管理", "Permission:UserLookup": "用户查询", + "Feature:IdentityGroup": "身份标识", + "Feature:TwoFactor": "双因素身份验证", + "Feature:TwoFactorDescription": "双因素身份验证", + "Feature:TwoFactor.Optional": "可选", + "Feature:TwoFactor.Disabled": "禁用", + "Feature:TwoFactor.Forced": "强制启用", "DisplayName:Abp.Identity.Password.RequiredLength": "要求长度", "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "要求唯一字符数量", "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "要求非字母数字", @@ -98,6 +104,10 @@ "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "登录时是否需要验证的电子邮箱.", "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "登录时是否需要验证的手机号码.", "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "是否允许用户更新用户名.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "是否允许用户更新电子邮箱." + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "是否允许用户更新电子邮箱.", + "DisplayName:Abp.Identity.TwoFactorBehaviour": "双因素身份验证行为", + "Description:Abp.Identity.TwoFactorBehaviour": "双因素身份验证行为", + "DisplayName:Abp.Identity.UsersCanChange": "允许用户更改其因素身份验证.", + "Description:Abp.Identity.UsersCanChange": "允许用户更改其因素身份验证." } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs index eb7a88407f..879c3ffd4c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs @@ -48,5 +48,14 @@ public const string MaxUserMembershipCount = OrganizationUnitPrefix + ".MaxUserMembershipCount"; } + + public static class TwoFactor + { + private const string TwoFactorPrefix = Prefix + ".TwoFactor"; + + public const string Behaviour = TwoFactorPrefix + ".Behaviour"; + + public const string UsersCanChange = TwoFactorPrefix + ".UsersCanChange"; + } } -} \ No newline at end of file +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs index 1fdd2dd451..cff38810c9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Identity.Localization; +using Volo.Abp.Identity.Features; +using Volo.Abp.Identity.Localization; using Volo.Abp.Identity.Settings; using Volo.Abp.Localization; using Volo.Abp.Settings; @@ -33,85 +34,97 @@ namespace Volo.Abp.Identity new SettingDefinition( IdentitySettingNames.Password.RequireLowercase, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.Password.RequireLowercase"), L("Description:Abp.Identity.Password.RequireLowercase"), true), new SettingDefinition( IdentitySettingNames.Password.RequireUppercase, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.Password.RequireUppercase"), L("Description:Abp.Identity.Password.RequireUppercase"), true), new SettingDefinition( IdentitySettingNames.Password.RequireDigit, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.Password.RequireDigit"), L("Description:Abp.Identity.Password.RequireDigit"), true), new SettingDefinition( IdentitySettingNames.Lockout.AllowedForNewUsers, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.Lockout.AllowedForNewUsers"), L("Description:Abp.Identity.Lockout.AllowedForNewUsers"), true), new SettingDefinition( IdentitySettingNames.Lockout.LockoutDuration, - (5 * 60).ToString(), + (5 * 60).ToString(), L("DisplayName:Abp.Identity.Lockout.LockoutDuration"), L("Description:Abp.Identity.Lockout.LockoutDuration"), true), new SettingDefinition( IdentitySettingNames.Lockout.MaxFailedAccessAttempts, - 5.ToString(), + 5.ToString(), L("DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts"), L("Description:Abp.Identity.Lockout.MaxFailedAccessAttempts"), true), new SettingDefinition( IdentitySettingNames.SignIn.RequireConfirmedEmail, - false.ToString(), + false.ToString(), L("DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail"), L("Description:Abp.Identity.SignIn.RequireConfirmedEmail"), true), new SettingDefinition( - IdentitySettingNames.SignIn.EnablePhoneNumberConfirmation, - true.ToString(), - L("DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation"), - L("Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation"), + IdentitySettingNames.SignIn.EnablePhoneNumberConfirmation, + true.ToString(), + L("DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation"), + L("Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation"), true), new SettingDefinition( - IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, - false.ToString(), - L("DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber"), - L("Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber"), + IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, + false.ToString(), + L("DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber"), + L("Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber"), true), new SettingDefinition( IdentitySettingNames.User.IsUserNameUpdateEnabled, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled"), L("Description:Abp.Identity.User.IsUserNameUpdateEnabled"), true), new SettingDefinition( IdentitySettingNames.User.IsEmailUpdateEnabled, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.User.IsEmailUpdateEnabled"), L("Description:Abp.Identity.User.IsEmailUpdateEnabled"), true), - new SettingDefinition( + new SettingDefinition( IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount, - int.MaxValue.ToString(), + int.MaxValue.ToString(), L("Identity.OrganizationUnit.MaxUserMembershipCount"), L("Identity.OrganizationUnit.MaxUserMembershipCount"), - true) + true), + + new SettingDefinition(IdentitySettingNames.TwoFactor.Behaviour, + IdentityTwoFactorBehaviour.Optional.ToString(), + L("DisplayName:Abp.Identity.TwoFactorBehaviour"), + L("Description:Abp.Identity.TwoFactorBehaviour"), + isVisibleToClients: true), + + new SettingDefinition(IdentitySettingNames.TwoFactor.UsersCanChange, + true.ToString(), + L("DisplayName:Abp.Identity.UsersCanChange"), + L("Description:Abp.Identity.UsersCanChange"), + isVisibleToClients: true) ); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySettingProviderExtensions.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySettingProviderExtensions.cs new file mode 100644 index 0000000000..6ffe035c80 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySettingProviderExtensions.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Identity.Features; +using Volo.Abp.Identity.Settings; +using Volo.Abp.Settings; + +namespace Volo.Abp.Identity +{ + public static class IdentitySettingProviderExtensions + { + public static async Task GetIdentityTwoFactorBehaviour([NotNull] this ISettingProvider settingProvider) + { + Check.NotNull(settingProvider, nameof(settingProvider)); + + var value = await settingProvider.GetOrNullAsync(IdentitySettingNames.TwoFactor.Behaviour); + if (value.IsNullOrWhiteSpace() || !Enum.TryParse(value, out var behaviour)) + { + throw new AbpException($"{IdentitySettingNames.TwoFactor.Behaviour} setting value is invalid"); + } + + return behaviour; + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityTwoFactorManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityTwoFactorManager.cs new file mode 100644 index 0000000000..5838ee20b8 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityTwoFactorManager.cs @@ -0,0 +1,69 @@ +using System.Threading.Tasks; +using Volo.Abp.Domain.Services; +using Volo.Abp.Features; +using Volo.Abp.Identity.Features; +using Volo.Abp.Settings; + +namespace Volo.Abp.Identity +{ + public class IdentityTwoFactorManager : IDomainService + { + protected IFeatureChecker FeatureChecker { get; } + + protected ISettingProvider SettingProvider { get; } + + public IdentityTwoFactorManager(IFeatureChecker featureChecker, ISettingProvider settingProvider) + { + FeatureChecker = featureChecker; + SettingProvider = settingProvider; + } + + public virtual async Task IsOptionalAsync() + { + var feature = await FeatureChecker.GetIdentityTwoFactorBehaviour(); + if (feature == IdentityTwoFactorBehaviour.Optional) + { + var setting = await SettingProvider.GetIdentityTwoFactorBehaviour(); + if (setting == IdentityTwoFactorBehaviour.Optional) + { + return true; + } + } + + return false; + } + + public virtual async Task IsForcedEnableAsync() + { + var feature = await FeatureChecker.GetIdentityTwoFactorBehaviour(); + if (feature == IdentityTwoFactorBehaviour.Forced) + { + return true; + } + + var setting = await SettingProvider.GetIdentityTwoFactorBehaviour(); + if (setting == IdentityTwoFactorBehaviour.Forced) + { + return true; + } + + return false; + } + + public virtual async Task IsForcedDisableAsync() + { + var feature = await FeatureChecker.GetIdentityTwoFactorBehaviour(); + if (feature == IdentityTwoFactorBehaviour.Disabled) + { + return true; + } + + var setting = await SettingProvider.GetIdentityTwoFactorBehaviour(); + if (setting == IdentityTwoFactorBehaviour.Disabled) + { + return true; + } + return false; + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs index 17a0fbd39d..2712e41607 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs @@ -11,7 +11,10 @@ using Microsoft.Extensions.Logging; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; +using Volo.Abp.Features; using Volo.Abp.Guids; +using Volo.Abp.Identity.Features; +using Volo.Abp.Settings; namespace Volo.Abp.Identity { @@ -56,12 +59,17 @@ namespace Volo.Abp.Identity protected ILookupNormalizer LookupNormalizer { get; } protected IIdentityUserRepository UserRepository { get; } + protected IFeatureChecker FeatureChecker { get; } + protected ISettingProvider SettingProvider { get; } + public IdentityUserStore( IIdentityUserRepository userRepository, IIdentityRoleRepository roleRepository, IGuidGenerator guidGenerator, ILogger logger, ILookupNormalizer lookupNormalizer, + IFeatureChecker featureChecker, + ISettingProvider settingProvider, IdentityErrorDescriber describer = null) { UserRepository = userRepository; @@ -69,6 +77,8 @@ namespace Volo.Abp.Identity GuidGenerator = guidGenerator; Logger = logger; LookupNormalizer = lookupNormalizer; + FeatureChecker = featureChecker; + SettingProvider = settingProvider; ErrorDescriber = describer ?? new IdentityErrorDescriber(); } @@ -931,13 +941,33 @@ namespace Volo.Abp.Identity /// The that represents the asynchronous operation, containing a flag indicating whether the specified /// has two factor authentication enabled or not. /// - public virtual Task GetTwoFactorEnabledAsync([NotNull] IdentityUser user, CancellationToken cancellationToken = default) + public virtual async Task GetTwoFactorEnabledAsync([NotNull] IdentityUser user, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); Check.NotNull(user, nameof(user)); - return Task.FromResult(user.TwoFactorEnabled); + var feature = await FeatureChecker.GetIdentityTwoFactorBehaviour(); + if (feature == IdentityTwoFactorBehaviour.Disabled) + { + return false; + } + if (feature == IdentityTwoFactorBehaviour.Forced) + { + return true; + } + + var setting = await SettingProvider.GetIdentityTwoFactorBehaviour(); + if (setting == IdentityTwoFactorBehaviour.Disabled) + { + return false; + } + if (setting == IdentityTwoFactorBehaviour.Forced) + { + return true; + } + + return user.TwoFactorEnabled; } ///