From 24498a052d7fb2900db45e45023bd3054e6fe2f3 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 22 Apr 2021 10:18:27 +0800 Subject: [PATCH] Introduce the SimpleStateChecker. --- .../Toolbars/ToolbarItem.cs | 8 +- .../Toolbars/ToolbarManager.cs | 21 ++-- .../Permissions/AbpPermissionOptions.cs | 3 - .../Permissions/IPermissionStateManager.cs | 9 -- .../Permissions/IPermissionStateProvider.cs | 9 -- .../Permissions/PermissionDefinition.cs | 7 +- .../PermissionDefinitionExtensions.cs | 19 --- .../PermissionSimpleStateCheckerExtensions.cs | 53 +++++++++ ...quirePermissionsSimpleBatchStateChecker.cs | 57 +++++++++ ...PermissionsSimpleBatchStateCheckerModel.cs | 24 ++++ .../RequirePermissionsSimpleStateChecker.cs | 34 ++++++ .../Permissions/PermissionChecker.cs | 11 +- .../Permissions/PermissionStateManager.cs | 51 -------- .../InternalServiceCollectionExtensions.cs | 3 + .../AbpSimpleStateCheckerOptions.cs | 15 +++ .../IHasSimpleStateCheckers.cs | 10 ++ .../ISimpleBatchStateChecker.cs | 10 ++ .../ISimpleStateChecker.cs | 10 ++ .../ISimpleStateCheckerManager.cs | 12 ++ .../SimpleBatchStateCheckerBase.cs | 16 +++ .../SimpleBatchStateCheckerContext.cs | 18 +++ .../SimpleStateCheckerContext.cs | 18 +++ .../SimpleStateCheckerManager.cs | 112 ++++++++++++++++++ .../SimpleStateCheckerResult.cs | 21 ++++ .../FeatureSimpleStateCheckerExtensions.cs | 30 +++++ .../PermissionDefinitionExtensions.cs | 28 ----- .../RequireFeaturesPermissionStateProvider.cs | 32 ----- .../RequireFeaturesSimpleStateChecker.cs | 32 +++++ .../GlobalFeatureDefinitionExtensions.cs | 50 -------- ...obalFeatureSimpleStateCheckerExtensions.cs | 51 ++++++++ ...equireGlobalFeaturesSimpleStateChecker.cs} | 15 +-- .../Abp/Ui/Navigation/ApplicationMenuItem.cs | 8 +- .../Volo/Abp/Ui/Navigation/MenuManager.cs | 41 ++++--- .../UI/Theme/Shared/Toolbars/Toolbar_Tests.cs | 7 +- .../PermissionStateProvider_Tests.cs | 20 ++-- ...equireRolePermissionSimpleStateChecker.cs} | 5 +- ...ireEditionPermissionSimpleStateChecker.cs} | 5 +- ...izationTestPermissionDefinitionProvider.cs | 2 +- .../Volo/Abp/AbpTestModule.cs | 9 ++ .../SimpleStateCheckerTestBase.cs | 105 ++++++++++++++++ .../SimpleStateChecker_CheckCount_Test.cs | 81 +++++++++++++ ...impleStateChecker_GlobalCheckCount_Test.cs | 95 +++++++++++++++ .../SimpleStateChecker_Tests.cs | 105 ++++++++++++++++ .../Abp/Ui/Navigation/MenuManager_Tests.cs | 13 +- .../BloggingAdminMenuContributor.cs | 5 +- .../Navigation/DocsMenuContributor.cs | 5 +- .../AbpIdentityWebMainMenuContributor.cs | 7 +- .../AbpIdentityWebMainMenuContributor.cs | 5 +- .../PermissionAppService.cs | 9 +- .../PermissionManagement/PermissionManager.cs | 11 +- .../TestPermissionDefinitionProvider.cs | 2 +- .../TestRequireRolePermissionStateProvider.cs | 5 +- .../TenantManagementBlazorMenuContributor.cs | 6 +- ...pTenantManagementWebMainMenuContributor.cs | 3 +- 54 files changed, 1052 insertions(+), 291 deletions(-) delete mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs delete mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs delete mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionSimpleStateCheckerExtensions.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateChecker.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateCheckerModel.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleStateChecker.cs delete mode 100644 framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/AbpSimpleStateCheckerOptions.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/IHasSimpleStateCheckers.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleBatchStateChecker.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerManager.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerBase.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerContext.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerContext.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerManager.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerResult.cs create mode 100644 framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureSimpleStateCheckerExtensions.cs delete mode 100644 framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs delete mode 100644 framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs create mode 100644 framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesSimpleStateChecker.cs delete mode 100644 framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs create mode 100644 framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureSimpleStateCheckerExtensions.cs rename framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/{RequireGlobalFeaturesPermissionStateProvider.cs => RequireGlobalFeaturesSimpleStateChecker.cs} (61%) rename framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/{TestGlobalRequireRolePermissionStateProvider.cs => TestGlobalRequireRolePermissionSimpleStateChecker.cs} (65%) rename framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/{TestRequireEditionPermissionStateProvider.cs => TestRequireEditionPermissionSimpleStateChecker.cs} (66%) create mode 100644 framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpTestModule.cs create mode 100644 framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateCheckerTestBase.cs create mode 100644 framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_CheckCount_Test.cs create mode 100644 framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_GlobalCheckCount_Test.cs create mode 100644 framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_Tests.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs index 4676202c24..f884e3436b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Generic; using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars { - public class ToolbarItem + public class ToolbarItem : IHasSimpleStateCheckers { public Type ComponentType { @@ -15,13 +17,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars public int Order { get; set; } [CanBeNull] + [Obsolete("Use RequirePermissions extension method.")] public string RequiredPermissionName { get; set; } + public List> SimpleStateCheckers { get; } + public ToolbarItem([NotNull] Type componentType, int order = 0, string requiredPermissionName = null) { Order = order; ComponentType = Check.NotNull(componentType, nameof(componentType)); RequiredPermissionName = requiredPermissionName; + SimpleStateCheckers = new List>(); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs index 2e97cebecb..b8e1e4687b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.UI.Theming; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars { @@ -15,13 +16,16 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars protected IThemeManager ThemeManager { get; } protected AbpToolbarOptions Options { get; } protected IServiceProvider ServiceProvider { get; } + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } public ToolbarManager( IOptions options, IServiceProvider serviceProvider, - IThemeManager themeManager) + IThemeManager themeManager, + ISimpleStateCheckerManager simpleStateCheckerManager) { ThemeManager = themeManager; + SimpleStateCheckerManager = simpleStateCheckerManager; ServiceProvider = serviceProvider; Options = options.Value; } @@ -47,17 +51,20 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars protected virtual async Task CheckPermissionsAsync(IServiceProvider serviceProvider, Toolbar toolbar) { - var requiredPermissionItems = toolbar.Items.Where(x => !x.RequiredPermissionName.IsNullOrWhiteSpace()).ToList(); + foreach (var item in toolbar.Items.Where(x => !x.RequiredPermissionName.IsNullOrWhiteSpace())) + { + item.RequirePermissions(item.RequiredPermissionName); + } - if (requiredPermissionItems.Any()) + var checkPermissionsToolbarItems = toolbar.Items.Where(x => x.SimpleStateCheckers.Any()).ToArray(); + if (checkPermissionsToolbarItems.Any()) { - var permissionChecker = serviceProvider.GetRequiredService(); - var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).Distinct().ToArray()); + var result = await SimpleStateCheckerManager.IsEnabledAsync(checkPermissionsToolbarItems); var toBeDeleted = new HashSet(); - foreach (var item in requiredPermissionItems) + foreach (var item in checkPermissionsToolbarItems) { - if (grantResult.Result[item.RequiredPermissionName!] != PermissionGrantResult.Granted) + if (!result[item]) { toBeDeleted.Add(item); } diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs index eb2ac920ac..ce9dc06798 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs @@ -8,13 +8,10 @@ namespace Volo.Abp.Authorization.Permissions public ITypeList ValueProviders { get; } - public ITypeList GlobalStateProviders { get; } - public AbpPermissionOptions() { DefinitionProviders = new TypeList(); ValueProviders = new TypeList(); - GlobalStateProviders = new TypeList(); } } } diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs deleted file mode 100644 index 6195e02545..0000000000 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.Authorization.Permissions -{ - public interface IPermissionStateManager - { - Task IsEnabledAsync(PermissionDefinition permission); - } -} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs deleted file mode 100644 index 7bc3087f50..0000000000 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.Authorization.Permissions -{ - public interface IPermissionStateProvider - { - Task IsEnabledAsync(PermissionStateContext context); - } -} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs index ac525367ad..bf2dcbded7 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs @@ -3,10 +3,11 @@ using System.Collections.Immutable; using JetBrains.Annotations; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization.Permissions { - public class PermissionDefinition + public class PermissionDefinition : IHasSimpleStateCheckers { /// /// Unique name of the permission. @@ -31,7 +32,7 @@ namespace Volo.Abp.Authorization.Permissions /// public List Providers { get; } //TODO: Rename to AllowedProviders? - public List StateProviders { get; } + public List> SimpleStateCheckers { get; } public ILocalizableString DisplayName { @@ -88,7 +89,7 @@ namespace Volo.Abp.Authorization.Permissions Properties = new Dictionary(); Providers = new List(); - StateProviders = new List(); + SimpleStateCheckers = new List>(); _children = new List(); } diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs deleted file mode 100644 index 7e5de5a1f1..0000000000 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -using JetBrains.Annotations; - -namespace Volo.Abp.Authorization.Permissions -{ - public static class PermissionDefinitionExtensions - { - public static PermissionDefinition AddStateProviders( - [NotNull] this PermissionDefinition permissionDefinition, - [NotNull] params IPermissionStateProvider[] permissionStateProviders) - { - Check.NotNull(permissionDefinition, nameof(permissionDefinition)); - Check.NotNull(permissionStateProviders, nameof(permissionStateProviders)); - - permissionDefinition.StateProviders.AddRange(permissionStateProviders); - - return permissionDefinition; - } - } -} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionSimpleStateCheckerExtensions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionSimpleStateCheckerExtensions.cs new file mode 100644 index 0000000000..56b50ab50a --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionSimpleStateCheckerExtensions.cs @@ -0,0 +1,53 @@ +using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions +{ + public static class PermissionSimpleStateCheckerExtensions + { + public static TState RequirePermissions( + [NotNull] this TState state, + params string[] permissions) + where TState : IHasSimpleStateCheckers + { + state.RequirePermissions(requiresAll: true, batchCheck: true, permissions); + return state; + } + + public static TState RequirePermissions( + [NotNull] this TState state, + bool requiresAll, + params string[] permissions) + where TState : IHasSimpleStateCheckers + { + state.RequirePermissions(requiresAll: requiresAll, batchCheck: true, permissions); + return state; + } + + public static TState RequirePermissions( + [NotNull] this TState state, + bool requiresAll, + bool batchCheck = true, + params string[] permissions) + where TState : IHasSimpleStateCheckers + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(permissions, nameof(permissions)); + + if (batchCheck) + { + lock (state) + { + RequirePermissionsSimpleBatchStateChecker.Instance.AddCheckModels(new RequirePermissionsSimpleBatchStateCheckerModel(state, permissions, requiresAll)); + state.SimpleStateCheckers.Add(RequirePermissionsSimpleBatchStateChecker.Instance); + } + } + else + { + state.SimpleStateCheckers.Add(new RequirePermissionsSimpleStateChecker(new RequirePermissionsSimpleBatchStateCheckerModel(state, permissions, requiresAll))); + } + + return state; + } + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateChecker.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateChecker.cs new file mode 100644 index 0000000000..5cce51ec51 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateChecker.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions +{ + public class RequirePermissionsSimpleBatchStateChecker : SimpleBatchStateCheckerBase + where TState : IHasSimpleStateCheckers + { + public static readonly RequirePermissionsSimpleBatchStateChecker Instance = new RequirePermissionsSimpleBatchStateChecker(); + + private readonly List> _models; + + public RequirePermissionsSimpleBatchStateChecker() + { + _models = new List>(); + } + + public RequirePermissionsSimpleBatchStateChecker AddCheckModels(params RequirePermissionsSimpleBatchStateCheckerModel[] models) + { + Check.NotNullOrEmpty(models, nameof(models)); + + _models.AddRange(models); + return this; + } + + public override async Task> IsEnabledAsync(SimpleBatchStateCheckerContext context) + { + var permissionChecker = context.ServiceProvider.GetRequiredService(); + + var result = new SimpleStateCheckerResult(context.States); + + var permissions = _models.Where(x => context.States.Any(s => s.Equals(x.State))).SelectMany(x => x.Permissions).Distinct().ToArray(); + var grantResult = await permissionChecker.IsGrantedAsync(permissions); + + foreach (var state in context.States) + { + var model = _models.FirstOrDefault(x => x.State.Equals(state)); + if (model != null) + { + if (model.RequiresAll) + { + result[model.State] = model.Permissions.All(x => grantResult.Result.Any(y => y.Key == x && y.Value == PermissionGrantResult.Granted)); + } + else + { + result[model.State] = grantResult.Result.Any(x => model.Permissions.Contains(x.Key) && x.Value == PermissionGrantResult.Granted); + } + } + } + + return result; + } + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateCheckerModel.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateCheckerModel.cs new file mode 100644 index 0000000000..3660d10f46 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateCheckerModel.cs @@ -0,0 +1,24 @@ +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions +{ + public class RequirePermissionsSimpleBatchStateCheckerModel + where TState : IHasSimpleStateCheckers + { + public TState State { get; } + + public string[] Permissions { get; } + + public bool RequiresAll { get; } + + public RequirePermissionsSimpleBatchStateCheckerModel(TState state, string[] permissions, bool requiresAll = true) + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(permissions, nameof(permissions)); + + State = state; + Permissions = permissions; + RequiresAll = requiresAll; + } + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleStateChecker.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleStateChecker.cs new file mode 100644 index 0000000000..32cedeecc6 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleStateChecker.cs @@ -0,0 +1,34 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions +{ + public class RequirePermissionsSimpleStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + private readonly RequirePermissionsSimpleBatchStateCheckerModel _model; + + public RequirePermissionsSimpleStateChecker(RequirePermissionsSimpleBatchStateCheckerModel model) + { + _model = model; + } + + public async Task IsEnabledAsync(SimpleStateCheckerContext context) + { + var permissionChecker = context.ServiceProvider.GetRequiredService(); + + if (_model.Permissions.Length == 1) + { + return await permissionChecker.IsGrantedAsync(_model.Permissions.First()); + } + + var grantResult = await permissionChecker.IsGrantedAsync(_model.Permissions); + + return _model.RequiresAll + ? grantResult.AllGranted + : grantResult.Result.Any(x => _model.Permissions.Contains(x.Key) && x.Value == PermissionGrantResult.Granted); + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs index f180a00bd7..d4f6e26d94 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization.Permissions { @@ -15,20 +16,20 @@ namespace Volo.Abp.Authorization.Permissions protected ICurrentPrincipalAccessor PrincipalAccessor { get; } protected ICurrentTenant CurrentTenant { get; } protected IPermissionValueProviderManager PermissionValueProviderManager { get; } - protected IPermissionStateManager PermissionStateManager { get; } + protected ISimpleStateCheckerManager PermissionSimpleStateCheckerManager { get; } public PermissionChecker( ICurrentPrincipalAccessor principalAccessor, IPermissionDefinitionManager permissionDefinitionManager, ICurrentTenant currentTenant, IPermissionValueProviderManager permissionValueProviderManager, - IPermissionStateManager permissionStateManager) + ISimpleStateCheckerManager permissionSimpleStateCheckerManager) { PrincipalAccessor = principalAccessor; PermissionDefinitionManager = permissionDefinitionManager; CurrentTenant = currentTenant; PermissionValueProviderManager = permissionValueProviderManager; - PermissionStateManager = permissionStateManager; + PermissionSimpleStateCheckerManager = permissionSimpleStateCheckerManager; } public virtual async Task IsGrantedAsync(string name) @@ -49,7 +50,7 @@ namespace Volo.Abp.Authorization.Permissions return false; } - if (!await PermissionStateManager.IsEnabledAsync(permission)) + if (!await PermissionSimpleStateCheckerManager.IsEnabledAsync(permission)) { return false; } @@ -112,7 +113,7 @@ namespace Volo.Abp.Authorization.Permissions result.Result.Add(name, PermissionGrantResult.Undefined); if (permission.IsEnabled && - await PermissionStateManager.IsEnabledAsync(permission) && + await PermissionSimpleStateCheckerManager.IsEnabledAsync(permission) && permission.MultiTenancySide.HasFlag(multiTenancySide)) { permissionDefinitions.Add(permission); diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs deleted file mode 100644 index 957ed3c7a6..0000000000 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Authorization.Permissions -{ - public class PermissionStateManager : IPermissionStateManager, ITransientDependency - { - protected IServiceProvider ServiceProvider { get; } - protected AbpPermissionOptions Options { get; } - - public PermissionStateManager(IServiceProvider serviceProvider, IOptions options) - { - ServiceProvider = serviceProvider; - Options = options.Value; - } - - public async Task IsEnabledAsync(PermissionDefinition permission) - { - using (var scope = ServiceProvider.CreateScope()) - { - var context = new PermissionStateContext - { - Permission = permission, - ServiceProvider = scope.ServiceProvider.GetRequiredService() - }; - - foreach (var provider in permission.StateProviders) - { - if (!await provider.IsEnabledAsync(context)) - { - return false; - } - } - - foreach (IPermissionStateProvider provider in Options.GlobalStateProviders.Select(x => ServiceProvider.GetRequiredService(x))) - { - if (!await provider.IsEnabledAsync(context)) - { - return false; - } - } - - return true; - } - } - } -} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs index ee06003204..5c729b4197 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Logging; using Volo.Abp.Modularity; using Volo.Abp.Reflection; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Internal { @@ -40,6 +41,8 @@ namespace Volo.Abp.Internal services.AddAssemblyOf(); + services.AddTransient(typeof(ISimpleStateCheckerManager<>), typeof(SimpleStateCheckerManager<>)); + services.Configure(options => { options.Contributors.Add(); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/AbpSimpleStateCheckerOptions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/AbpSimpleStateCheckerOptions.cs new file mode 100644 index 0000000000..bdc756fdb8 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/AbpSimpleStateCheckerOptions.cs @@ -0,0 +1,15 @@ +using Volo.Abp.Collections; + +namespace Volo.Abp.SimpleStateChecking +{ + public class AbpSimpleStateCheckerOptions + where TState : IHasSimpleStateCheckers + { + public ITypeList> GlobalSimpleStateCheckers { get; } + + public AbpSimpleStateCheckerOptions() + { + GlobalSimpleStateCheckers = new TypeList>(); + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/IHasSimpleStateCheckers.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/IHasSimpleStateCheckers.cs new file mode 100644 index 0000000000..cf5a7df6fb --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/IHasSimpleStateCheckers.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Volo.Abp.SimpleStateChecking +{ + public interface IHasSimpleStateCheckers + where TState : IHasSimpleStateCheckers + { + List> SimpleStateCheckers { get; } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleBatchStateChecker.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleBatchStateChecker.cs new file mode 100644 index 0000000000..ff364ff223 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleBatchStateChecker.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.SimpleStateChecking +{ + public interface ISimpleBatchStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + Task> IsEnabledAsync(SimpleBatchStateCheckerContext context); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs new file mode 100644 index 0000000000..6d50044520 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.SimpleStateChecking +{ + public interface ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + Task IsEnabledAsync(SimpleStateCheckerContext context); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerManager.cs new file mode 100644 index 0000000000..4ea98f7e68 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerManager.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.SimpleStateChecking +{ + public interface ISimpleStateCheckerManager + where TState : IHasSimpleStateCheckers + { + Task IsEnabledAsync(TState state); + + Task> IsEnabledAsync(TState[] states); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerBase.cs new file mode 100644 index 0000000000..43b2e2a6fe --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerBase.cs @@ -0,0 +1,16 @@ +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.SimpleStateChecking +{ + public abstract class SimpleBatchStateCheckerBase: ISimpleBatchStateChecker + where TState : IHasSimpleStateCheckers + { + public async Task IsEnabledAsync(SimpleStateCheckerContext context) + { + return (await IsEnabledAsync(new SimpleBatchStateCheckerContext(context.ServiceProvider, new[] {context.State}))).Values.All(x => x); + } + + public abstract Task> IsEnabledAsync(SimpleBatchStateCheckerContext context); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerContext.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerContext.cs new file mode 100644 index 0000000000..ae5826a3e1 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerContext.cs @@ -0,0 +1,18 @@ +using System; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleBatchStateCheckerContext + where TState : IHasSimpleStateCheckers + { + public IServiceProvider ServiceProvider { get; } + + public TState[] States { get; } + + public SimpleBatchStateCheckerContext(IServiceProvider serviceProvider, TState[] states) + { + ServiceProvider = serviceProvider; + States = states; + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerContext.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerContext.cs new file mode 100644 index 0000000000..04e9da4720 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerContext.cs @@ -0,0 +1,18 @@ +using System; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateCheckerContext + where TState : IHasSimpleStateCheckers + { + public IServiceProvider ServiceProvider { get; } + + public TState State { get; } + + public SimpleStateCheckerContext(IServiceProvider serviceProvider, TState state) + { + ServiceProvider = serviceProvider; + State = state; + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerManager.cs new file mode 100644 index 0000000000..22831d8674 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerManager.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateCheckerManager : ISimpleStateCheckerManager + where TState : IHasSimpleStateCheckers + { + protected IServiceProvider ServiceProvider { get; } + + protected AbpSimpleStateCheckerOptions Options { get; } + + public SimpleStateCheckerManager(IServiceProvider serviceProvider, IOptions> options) + { + ServiceProvider = serviceProvider; + Options = options.Value; + } + + public virtual async Task IsEnabledAsync(TState state) + { + return await InternalIsEnabledAsync(state, true); + } + + public virtual async Task> IsEnabledAsync(TState[] states) + { + var result = new SimpleStateCheckerResult(states); + + using (var scope = ServiceProvider.CreateScope()) + { + var batchStateCheckers = states.SelectMany(x => x.SimpleStateCheckers) + .Where(x => x is ISimpleBatchStateChecker) + .Cast>() + .GroupBy(x => x) + .Select(x => x.Key); + + foreach (var stateChecker in batchStateCheckers) + { + var context = new SimpleBatchStateCheckerContext( + scope.ServiceProvider.GetRequiredService(), + states.Where(x => x.SimpleStateCheckers.Contains(stateChecker)).ToArray()); + + foreach (var x in await stateChecker.IsEnabledAsync(context)) + { + result[x.Key] = x.Value; + } + + if (result.Values.All(x => !x)) + { + return result; + } + } + + foreach (ISimpleBatchStateChecker globalStateChecker in Options.GlobalSimpleStateCheckers + .Where(x => typeof(ISimpleBatchStateChecker).IsAssignableFrom(x)) + .Select(x => ServiceProvider.GetRequiredService(x))) + { + var context = new SimpleBatchStateCheckerContext( + scope.ServiceProvider.GetRequiredService(), + states.Where(x => result.Any(y => y.Key.Equals(x) && y.Value)).ToArray()); + + foreach (var x in await globalStateChecker.IsEnabledAsync(context)) + { + result[x.Key] = x.Value; + } + } + + foreach (var state in states) + { + if (result[state]) + { + result[state] = await InternalIsEnabledAsync(state, false); + } + } + + return result; + } + } + + protected virtual async Task InternalIsEnabledAsync(TState state, bool useBatchChecker) + { + using (var scope = ServiceProvider.CreateScope()) + { + var context = new SimpleStateCheckerContext(scope.ServiceProvider.GetRequiredService(), state); + + foreach (var provider in state.SimpleStateCheckers.WhereIf(!useBatchChecker, x => x is not ISimpleBatchStateChecker)) + { + if (!await provider.IsEnabledAsync(context)) + { + return false; + } + } + + foreach (ISimpleStateChecker provider in Options.GlobalSimpleStateCheckers + .WhereIf(!useBatchChecker, x => !typeof(ISimpleBatchStateChecker).IsAssignableFrom(x)) + .Select(x => ServiceProvider.GetRequiredService(x))) + { + if (!await provider.IsEnabledAsync(context)) + { + return false; + } + } + + return true; + } + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerResult.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerResult.cs new file mode 100644 index 0000000000..a3c1dc8020 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerResult.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateCheckerResult : Dictionary + where TState : IHasSimpleStateCheckers + { + public SimpleStateCheckerResult() + { + + } + + public SimpleStateCheckerResult(IEnumerable states, bool initValue = true) + { + foreach (var state in states) + { + Add(state, initValue); + } + } + } +} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureSimpleStateCheckerExtensions.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureSimpleStateCheckerExtensions.cs new file mode 100644 index 0000000000..b05a5f9d7a --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureSimpleStateCheckerExtensions.cs @@ -0,0 +1,30 @@ +using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Features +{ + public static class FeatureSimpleStateCheckerExtensions + { + public static TState RequireFeatures( + [NotNull] this TState state, + params string[] features) + where TState : IHasSimpleStateCheckers + { + state.RequireFeatures(true, features); + return state; + } + + public static TState RequireFeatures( + [NotNull] this TState state, + bool requiresAll, + params string[] features) + where TState : IHasSimpleStateCheckers + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(features, nameof(features)); + + state.SimpleStateCheckers.Add(new RequireFeaturesSimpleStateChecker(requiresAll, features)); + return state; + } + } +} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs deleted file mode 100644 index a213232f2f..0000000000 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using JetBrains.Annotations; -using Volo.Abp.Authorization.Permissions; - -namespace Volo.Abp.Features -{ - public static class FeatureDefinitionExtensions - { - public static PermissionDefinition RequireFeatures( - [NotNull] this PermissionDefinition permissionDefinition, - params string[] features) - { - return permissionDefinition.RequireFeatures(true, features); - } - - public static PermissionDefinition RequireFeatures( - [NotNull] this PermissionDefinition permissionDefinition, - bool requiresAll, - params string[] features) - { - Check.NotNull(permissionDefinition, nameof(permissionDefinition)); - Check.NotNullOrEmpty(features, nameof(features)); - - return permissionDefinition.AddStateProviders( - new RequireFeaturesPermissionStateProvider(requiresAll, features) - ); - } - } -} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs deleted file mode 100644 index 0fee54c598..0000000000 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Authorization.Permissions; - -namespace Volo.Abp.Features -{ - public class RequireFeaturesPermissionStateProvider : IPermissionStateProvider - { - private readonly string[] _featureNames; - private readonly bool _requiresAll; - - public RequireFeaturesPermissionStateProvider(params string[] featureNames) - : this(true, featureNames) - { - - } - - public RequireFeaturesPermissionStateProvider(bool requiresAll, params string[] featureNames) - { - Check.NotNullOrEmpty(featureNames, nameof(featureNames)); - - _requiresAll = requiresAll; - _featureNames = featureNames; - } - - public async Task IsEnabledAsync(PermissionStateContext context) - { - var feature = context.ServiceProvider.GetRequiredService(); - return await feature.IsEnabledAsync(_requiresAll, _featureNames); - } - } -} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesSimpleStateChecker.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesSimpleStateChecker.cs new file mode 100644 index 0000000000..1a4c028653 --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesSimpleStateChecker.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Features +{ + public class RequireFeaturesSimpleStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + private readonly string[] _featureNames; + private readonly bool _requiresAll; + + public RequireFeaturesSimpleStateChecker(params string[] featureNames) + : this(true, featureNames) + { + } + + public RequireFeaturesSimpleStateChecker(bool requiresAll, params string[] featureNames) + { + Check.NotNullOrEmpty(featureNames, nameof(featureNames)); + + _requiresAll = requiresAll; + _featureNames = featureNames; + } + + public async Task IsEnabledAsync(SimpleStateCheckerContext context) + { + var featureChecker = context.ServiceProvider.GetRequiredService(); + return await featureChecker.IsEnabledAsync(_requiresAll, _featureNames); + } + } +} diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs deleted file mode 100644 index 299994e695..0000000000 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using JetBrains.Annotations; -using Volo.Abp.Authorization.Permissions; - -namespace Volo.Abp.GlobalFeatures -{ - public static class GlobalFeatureDefinitionExtensions - { - public static PermissionDefinition RequireGlobalFeatures( - this PermissionDefinition permissionDefinition, - params string[] globalFeatures) - { - return permissionDefinition.RequireGlobalFeatures(true, globalFeatures); - } - - public static PermissionDefinition RequireGlobalFeatures( - [NotNull] this PermissionDefinition permissionDefinition, - bool requiresAll, - params string[] globalFeatures) - { - Check.NotNull(permissionDefinition, nameof(permissionDefinition)); - Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); - - return permissionDefinition.AddStateProviders( - new RequireGlobalFeaturesPermissionStateProvider(requiresAll, globalFeatures) - ); - } - - public static PermissionDefinition RequireGlobalFeatures( - this PermissionDefinition permissionDefinition, - params Type[] globalFeatures) - { - return permissionDefinition.RequireGlobalFeatures(true, globalFeatures); - } - - public static PermissionDefinition RequireGlobalFeatures( - [NotNull] this PermissionDefinition permissionDefinition, - bool requiresAll, - params Type[] globalFeatures) - { - Check.NotNull(permissionDefinition, nameof(permissionDefinition)); - Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); - - return permissionDefinition.AddStateProviders( - new RequireGlobalFeaturesPermissionStateProvider(requiresAll, globalFeatures) - ); - } - - } -} diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureSimpleStateCheckerExtensions.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureSimpleStateCheckerExtensions.cs new file mode 100644 index 0000000000..dab3aa5b0e --- /dev/null +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureSimpleStateCheckerExtensions.cs @@ -0,0 +1,51 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.GlobalFeatures +{ + public static class GlobalFeatureSimpleStateCheckerExtensions + { + public static TState RequireGlobalFeatures( + [NotNull] this TState state, + params string[] globalFeatures) + where TState : IHasSimpleStateCheckers + { + return state.RequireGlobalFeatures(true, globalFeatures); + } + + public static TState RequireGlobalFeatures( + [NotNull] this TState state, + bool requiresAll, + params string[] globalFeatures) + where TState : IHasSimpleStateCheckers + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); + + state.SimpleStateCheckers.Add(new RequireGlobalFeaturesSimpleStateChecker(requiresAll, globalFeatures)); + return state; + } + + public static TState RequireGlobalFeatures( + [NotNull] this TState state, + params Type[] globalFeatures) + where TState : IHasSimpleStateCheckers + { + return state.RequireGlobalFeatures(true, globalFeatures); + } + + public static TState RequireGlobalFeatures( + [NotNull] this TState state, + bool requiresAll, + params Type[] globalFeatures) + where TState : IHasSimpleStateCheckers + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); + + state.SimpleStateCheckers.Add(new RequireGlobalFeaturesSimpleStateChecker(requiresAll, globalFeatures)); + return state; + } + } +} diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesSimpleStateChecker.cs similarity index 61% rename from framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs rename to framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesSimpleStateChecker.cs index c96e652e8c..12754d87df 100644 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesSimpleStateChecker.cs @@ -1,21 +1,22 @@ using System; using System.Linq; using System.Threading.Tasks; -using Volo.Abp.Authorization.Permissions; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.GlobalFeatures { - public class RequireGlobalFeaturesPermissionStateProvider : IPermissionStateProvider + public class RequireGlobalFeaturesSimpleStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers { private readonly string[] _globalFeatureNames; private readonly bool _requiresAll; - public RequireGlobalFeaturesPermissionStateProvider(params string[] globalFeatureNames) + public RequireGlobalFeaturesSimpleStateChecker(params string[] globalFeatureNames) : this(true, globalFeatureNames) { } - public RequireGlobalFeaturesPermissionStateProvider(bool requiresAll, params string[] globalFeatureNames) + public RequireGlobalFeaturesSimpleStateChecker(bool requiresAll, params string[] globalFeatureNames) { Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames)); @@ -23,7 +24,7 @@ namespace Volo.Abp.GlobalFeatures _globalFeatureNames = globalFeatureNames; } - public RequireGlobalFeaturesPermissionStateProvider(bool requiresAll, params Type[] globalFeatureNames) + public RequireGlobalFeaturesSimpleStateChecker(bool requiresAll, params Type[] globalFeatureNames) { Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames)); @@ -31,9 +32,9 @@ namespace Volo.Abp.GlobalFeatures _globalFeatureNames = globalFeatureNames.Select(GlobalFeatureNameAttribute.GetName).ToArray(); } - public Task IsEnabledAsync(PermissionStateContext context) + public Task IsEnabledAsync(SimpleStateCheckerContext context) { - bool isEnabled = _requiresAll + var isEnabled = _requiresAll ? _globalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x)) : _globalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x)); diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs index 63f4d7239d..ff2490cdeb 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.UI.Navigation { - public class ApplicationMenuItem : IHasMenuItems + public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers { private string _displayName; @@ -72,8 +73,11 @@ namespace Volo.Abp.UI.Navigation public ApplicationMenuItemList Items { get; } [CanBeNull] + [Obsolete("Use RequirePermissions extension method.")] public string RequiredPermissionName { get; set; } + public List> SimpleStateCheckers { get; } + /// /// Can be used to store a custom object related to this menu item. Optional. /// @@ -114,7 +118,7 @@ namespace Volo.Abp.UI.Navigation ElementId = elementId ?? GetDefaultElementId(); CssClass = cssClass; RequiredPermissionName = requiredPermissionName; - + SimpleStateCheckers = new List>(); Items = new ApplicationMenuItemList(); } diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs index 960389230e..24870070a7 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs @@ -2,10 +2,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.UI.Navigation { @@ -13,13 +13,16 @@ namespace Volo.Abp.UI.Navigation { protected AbpNavigationOptions Options { get; } protected IHybridServiceScopeFactory ServiceScopeFactory { get; } + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } public MenuManager( IOptions options, - IHybridServiceScopeFactory serviceScopeFactory) + IHybridServiceScopeFactory serviceScopeFactory, + ISimpleStateCheckerManager simpleStateCheckerManager) { - ServiceScopeFactory = serviceScopeFactory; Options = options.Value; + ServiceScopeFactory = serviceScopeFactory; + SimpleStateCheckerManager = simpleStateCheckerManager; } public async Task GetAsync(string name) @@ -45,18 +48,26 @@ namespace Volo.Abp.UI.Navigation protected virtual async Task CheckPermissionsAsync(IServiceProvider serviceProvider, IHasMenuItems menuWithItems) { - var requiredPermissionItems = new List(); - GetRequiredPermissionNameMenus(menuWithItems, requiredPermissionItems); + var allMenuItems = new List(); + GetAllMenuItems(menuWithItems, allMenuItems); - if (requiredPermissionItems.Any()) + foreach (var item in allMenuItems) { - var permissionChecker = serviceProvider.GetRequiredService(); - var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).Distinct().ToArray()); + if (!item.RequiredPermissionName.IsNullOrWhiteSpace()) + { + item.RequirePermissions(item.RequiredPermissionName); + } + } + var checkPermissionsMenuItems = allMenuItems.Where(x => x.SimpleStateCheckers.Any()).ToArray(); + + if (checkPermissionsMenuItems.Any()) + { var toBeDeleted = new HashSet(); - foreach (var menu in requiredPermissionItems) + var result = await SimpleStateCheckerManager.IsEnabledAsync(checkPermissionsMenuItems); + foreach (var menu in checkPermissionsMenuItems) { - if (grantResult.Result[menu.RequiredPermissionName!] != PermissionGrantResult.Granted) + if (!result[menu]) { toBeDeleted.Add(menu); } @@ -66,16 +77,12 @@ namespace Volo.Abp.UI.Navigation } } - protected virtual void GetRequiredPermissionNameMenus(IHasMenuItems menuWithItems, List output) + protected virtual void GetAllMenuItems(IHasMenuItems menuWithItems, List output) { foreach (var item in menuWithItems.Items) { - if (!item.RequiredPermissionName.IsNullOrWhiteSpace()) - { - output.Add(item); - } - - GetRequiredPermissionNameMenus(item, output); + output.Add(item); + GetAllMenuItems(item, output); } } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs index 70ca907fac..928a2af8de 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs @@ -11,6 +11,7 @@ using NSubstitute; using Shouldly; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; using Volo.Abp.AspNetCore.Mvc.UI.Theming; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; using Xunit; @@ -71,8 +72,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc. return Task.CompletedTask; } - context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent1), requiredPermissionName: "MyComponent1")); - context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent2), requiredPermissionName: "MyComponent2")); + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent1)).RequirePermissions("MyComponent1")); + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent2)).RequirePermissions("MyComponent2")); return Task.CompletedTask; } @@ -87,7 +88,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc. return Task.CompletedTask; } - context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent3), requiredPermissionName: "MyComponent3")); + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent3)).RequirePermissions("MyComponent3")); context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent4))); return Task.CompletedTask; diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs index f7ab858ac1..162fb755a4 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs @@ -5,19 +5,20 @@ using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; using Xunit; namespace Volo.Abp.Authorization { public abstract class PermissionStateProvider_Tests : AuthorizationTestBase { - protected IPermissionStateManager PermissionStateManager { get; } + protected ISimpleStateCheckerManager PermissionSimpleStateCheckerManager { get; } protected IPermissionDefinitionManager PermissionDefinitionManager { get; } protected ICurrentPrincipalAccessor CurrentPrincipalAccessor { get; } public PermissionStateProvider_Tests() { - PermissionStateManager = GetRequiredService(); + PermissionSimpleStateCheckerManager = GetRequiredService>(); PermissionDefinitionManager = GetRequiredService(); CurrentPrincipalAccessor = GetRequiredService(); } @@ -29,13 +30,13 @@ namespace Volo.Abp.Authorization public async Task PermissionState_Test() { var myPermission1 = PermissionDefinitionManager.Get("MyPermission1"); - myPermission1.StateProviders.ShouldContain(x => x.GetType() == typeof(TestRequireEditionPermissionStateProvider)); + myPermission1.SimpleStateCheckers.ShouldContain(x => x.GetType() == typeof(TestRequireEditionPermissionSimpleStateChecker)); - (await PermissionStateManager.IsEnabledAsync(myPermission1)).ShouldBeFalse(); + (await PermissionSimpleStateCheckerManager.IsEnabledAsync(myPermission1)).ShouldBeFalse(); using (CurrentPrincipalAccessor.Change(new Claim(AbpClaimTypes.EditionId, Guid.NewGuid().ToString()))) { - (await PermissionStateManager.IsEnabledAsync(myPermission1)).ShouldBeTrue(); + (await PermissionSimpleStateCheckerManager.IsEnabledAsync(myPermission1)).ShouldBeTrue(); } } } @@ -44,7 +45,10 @@ namespace Volo.Abp.Authorization { protected override void AfterAddApplication(IServiceCollection services) { - services.Configure(options => options.GlobalStateProviders.Add()); + services.Configure>(options => + { + options.GlobalSimpleStateCheckers.Add(); + }); } [Fact] @@ -52,11 +56,11 @@ namespace Volo.Abp.Authorization { var myPermission2 = PermissionDefinitionManager.Get("MyPermission2"); - (await PermissionStateManager.IsEnabledAsync(myPermission2)).ShouldBeFalse(); + (await PermissionSimpleStateCheckerManager.IsEnabledAsync(myPermission2)).ShouldBeFalse(); using (CurrentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "admin"))) { - (await PermissionStateManager.IsEnabledAsync(myPermission2)).ShouldBeTrue(); + (await PermissionSimpleStateCheckerManager.IsEnabledAsync(myPermission2)).ShouldBeTrue(); } } } diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionSimpleStateChecker.cs similarity index 65% rename from framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs rename to framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionSimpleStateChecker.cs index 6e3b58d2de..78726a343d 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionSimpleStateChecker.cs @@ -3,12 +3,13 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization { - public class TestGlobalRequireRolePermissionStateProvider : IPermissionStateProvider, ITransientDependency + public class TestGlobalRequireRolePermissionSimpleStateChecker : ISimpleStateChecker, ITransientDependency { - public Task IsEnabledAsync(PermissionStateContext context) + public Task IsEnabledAsync(SimpleStateCheckerContext context) { var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); return Task.FromResult(currentPrincipalAccessor.Principal != null && currentPrincipalAccessor.Principal.IsInRole("admin")); diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionSimpleStateChecker.cs similarity index 66% rename from framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs rename to framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionSimpleStateChecker.cs index a793c84431..8ce5ab9523 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionSimpleStateChecker.cs @@ -3,12 +3,13 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization { - public class TestRequireEditionPermissionStateProvider : IPermissionStateProvider + public class TestRequireEditionPermissionSimpleStateChecker : ISimpleStateChecker { - public Task IsEnabledAsync(PermissionStateContext context) + public Task IsEnabledAsync(SimpleStateCheckerContext context) { var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); return Task.FromResult(currentPrincipalAccessor.Principal?.FindEditionId() != null); diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs index d67cf8febc..868cc0225a 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.Authorization.TestServices group.AddPermission("MyAuthorizedService1"); - group.AddPermission("MyPermission1").AddStateProviders(new TestRequireEditionPermissionStateProvider()); + group.AddPermission("MyPermission1").SimpleStateCheckers.Add(new TestRequireEditionPermissionSimpleStateChecker()); group.AddPermission("MyPermission2"); group.GetPermissionOrNull("MyAuthorizedService1").ShouldNotBeNull(); diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpTestModule.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpTestModule.cs new file mode 100644 index 0000000000..b42ff1e6e8 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpTestModule.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp +{ + public class AbpTestModule : AbpModule + { + + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateCheckerTestBase.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateCheckerTestBase.cs new file mode 100644 index 0000000000..989cd9fdc2 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateCheckerTestBase.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Testing; + +namespace Volo.Abp.SimpleStateChecking +{ + public abstract class SimpleStateCheckerTestBase : AbpIntegratedTest + { + protected readonly ISimpleStateCheckerManager SimpleStateCheckerManager; + + public SimpleStateCheckerTestBase() + { + SimpleStateCheckerManager = GetRequiredService>(); + } + + public class MyStateEntity : IHasSimpleStateCheckers + { + public int CheckCount { get; set; } + + public int GlobalCheckCount { get; set; } + + public int MultipleCheckCount { get; set; } + + public int MultipleGlobalCheckCount { get; set; } + + public DateTime CreationTime { get; set; } + + public DateTime? LastModificationTime { get; set; } + + public List> SimpleStateCheckers { get; } + + public MyStateEntity() + { + SimpleStateCheckers = new List>(); + } + + public MyStateEntity AddSimpleStateChecker(ISimpleStateChecker checker) + { + SimpleStateCheckers.Add(checker); + return this; + } + } + + public class MySimpleStateChecker : ISimpleStateChecker + { + public Task IsEnabledAsync(SimpleStateCheckerContext context) + { + context.State.CheckCount += 1; + return Task.FromResult(context.State.CreationTime > DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture)); + } + } + + public class MyGlobalSimpleStateChecker : ISimpleStateChecker, ITransientDependency + { + public Task IsEnabledAsync(SimpleStateCheckerContext context) + { + context.State.GlobalCheckCount += 1; + return Task.FromResult(context.State.LastModificationTime.HasValue); + } + } + + public class MySimpleBatchStateChecker : SimpleBatchStateCheckerBase + { + public override Task> IsEnabledAsync(SimpleBatchStateCheckerContext context) + { + foreach (var state in context.States) + { + state.MultipleCheckCount += 1; + } + + var result = new SimpleStateCheckerResult(context.States); + + foreach (var x in result) + { + result[x.Key] = x.Key.CreationTime > DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture); + } + + return Task.FromResult(result); + } + } + + public class MyGlobalSimpleBatchStateChecker : SimpleBatchStateCheckerBase, ITransientDependency + { + public override Task> IsEnabledAsync(SimpleBatchStateCheckerContext context) + { + foreach (var state in context.States) + { + state.MultipleGlobalCheckCount += 1; + } + + var result = new SimpleStateCheckerResult(context.States); + + foreach (var x in result) + { + result[x.Key] = x.Key.LastModificationTime.HasValue; + } + + return Task.FromResult(result); + } + } + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_CheckCount_Test.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_CheckCount_Test.cs new file mode 100644 index 0000000000..ff7f320bb3 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_CheckCount_Test.cs @@ -0,0 +1,81 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateChecker_CheckCount_Test : SimpleStateCheckerTestBase + { + [Fact] + public async Task Simple_State_Check_Should_Be_Prevent_Multiple_Checks() + { + var myStateEntities = new SimpleStateCheckerTestBase.MyStateEntity[] + { + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture) + }, + + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture), + } + }; + + myStateEntities[0].AddSimpleStateChecker(new MySimpleBatchStateChecker()); + myStateEntities[1].AddSimpleStateChecker(new MySimpleStateChecker()); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities[0])).ShouldBeTrue(); + + myStateEntities[0].CheckCount.ShouldBe(0); + myStateEntities[0].GlobalCheckCount.ShouldBe(0); + myStateEntities[0].MultipleCheckCount.ShouldBe(1); + myStateEntities[0].MultipleGlobalCheckCount.ShouldBe(0); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities[1])).ShouldBeFalse(); + + myStateEntities[1].CheckCount.ShouldBe(1); + myStateEntities[1].GlobalCheckCount.ShouldBe(0); + myStateEntities[1].MultipleCheckCount.ShouldBe(0); + myStateEntities[1].MultipleGlobalCheckCount.ShouldBe(0); + } + + [Fact] + public async Task Multiple_And_Simple_State_Check_Should_Be_Prevent_Multiple_Checks() + { + var myStateEntities = new SimpleStateCheckerTestBase.MyStateEntity[] + { + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture) + }, + + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture), + } + }; + + myStateEntities[0].AddSimpleStateChecker(new MySimpleBatchStateChecker()); + myStateEntities[1].AddSimpleStateChecker(new MySimpleStateChecker()); + + var result = await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities); + result.Count.ShouldBe(2); + + result[myStateEntities[0]].ShouldBeTrue(); + result[myStateEntities[1]].ShouldBeFalse(); + + myStateEntities[0].CheckCount.ShouldBe(0); + myStateEntities[0].GlobalCheckCount.ShouldBe(0); + myStateEntities[0].MultipleCheckCount.ShouldBe(1); + myStateEntities[0].MultipleGlobalCheckCount.ShouldBe(0); + + myStateEntities[1].CheckCount.ShouldBe(1); + myStateEntities[1].GlobalCheckCount.ShouldBe(0); + myStateEntities[1].MultipleCheckCount.ShouldBe(0); + myStateEntities[1].MultipleGlobalCheckCount.ShouldBe(0); + } + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_GlobalCheckCount_Test.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_GlobalCheckCount_Test.cs new file mode 100644 index 0000000000..89905a3123 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_GlobalCheckCount_Test.cs @@ -0,0 +1,95 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateChecker_GlobalCheckCount_Test : SimpleStateCheckerTestBase + { + protected override void AfterAddApplication(IServiceCollection services) + { + services.Configure>(options => + { + options.GlobalSimpleStateCheckers.Add(); + options.GlobalSimpleStateCheckers.Add(); + }); + + base.AfterAddApplication(services); + } + + [Fact] + public async Task Simple_State_Check_Should_Be_Prevent_Multiple_Checks() + { + var myStateEntities = new SimpleStateCheckerTestBase.MyStateEntity[] + { + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture) + }, + + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture) + } + }; + + myStateEntities[0].AddSimpleStateChecker(new MySimpleBatchStateChecker()); + myStateEntities[1].AddSimpleStateChecker(new MySimpleStateChecker()); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities[0])).ShouldBeTrue(); + + myStateEntities[0].CheckCount.ShouldBe(0); + myStateEntities[0].GlobalCheckCount.ShouldBe(1); + myStateEntities[0].MultipleCheckCount.ShouldBe(1); + myStateEntities[0].MultipleGlobalCheckCount.ShouldBe(1); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities[1])).ShouldBeFalse(); + + myStateEntities[1].CheckCount.ShouldBe(1); + myStateEntities[1].GlobalCheckCount.ShouldBe(0); + myStateEntities[1].MultipleCheckCount.ShouldBe(0); + myStateEntities[1].MultipleGlobalCheckCount.ShouldBe(0); + } + + [Fact] + public async Task Multiple_And_Simple_State_Check_Should_Be_Prevent_Multiple_Checks() + { + var myStateEntities = new SimpleStateCheckerTestBase.MyStateEntity[] + { + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture) + }, + + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture) + } + }; + + myStateEntities[0].AddSimpleStateChecker(new MySimpleBatchStateChecker()); + myStateEntities[1].AddSimpleStateChecker(new MySimpleStateChecker()); + + var result = await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities); + result.Count.ShouldBe(2); + + result[myStateEntities[0]].ShouldBeTrue(); + result[myStateEntities[1]].ShouldBeFalse(); + + myStateEntities[0].CheckCount.ShouldBe(0); + myStateEntities[0].GlobalCheckCount.ShouldBe(1); + myStateEntities[0].MultipleCheckCount.ShouldBe(1); + myStateEntities[0].MultipleGlobalCheckCount.ShouldBe(1); + + myStateEntities[1].CheckCount.ShouldBe(0); + myStateEntities[1].GlobalCheckCount.ShouldBe(0); + myStateEntities[1].MultipleCheckCount.ShouldBe(0); + myStateEntities[1].MultipleGlobalCheckCount.ShouldBe(1); + } + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_Tests.cs new file mode 100644 index 0000000000..536f8c3c68 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_Tests.cs @@ -0,0 +1,105 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateChecker_Tests : SimpleStateCheckerTestBase + { + protected override void AfterAddApplication(IServiceCollection services) + { + services.Configure>(options => + { + options.GlobalSimpleStateCheckers.Add(); + options.GlobalSimpleStateCheckers.Add(); + }); + + base.AfterAddApplication(services); + } + + [Fact] + public async Task State_Check_Should_Be_Works() + { + var myStateEntity = new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + }; + myStateEntity.AddSimpleStateChecker(new MySimpleStateChecker()); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeTrue(); + + myStateEntity.CreationTime = DateTime.Parse("2001-01-01", CultureInfo.InvariantCulture); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeFalse(); + } + + [Fact] + public async Task Global_State_Check_Should_Be_Works() + { + var myStateEntity = new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + }; + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeFalse(); + + myStateEntity.LastModificationTime = DateTime.Parse("2001-01-01", CultureInfo.InvariantCulture); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeTrue(); + } + + [Fact] + public async Task Multiple_State_Check_Should_Be_Works() + { + var checker = new MySimpleBatchStateChecker(); + + var myStateEntities = new MyStateEntity[] + { + new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + }, + + new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + } + }; + + foreach (var myStateEntity in myStateEntities) + { + myStateEntity.AddSimpleStateChecker(checker); + } + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities)).ShouldAllBe(x => x.Value); + + foreach (var myStateEntity in myStateEntities) + { + myStateEntity.CreationTime = DateTime.Parse("2001-01-01", CultureInfo.InvariantCulture); + } + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities)).ShouldAllBe(x => !x.Value); + } + + [Fact] + public async Task Multiple_Global_State_Check_Should_Be_Works() + { + var myStateEntity = new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + }; + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeFalse(); + + myStateEntity.LastModificationTime = DateTime.Parse("2001-01-01", CultureInfo.InvariantCulture); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeTrue(); + } + } +} diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs index c72082945b..d641969f9a 100644 --- a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using NSubstitute; using Shouldly; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; using Volo.Abp.Testing; using Xunit; @@ -73,8 +74,8 @@ namespace Volo.Abp.UI.Navigation var administration = context.Menu.GetAdministration(); - administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users", requiredPermissionName: "Administration.UserManagement")); - administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles", requiredPermissionName: "Administration.RoleManagement")); + administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users").RequirePermissions("Administration.UserManagement")); + administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles").RequirePermissions("Administration.RoleManagement")); return Task.CompletedTask; } @@ -94,16 +95,16 @@ namespace Volo.Abp.UI.Navigation return Task.CompletedTask; } - context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard", requiredPermissionName: "Dashboard")); + context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard").RequirePermissions("Dashboard")); var administration = context.Menu.GetAdministration(); - administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard", requiredPermissionName: "Administration.DashboardSettings")); + administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard").RequirePermissions("Administration.DashboardSettings")); administration.AddItem( new ApplicationMenuItem("Administration.SubMenu1", "Sub menu 1", url: "/submenu1") - .AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1", requiredPermissionName: "Administration.SubMenu1.1")) - .AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2", requiredPermissionName: "Administration.SubMenu1.2")) + .AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1").RequirePermissions("Administration.SubMenu1.1")) + .AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2").RequirePermissions("Administration.SubMenu1.2")) ); return Task.CompletedTask; diff --git a/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs b/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs index 43e4bfca5b..93fe6c60d7 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs +++ b/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; using Volo.Blogging.Localization; namespace Volo.Blogging.Admin @@ -18,9 +19,9 @@ namespace Volo.Blogging.Admin { var l = context.GetLocalizer(); - var managementRootMenuItem = new ApplicationMenuItem("BlogManagement", l["Menu:BlogManagement"], requiredPermissionName: BloggingPermissions.Blogs.Management); + var managementRootMenuItem = new ApplicationMenuItem("BlogManagement", l["Menu:BlogManagement"]).RequirePermissions(BloggingPermissions.Blogs.Management); - managementRootMenuItem.AddItem(new ApplicationMenuItem("BlogManagement.Blogs", l["Menu:Blogs"], "~/Blogging/Admin/Blogs", requiredPermissionName: BloggingPermissions.Blogs.Management)); + managementRootMenuItem.AddItem(new ApplicationMenuItem("BlogManagement.Blogs", l["Menu:Blogs"], "~/Blogging/Admin/Blogs").RequirePermissions(BloggingPermissions.Blogs.Management)); context.Menu.GetAdministration().AddItem(managementRootMenuItem); diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs b/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs index 644dd037c4..41eba37ced 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs +++ b/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; using Volo.Docs.Localization; namespace Volo.Docs.Admin.Navigation @@ -27,8 +28,8 @@ namespace Volo.Docs.Admin.Navigation administrationMenu.AddItem(rootMenuItem); - rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Projects, l["Menu:ProjectManagement"], "~/Docs/Admin/Projects", requiredPermissionName: DocsAdminPermissions.Projects.Default)); - rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Documents, l["Menu:DocumentManagement"], "~/Docs/Admin/Documents", requiredPermissionName: DocsAdminPermissions.Documents.Default)); + rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Projects, l["Menu:ProjectManagement"], "~/Docs/Admin/Projects").RequirePermissions(DocsAdminPermissions.Projects.Default)); + rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Documents, l["Menu:DocumentManagement"], "~/Docs/Admin/Documents").RequirePermissions(DocsAdminPermissions.Documents.Default)); return Task.CompletedTask; } diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs index 9b75491d0b..e651e54f04 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Volo.Abp.Identity.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.Identity.Blazor { @@ -24,15 +25,13 @@ namespace Volo.Abp.Identity.Blazor identityMenuItem.AddItem(new ApplicationMenuItem( IdentityMenuNames.Roles, l["Roles"], - url: "~/identity/roles", - requiredPermissionName: IdentityPermissions.Roles.Default)); + url: "~/identity/roles").RequirePermissions(IdentityPermissions.Roles.Default)); identityMenuItem.AddItem(new ApplicationMenuItem( IdentityMenuNames.Users, l["Users"], - url: "~/identity/users", - requiredPermissionName: IdentityPermissions.Users.Default)); + url: "~/identity/users").RequirePermissions(IdentityPermissions.Users.Default)); return Task.CompletedTask; } diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs b/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs index 2f48318511..a6355a794a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Volo.Abp.Identity.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.Identity.Web.Navigation { @@ -19,8 +20,8 @@ namespace Volo.Abp.Identity.Web.Navigation var l = context.GetLocalizer(); var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], icon: "fa fa-id-card-o"); - identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "~/Identity/Roles", requiredPermissionName: IdentityPermissions.Roles.Default)); - identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "~/Identity/Users", requiredPermissionName: IdentityPermissions.Users.Default)); + identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "~/Identity/Roles").RequirePermissions(IdentityPermissions.Roles.Default)); + identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "~/Identity/Users").RequirePermissions( IdentityPermissions.Users.Default)); context.Menu.GetAdministration().AddItem(identityMenuItem); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs index 4bc73a6f86..abcbcd6a48 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Options; using Volo.Abp.Application.Services; using Volo.Abp.Authorization.Permissions; using Volo.Abp.MultiTenancy; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.PermissionManagement { @@ -16,18 +17,18 @@ namespace Volo.Abp.PermissionManagement protected PermissionManagementOptions Options { get; } protected IPermissionManager PermissionManager { get; } protected IPermissionDefinitionManager PermissionDefinitionManager { get; } - protected IPermissionStateManager PermissionStateManager { get; } + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } public PermissionAppService( IPermissionManager permissionManager, IPermissionDefinitionManager permissionDefinitionManager, IOptions options, - IPermissionStateManager permissionStateManager) + ISimpleStateCheckerManager simpleStateCheckerManager) { Options = options.Value; PermissionManager = permissionManager; PermissionDefinitionManager = permissionDefinitionManager; - PermissionStateManager = permissionStateManager; + SimpleStateCheckerManager = simpleStateCheckerManager; } public virtual async Task GetAsync(string providerName, string providerKey) @@ -58,7 +59,7 @@ namespace Volo.Abp.PermissionManagement continue; } - if (!await PermissionStateManager.IsEnabledAsync(permission)) + if (!await SimpleStateCheckerManager.IsEnabledAsync(permission)) { continue; } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs index c178a6ae0e..d0ee7c4853 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs @@ -9,6 +9,7 @@ using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.PermissionManagement { @@ -18,7 +19,7 @@ namespace Volo.Abp.PermissionManagement protected IPermissionDefinitionManager PermissionDefinitionManager { get; } - protected IPermissionStateManager PermissionStateManager { get; } + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } protected IGuidGenerator GuidGenerator { get; } @@ -34,7 +35,7 @@ namespace Volo.Abp.PermissionManagement public PermissionManager( IPermissionDefinitionManager permissionDefinitionManager, - IPermissionStateManager permissionStateManager, + ISimpleStateCheckerManager simpleStateCheckerManager, IPermissionGrantRepository permissionGrantRepository, IServiceProvider serviceProvider, IGuidGenerator guidGenerator, @@ -45,7 +46,7 @@ namespace Volo.Abp.PermissionManagement GuidGenerator = guidGenerator; CurrentTenant = currentTenant; Cache = cache; - PermissionStateManager = permissionStateManager; + SimpleStateCheckerManager = simpleStateCheckerManager; PermissionGrantRepository = permissionGrantRepository; PermissionDefinitionManager = permissionDefinitionManager; Options = options.Value; @@ -80,7 +81,7 @@ namespace Volo.Abp.PermissionManagement { var permission = PermissionDefinitionManager.Get(permissionName); - if (!permission.IsEnabled || !await PermissionStateManager.IsEnabledAsync(permission)) + if (!permission.IsEnabled || !await SimpleStateCheckerManager.IsEnabledAsync(permission)) { //TODO: BusinessException throw new ApplicationException($"The permission named '{permission.Name}' is disabled!"); @@ -150,7 +151,7 @@ namespace Volo.Abp.PermissionManagement return result; } - if (!await PermissionStateManager.IsEnabledAsync(permission)) + if (!await SimpleStateCheckerManager.IsEnabledAsync(permission)) { return result; } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs index d2256a5868..86b2057239 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.PermissionManagement testGroup.AddPermission("MyPermission4", multiTenancySide: MultiTenancySides.Host).WithProviders(UserPermissionValueProvider.ProviderName); - testGroup.AddPermission("MyPermission5").AddStateProviders(new TestRequireRolePermissionStateProvider("super-admin")); + testGroup.AddPermission("MyPermission5").SimpleStateCheckers.Add(new TestRequireRolePermissionStateProvider("super-admin")); } } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs index 56e34f2894..3531479b43 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs @@ -4,10 +4,11 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.PermissionManagement { - public class TestRequireRolePermissionStateProvider : IPermissionStateProvider + public class TestRequireRolePermissionStateProvider : ISimpleStateChecker { private readonly List _allowRoles = new List(); @@ -16,7 +17,7 @@ namespace Volo.Abp.PermissionManagement _allowRoles.AddRange(roles); } - public Task IsEnabledAsync(PermissionStateContext context) + public Task IsEnabledAsync(SimpleStateCheckerContext context) { var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); return Task.FromResult(currentPrincipalAccessor.Principal != null && _allowRoles.Any(role => currentPrincipalAccessor.Principal.IsInRole(role))); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs index 3f4fa8683c..193cfb034b 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Volo.Abp.TenantManagement.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.TenantManagement.Blazor.Navigation { @@ -27,9 +28,8 @@ namespace Volo.Abp.TenantManagement.Blazor.Navigation tenantManagementMenuItem.AddItem(new ApplicationMenuItem( TenantManagementMenuNames.Tenants, l["Tenants"], - url: "~/tenant-management/tenants", - requiredPermissionName: TenantManagementPermissions.Tenants.Default - )); + url: "~/tenant-management/tenants" + ).RequirePermissions(TenantManagementPermissions.Tenants.Default)); return Task.CompletedTask; } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs index c3ebaa39b5..1cc917c311 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Volo.Abp.TenantManagement.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.TenantManagement.Web.Navigation { @@ -23,7 +24,7 @@ namespace Volo.Abp.TenantManagement.Web.Navigation var tenantManagementMenuItem = new ApplicationMenuItem(TenantManagementMenuNames.GroupName, l["Menu:TenantManagement"], icon: "fa fa-users"); administrationMenu.AddItem(tenantManagementMenuItem); - tenantManagementMenuItem.AddItem(new ApplicationMenuItem(TenantManagementMenuNames.Tenants, l["Tenants"], url: "~/TenantManagement/Tenants", requiredPermissionName: TenantManagementPermissions.Tenants.Default)); + tenantManagementMenuItem.AddItem(new ApplicationMenuItem(TenantManagementMenuNames.Tenants, l["Tenants"], url: "~/TenantManagement/Tenants").RequirePermissions(TenantManagementPermissions.Tenants.Default)); return Task.CompletedTask; }