From 6754ea3de4c444a44b5219af47e5f9e103215e5b Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 9 Nov 2020 16:37:32 +0800 Subject: [PATCH 1/7] Make IPermissionChecker support batch check. --- .../Mvc/Client/RemotePermissionChecker.cs | 23 +++++- .../AbpApplicationConfigurationAppService.cs | 35 +++++++++ .../Authorization/AbpAuthorizationModule.cs | 3 + .../AlwaysAllowPermissionChecker.cs | 21 ++++- .../ClientPermissionValueProvider.cs | 22 +++++- .../Permissions/IPermissionChecker.cs | 9 ++- .../Permissions/IPermissionStore.cs | 6 ++ .../Permissions/IPermissionValueProvider.cs | 7 +- .../MultiplePermissionGrantResult.cs | 31 ++++++++ .../Permissions/NullPermissionStore.cs | 12 ++- .../Permissions/PermissionChecker.cs | 62 ++++++++++++++- .../Permissions/PermissionValueProvider.cs | 7 +- .../PermissionValuesCheckContext.cs | 25 ++++++ .../RolePermissionValueProvider.cs | 40 +++++++++- .../UserPermissionValueProvider.cs | 22 +++++- .../Mvc/Authorization/FakePermissionStore.cs | 15 ++++ .../PermissionGrantCacheItem.cs | 11 ++- .../PermissionManagement/PermissionStore.cs | 78 +++++++++++++++++-- 18 files changed, 405 insertions(+), 24 deletions(-) create mode 100644 framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs create mode 100644 framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValuesCheckContext.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs index 18f5272e7b..66f9aea05a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs @@ -1,4 +1,5 @@ -using System.Security.Claims; +using System.Collections.Generic; +using System.Security.Claims; using System.Threading.Tasks; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; @@ -26,5 +27,25 @@ namespace Volo.Abp.AspNetCore.Mvc.Client /* This provider always works for the current principal. */ return await IsGrantedAsync(name); } + + public async Task IsGrantedAsync(string[] names) + { + var result = new MultiplePermissionGrantResult(); + var configuration = await ConfigurationClient.GetAsync(); + foreach (var name in names) + { + result.Result.Add(name, configuration.Auth.GrantedPolicies.ContainsKey(name) ? + PermissionGrantResult.Granted : + PermissionGrantResult.Undefined); + } + + return result; + } + + public async Task IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string[] names) + { + /* This provider always works for the current principal. */ + return await IsGrantedAsync(names); + } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs index 89bf3e7cfc..e02132a84a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs @@ -5,12 +5,14 @@ using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Volo.Abp.Application.Services; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending; using Volo.Abp.AspNetCore.Mvc.MultiTenancy; using Volo.Abp.Authorization; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Features; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; @@ -26,6 +28,9 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations private readonly AbpMultiTenancyOptions _multiTenancyOptions; private readonly IServiceProvider _serviceProvider; private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider; + private readonly IPermissionDefinitionManager _permissionDefinitionManager; + private readonly DefaultAuthorizationPolicyProvider _defaultAuthorizationPolicyProvider; + private readonly IPermissionChecker _permissionChecker; private readonly IAuthorizationService _authorizationService; private readonly ICurrentUser _currentUser; private readonly ISettingProvider _settingProvider; @@ -41,6 +46,9 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations IOptions multiTenancyOptions, IServiceProvider serviceProvider, IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider, + IPermissionDefinitionManager permissionDefinitionManager, + DefaultAuthorizationPolicyProvider defaultAuthorizationPolicyProvider, + IPermissionChecker permissionChecker, IAuthorizationService authorizationService, ICurrentUser currentUser, ISettingProvider settingProvider, @@ -53,6 +61,9 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations { _serviceProvider = serviceProvider; _abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider; + _permissionDefinitionManager = permissionDefinitionManager; + _defaultAuthorizationPolicyProvider = defaultAuthorizationPolicyProvider; + _permissionChecker = permissionChecker; _authorizationService = authorizationService; _currentUser = currentUser; _settingProvider = settingProvider; @@ -132,8 +143,22 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations var authConfig = new ApplicationAuthConfigurationDto(); var policyNames = await _abpAuthorizationPolicyProvider.GetPoliciesNamesAsync(); + var abpPolicyNames = new List(); + var otherPolicyNames = new List(); foreach (var policyName in policyNames) + { + if(await _defaultAuthorizationPolicyProvider.GetPolicyAsync(policyName) == null && _permissionDefinitionManager.GetOrNull(policyName) != null) + { + abpPolicyNames.Add(policyName); + } + else + { + otherPolicyNames.Add(policyName); + } + } + + foreach (var policyName in otherPolicyNames) { authConfig.Policies[policyName] = true; @@ -143,6 +168,16 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations } } + var result = await _permissionChecker.IsGrantedAsync(abpPolicyNames.ToArray()); + foreach (var (key, value) in result.Result) + { + authConfig.Policies[key] = true; + if (value == PermissionGrantResult.Granted) + { + authConfig.GrantedPolicies[key] = true; + } + } + return authConfig; } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs index 86b2b18d04..b16e08a214 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Localization; using Volo.Abp.Modularity; @@ -29,6 +30,8 @@ namespace Volo.Abp.Authorization context.Services.AddSingleton(); + context.Services.TryAddTransient(); + Configure(options => { options.ValueProviders.Add(); diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs index e3f4425289..9efcfeb293 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs @@ -1,4 +1,6 @@ -using System.Security.Claims; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; using Volo.Abp.Threading; @@ -6,7 +8,7 @@ namespace Volo.Abp.Authorization.Permissions { /// /// Always allows for any permission. - /// + /// /// Use IServiceCollection.AddAlwaysAllowAuthorization() to replace /// IPermissionChecker with this class. This is useful for tests. /// @@ -21,5 +23,20 @@ namespace Volo.Abp.Authorization.Permissions { return TaskCache.TrueResult; } + + public Task IsGrantedAsync(string[] names) + { + return IsGrantedAsync(null, names); + } + + public Task IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string[] names) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in names) + { + result.Result.Add(name, PermissionGrantResult.Granted); + } + return Task.FromResult(result); + } } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs index c1d9b3a6dc..5e9f34767b 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.Security.Claims; namespace Volo.Abp.Authorization.Permissions @@ -28,5 +30,23 @@ namespace Volo.Abp.Authorization.Permissions ? PermissionGrantResult.Granted : PermissionGrantResult.Undefined; } + + public async override Task CheckAsync(PermissionValuesCheckContext context) + { + var result = new MultiplePermissionGrantResult(); + var permissionNames = context.Permissions.Select(x => x.Name).ToList(); + foreach (var name in permissionNames) + { + result.Result.Add(name, PermissionGrantResult.Undefined); + } + + var clientId = context.Principal?.FindFirst(AbpClaimTypes.ClientId)?.Value; + if (clientId == null) + { + return result; + } + + return await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, clientId); + } } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs index b394a29f52..91987b408d 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs @@ -1,4 +1,5 @@ -using System.Security.Claims; +using System.Collections.Generic; +using System.Security.Claims; using System.Threading.Tasks; using JetBrains.Annotations; @@ -9,5 +10,9 @@ namespace Volo.Abp.Authorization.Permissions Task IsGrantedAsync([NotNull]string name); Task IsGrantedAsync([CanBeNull] ClaimsPrincipal claimsPrincipal, [NotNull]string name); + + Task IsGrantedAsync([NotNull]string[] names); + + Task IsGrantedAsync([CanBeNull] ClaimsPrincipal claimsPrincipal, [NotNull]string[] names); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionStore.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionStore.cs index b2d077d3c7..08ca09fc72 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionStore.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionStore.cs @@ -10,5 +10,11 @@ namespace Volo.Abp.Authorization.Permissions [CanBeNull] string providerName, [CanBeNull] string providerKey ); + + Task IsGrantedAsync( + [NotNull] string[] names, + [CanBeNull] string providerName, + [CanBeNull] string providerKey + ); } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs index a9b5e78337..9d69b6d55d 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; namespace Volo.Abp.Authorization.Permissions { @@ -8,5 +9,7 @@ namespace Volo.Abp.Authorization.Permissions //TODO: Rename to GetResult? (CheckAsync throws exception by naming convention) Task CheckAsync(PermissionValueCheckContext context); + + Task CheckAsync(PermissionValuesCheckContext context); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs new file mode 100644 index 0000000000..dd0aff0633 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Volo.Abp.Authorization.Permissions +{ + public class MultiplePermissionGrantResult + { + public bool AllGranted + { + get + { + return Result.Values.All(x => x == PermissionGrantResult.Granted); + } + } + + public bool AllProhibited + { + get + { + return Result.Values.All(x => x == PermissionGrantResult.Prohibited); + } + } + + public Dictionary Result { get; } + + public MultiplePermissionGrantResult() + { + Result = new Dictionary(); + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs index 57c76ac6c9..df2311d6b6 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs @@ -19,5 +19,15 @@ namespace Volo.Abp.Authorization.Permissions { return TaskCache.FalseResult; } + + public Task IsGrantedAsync(string[] names, string providerName, string providerKey) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in names) + { + result.Result.Add(name, PermissionGrantResult.Prohibited); + } + return Task.FromResult(result); + } } -} \ No newline at end of file +} 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 931c9d1d23..49f5ba24e5 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 @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using System.Security.Claims; using System.Security.Principal; using System.Threading.Tasks; @@ -17,7 +18,7 @@ namespace Volo.Abp.Authorization.Permissions public PermissionChecker( ICurrentPrincipalAccessor principalAccessor, - IPermissionDefinitionManager permissionDefinitionManager, + IPermissionDefinitionManager permissionDefinitionManager, ICurrentTenant currentTenant, IPermissionValueProviderManager permissionValueProviderManager) { @@ -33,7 +34,7 @@ namespace Volo.Abp.Authorization.Permissions } public virtual async Task IsGrantedAsync( - ClaimsPrincipal claimsPrincipal, + ClaimsPrincipal claimsPrincipal, string name) { Check.NotNull(name, nameof(name)); @@ -77,5 +78,58 @@ namespace Volo.Abp.Authorization.Permissions return isGranted; } + + public async Task IsGrantedAsync(string[] names) + { + return await IsGrantedAsync(PrincipalAccessor.Principal, names); + } + + public async Task IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string[] names) + { + Check.NotNull(names, nameof(names)); + + var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() + ?? CurrentTenant.GetMultiTenancySide(); + + var result = new MultiplePermissionGrantResult(); + + var definitions = new List(); + foreach (var name in names) + { + var permission = PermissionDefinitionManager.Get(name); + if (!permission.IsEnabled || !permission.MultiTenancySide.HasFlag(multiTenancySide)) + { + result.Result.Add(name, PermissionGrantResult.Undefined); + continue; + } + + result.Result.Add(name, PermissionGrantResult.Undefined); + definitions.Add(permission); + } + + foreach (var provider in PermissionValueProviderManager.ValueProviders) + { + var context = new PermissionValuesCheckContext(definitions.Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)).ToList(), + claimsPrincipal); + + foreach (var grantResult in (await provider.CheckAsync(context)).Result) + { + if (result.Result.ContainsKey(grantResult.Key) && + result.Result[grantResult.Key] == PermissionGrantResult.Undefined && + grantResult.Value != PermissionGrantResult.Undefined) + { + result.Result[grantResult.Key] = grantResult.Value; + definitions.Remove(definitions.First(x => x.Name == grantResult.Key)); + } + + if (result.AllGranted || result.AllProhibited) + { + break; + } + } + } + + return result; + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs index d15311b77c..47ed4e7722 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Authorization.Permissions @@ -15,5 +16,7 @@ namespace Volo.Abp.Authorization.Permissions } public abstract Task CheckAsync(PermissionValueCheckContext context); + + public abstract Task CheckAsync(PermissionValuesCheckContext context); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValuesCheckContext.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValuesCheckContext.cs new file mode 100644 index 0000000000..e9014eff94 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValuesCheckContext.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Security.Claims; +using JetBrains.Annotations; + +namespace Volo.Abp.Authorization.Permissions +{ + public class PermissionValuesCheckContext + { + [NotNull] + public List Permissions { get; } + + [CanBeNull] + public ClaimsPrincipal Principal { get; } + + public PermissionValuesCheckContext( + [NotNull] List permissions, + [CanBeNull] ClaimsPrincipal principal) + { + Check.NotNull(permissions, nameof(permissions)); + + Permissions = permissions; + Principal = principal; + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs index a458cd8fdb..5ae21a3ecc 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Volo.Abp.Security.Claims; @@ -35,5 +36,42 @@ namespace Volo.Abp.Authorization.Permissions return PermissionGrantResult.Undefined; } + + public async override Task CheckAsync(PermissionValuesCheckContext context) + { + var result = new MultiplePermissionGrantResult(); + var permissionNames = context.Permissions.Select(x => x.Name).ToList(); + foreach (var name in permissionNames) + { + result.Result.Add(name, PermissionGrantResult.Undefined); + } + + var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray(); + if (roles == null || !roles.Any()) + { + return result; + } + + foreach (var role in roles) + { + foreach (var grantResult in (await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, role)).Result) + { + if (result.Result.ContainsKey(grantResult.Key) && + result.Result[grantResult.Key] == PermissionGrantResult.Undefined && + grantResult.Value != PermissionGrantResult.Undefined) + { + result.Result[grantResult.Key] = grantResult.Value; + permissionNames.Remove(grantResult.Key); + } + } + + if (result.AllGranted) + { + break; + } + } + + return result; + } } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs index 204b928e61..ae40285cee 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.Security.Claims; namespace Volo.Abp.Authorization.Permissions @@ -28,5 +30,23 @@ namespace Volo.Abp.Authorization.Permissions ? PermissionGrantResult.Granted : PermissionGrantResult.Undefined; } + + public async override Task CheckAsync(PermissionValuesCheckContext context) + { + var result = new MultiplePermissionGrantResult(); + var permissionNames = context.Permissions.Select(x => x.Name).ToList(); + foreach (var name in permissionNames) + { + result.Result.Add(name, PermissionGrantResult.Undefined); + } + + var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value; + if (userId == null) + { + return result; + } + + return await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, userId); + } } } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/FakePermissionStore.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/FakePermissionStore.cs index 175e281716..6509d6dce2 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/FakePermissionStore.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/FakePermissionStore.cs @@ -14,5 +14,20 @@ namespace Volo.Abp.AspNetCore.Mvc.Authorization return Task.FromResult(result); } + + public Task IsGrantedAsync(string[] names, string providerName, string providerKey) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in names) + { + result.Result.Add(name, name == "TestPermission1" && + providerName == UserPermissionValueProvider.ProviderName && + providerKey == AuthTestController.FakeUserId.ToString() + ? PermissionGrantResult.Granted + : PermissionGrantResult.Undefined); + } + + return Task.FromResult(result); + } } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItem.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItem.cs index 49013954a2..47a7e1530c 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItem.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItem.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using Volo.Abp.Text.Formatting; namespace Volo.Abp.PermissionManagement { @@ -21,5 +23,12 @@ namespace Volo.Abp.PermissionManagement { return "pn:" + providerName + ",pk:" + providerKey + ",n:" + name; } + + public static string ParseCacheKeyOrNull(string key) + { + var format = "pn:{0},pk:{1},n:{2}"; + var result = FormattedStringValueExtracter.Extract(key, format, true); + return result.IsMatch ? result.Matches.Last().Value : null; + } } -} \ No newline at end of file +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs index bdfdc38881..b80c0b3fa1 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs @@ -35,6 +35,21 @@ namespace Volo.Abp.PermissionManagement return (await GetCacheItemAsync(name, providerName, providerKey)).IsGranted; } + public virtual async Task IsGrantedAsync(string[] names, string providerName, string providerKey) + { + var result = new MultiplePermissionGrantResult(); + + var cacheItems = await GetCacheItemsAsync(names, providerName, providerKey); + foreach (var item in cacheItems) + { + result.Result.Add(PermissionGrantCacheItem.ParseCacheKeyOrNull(item.Key), item.Value.IsGranted + ? PermissionGrantResult.Granted : + PermissionGrantResult.Undefined); + } + + return result; + } + protected virtual async Task GetCacheItemAsync( string name, string providerName, @@ -53,9 +68,9 @@ namespace Volo.Abp.PermissionManagement } Logger.LogDebug($"Not found in the cache: {cacheKey}"); - + cacheItem = new PermissionGrantCacheItem(false); - + await SetCacheItemsAsync(providerName, providerKey, name, cacheItem); return cacheItem; @@ -68,7 +83,7 @@ namespace Volo.Abp.PermissionManagement PermissionGrantCacheItem currentCacheItem) { var permissions = PermissionDefinitionManager.GetPermissions(); - + Logger.LogDebug($"Getting all granted permissions from the repository for this provider name,key: {providerName},{providerKey}"); var grantedPermissionsHashSet = new HashSet( @@ -87,7 +102,7 @@ namespace Volo.Abp.PermissionManagement CalculateCacheKey(permission.Name, providerName, providerKey), new PermissionGrantCacheItem(isGranted)) ); - + if (permission.Name == currentName) { currentCacheItem.IsGranted = isGranted; @@ -95,13 +110,64 @@ namespace Volo.Abp.PermissionManagement } await Cache.SetManyAsync(cacheItems); - + Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}"); } + protected virtual async Task>> GetCacheItemsAsync( + string[] names, + string providerName, + string providerKey) + { + var cacheKeys = names.Select(x => CalculateCacheKey(x, providerName, providerKey)).ToList(); + var cacheItems = (await Cache.GetManyAsync(cacheKeys)).ToList(); + if (cacheItems.All(x => x.Value != null)) + { + return cacheItems; + } + + return cacheItems.Where(x => x.Value != null) + .Union(await SetCacheItemsAsync(providerName, providerKey, cacheItems.Where(x => x.Value == null))) + .ToList(); + } + + protected virtual async Task>> SetCacheItemsAsync( + string providerName, + string providerKey, + IEnumerable> notCacheItems) + { + var permissions = PermissionDefinitionManager.GetPermissions(); + + Logger.LogDebug($"Getting all granted permissions from the repository for this provider name,key: {providerName},{providerKey}"); + + var grantedPermissionsHashSet = new HashSet( + (await PermissionGrantRepository.GetListAsync(providerName, providerKey)).Select(p => p.Name) + ); + + Logger.LogDebug($"Setting the cache items. Count: {permissions.Count}"); + + var cacheItems = new List>(); + + foreach (var permission in permissions) + { + var isGranted = grantedPermissionsHashSet.Contains(permission.Name); + + cacheItems.Add(new KeyValuePair( + CalculateCacheKey(permission.Name, providerName, providerKey), + new PermissionGrantCacheItem(isGranted)) + ); + } + + await Cache.SetManyAsync(cacheItems); + + Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}"); + + return cacheItems.Where(x => notCacheItems.Any(y => x.Key == y.Key)).ToList(); + } + protected virtual string CalculateCacheKey(string name, string providerName, string providerKey) { return PermissionGrantCacheItem.CalculateCacheKey(name, providerName, providerKey); } } -} \ No newline at end of file +} From 8498f558bf521306d74ec4b978d7f68d1379a463 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 9 Nov 2020 21:10:10 +0800 Subject: [PATCH 2/7] Refactor. --- .../Mvc/Client/RemotePermissionChecker.cs | 1 - .../AlwaysAllowPermissionChecker.cs | 11 +-- .../ClientPermissionValueProvider.cs | 14 +--- .../MultiplePermissionGrantResult.cs | 12 +++ .../Permissions/NullPermissionStore.cs | 7 +- .../Permissions/PermissionChecker.cs | 18 +++-- .../RolePermissionValueProvider.cs | 13 ++-- .../UserPermissionValueProvider.cs | 14 +--- .../Mvc/Authorization/FakePermissionStore.cs | 2 +- .../PermissionGrantCacheItem.cs | 9 ++- .../PermissionManagement/PermissionStore.cs | 73 ++++++++++++++----- 11 files changed, 98 insertions(+), 76 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs index 66f9aea05a..5ce1ea9edc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Security.Claims; using System.Threading.Tasks; using Volo.Abp.Authorization.Permissions; diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs index 9efcfeb293..f3a90ec976 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; +using System.Security.Claims; using System.Threading.Tasks; using Volo.Abp.Threading; @@ -31,12 +29,7 @@ namespace Volo.Abp.Authorization.Permissions public Task IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string[] names) { - var result = new MultiplePermissionGrantResult(); - foreach (var name in names) - { - result.Result.Add(name, PermissionGrantResult.Granted); - } - return Task.FromResult(result); + return Task.FromResult(new MultiplePermissionGrantResult(names, PermissionGrantResult.Granted)); } } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs index 5e9f34767b..7465acc087 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using Volo.Abp.Security.Claims; @@ -33,20 +32,15 @@ namespace Volo.Abp.Authorization.Permissions public async override Task CheckAsync(PermissionValuesCheckContext context) { - var result = new MultiplePermissionGrantResult(); - var permissionNames = context.Permissions.Select(x => x.Name).ToList(); - foreach (var name in permissionNames) - { - result.Result.Add(name, PermissionGrantResult.Undefined); - } + var permissionNames = context.Permissions.Select(x => x.Name).ToArray(); var clientId = context.Principal?.FindFirst(AbpClaimTypes.ClientId)?.Value; if (clientId == null) { - return result; + return new MultiplePermissionGrantResult(permissionNames);; } - return await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, clientId); + return await PermissionStore.IsGrantedAsync(permissionNames, Name, clientId); } } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs index dd0aff0633..5fc2293e76 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs @@ -27,5 +27,17 @@ namespace Volo.Abp.Authorization.Permissions { Result = new Dictionary(); } + + public MultiplePermissionGrantResult(string[] names, PermissionGrantResult grantResult = PermissionGrantResult.Undefined) + { + Check.NotNull(names, nameof(names)); + + Result = new Dictionary(); + + foreach (var name in names) + { + Result.Add(name, grantResult); + } + } } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs index df2311d6b6..21b10b29b6 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs @@ -22,12 +22,7 @@ namespace Volo.Abp.Authorization.Permissions public Task IsGrantedAsync(string[] names, string providerName, string providerKey) { - var result = new MultiplePermissionGrantResult(); - foreach (var name in names) - { - result.Result.Add(name, PermissionGrantResult.Prohibited); - } - return Task.FromResult(result); + return Task.FromResult(new MultiplePermissionGrantResult(names, PermissionGrantResult.Prohibited)); } } } 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 49f5ba24e5..3f61df0b7e 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 @@ -88,12 +88,15 @@ namespace Volo.Abp.Authorization.Permissions { Check.NotNull(names, nameof(names)); - var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() - ?? CurrentTenant.GetMultiTenancySide(); + var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() ?? CurrentTenant.GetMultiTenancySide(); var result = new MultiplePermissionGrantResult(); + if (!names.Any()) + { + return result; + } - var definitions = new List(); + var permissionDefinitions = new List(); foreach (var name in names) { var permission = PermissionDefinitionManager.Get(name); @@ -104,22 +107,23 @@ namespace Volo.Abp.Authorization.Permissions } result.Result.Add(name, PermissionGrantResult.Undefined); - definitions.Add(permission); + permissionDefinitions.Add(permission); } foreach (var provider in PermissionValueProviderManager.ValueProviders) { - var context = new PermissionValuesCheckContext(definitions.Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)).ToList(), + var context = new PermissionValuesCheckContext(permissionDefinitions.Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)).ToList(), claimsPrincipal); - foreach (var grantResult in (await provider.CheckAsync(context)).Result) + var multipleResult = await provider.CheckAsync(context); + foreach (var grantResult in multipleResult.Result) { if (result.Result.ContainsKey(grantResult.Key) && result.Result[grantResult.Key] == PermissionGrantResult.Undefined && grantResult.Value != PermissionGrantResult.Undefined) { result.Result[grantResult.Key] = grantResult.Value; - definitions.Remove(definitions.First(x => x.Name == grantResult.Key)); + permissionDefinitions.RemoveAll(x => x.Name == grantResult.Key); } if (result.AllGranted || result.AllProhibited) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs index 5ae21a3ecc..e8187f762a 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs @@ -39,12 +39,8 @@ namespace Volo.Abp.Authorization.Permissions public async override Task CheckAsync(PermissionValuesCheckContext context) { - var result = new MultiplePermissionGrantResult(); var permissionNames = context.Permissions.Select(x => x.Name).ToList(); - foreach (var name in permissionNames) - { - result.Result.Add(name, PermissionGrantResult.Undefined); - } + var result = new MultiplePermissionGrantResult(permissionNames.ToArray()); var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray(); if (roles == null || !roles.Any()) @@ -54,18 +50,19 @@ namespace Volo.Abp.Authorization.Permissions foreach (var role in roles) { - foreach (var grantResult in (await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, role)).Result) + var multipleResult = await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, role); + foreach (var grantResult in multipleResult.Result) { if (result.Result.ContainsKey(grantResult.Key) && result.Result[grantResult.Key] == PermissionGrantResult.Undefined && grantResult.Value != PermissionGrantResult.Undefined) { result.Result[grantResult.Key] = grantResult.Value; - permissionNames.Remove(grantResult.Key); + permissionNames.RemoveAll(x => x == grantResult.Key); } } - if (result.AllGranted) + if (result.AllGranted || result.AllProhibited) { break; } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs index ae40285cee..fcdc25d1e1 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using Volo.Abp.Security.Claims; @@ -33,20 +32,15 @@ namespace Volo.Abp.Authorization.Permissions public async override Task CheckAsync(PermissionValuesCheckContext context) { - var result = new MultiplePermissionGrantResult(); - var permissionNames = context.Permissions.Select(x => x.Name).ToList(); - foreach (var name in permissionNames) - { - result.Result.Add(name, PermissionGrantResult.Undefined); - } + var permissionNames = context.Permissions.Select(x => x.Name).ToArray(); var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value; if (userId == null) { - return result; + return new MultiplePermissionGrantResult(permissionNames); } - return await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, userId); + return await PermissionStore.IsGrantedAsync(permissionNames, Name, userId); } } } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/FakePermissionStore.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/FakePermissionStore.cs index 6509d6dce2..fb4718e1c8 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/FakePermissionStore.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/FakePermissionStore.cs @@ -24,7 +24,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Authorization providerName == UserPermissionValueProvider.ProviderName && providerKey == AuthTestController.FakeUserId.ToString() ? PermissionGrantResult.Granted - : PermissionGrantResult.Undefined); + : PermissionGrantResult.Prohibited); } return Task.FromResult(result); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItem.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItem.cs index 47a7e1530c..c3d9aacecd 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItem.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItem.cs @@ -7,6 +7,8 @@ namespace Volo.Abp.PermissionManagement [Serializable] public class PermissionGrantCacheItem { + private const string CacheKeyFormat = "pn:{0},pk:{1},n:{2}"; + public bool IsGranted { get; set; } public PermissionGrantCacheItem() @@ -21,13 +23,12 @@ namespace Volo.Abp.PermissionManagement public static string CalculateCacheKey(string name, string providerName, string providerKey) { - return "pn:" + providerName + ",pk:" + providerKey + ",n:" + name; + return string.Format(CacheKeyFormat, providerName, providerKey, name); } - public static string ParseCacheKeyOrNull(string key) + public static string GetPermissionNameFormCacheKeyOrNull(string cacheKey) { - var format = "pn:{0},pk:{1},n:{2}"; - var result = FormattedStringValueExtracter.Extract(key, format, true); + var result = FormattedStringValueExtracter.Extract(cacheKey, CacheKeyFormat, true); return result.IsMatch ? result.Matches.Last().Value : null; } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs index b80c0b3fa1..9add7eb85b 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs @@ -35,21 +35,6 @@ namespace Volo.Abp.PermissionManagement return (await GetCacheItemAsync(name, providerName, providerKey)).IsGranted; } - public virtual async Task IsGrantedAsync(string[] names, string providerName, string providerKey) - { - var result = new MultiplePermissionGrantResult(); - - var cacheItems = await GetCacheItemsAsync(names, providerName, providerKey); - foreach (var item in cacheItems) - { - result.Result.Add(PermissionGrantCacheItem.ParseCacheKeyOrNull(item.Key), item.Value.IsGranted - ? PermissionGrantResult.Granted : - PermissionGrantResult.Undefined); - } - - return result; - } - protected virtual async Task GetCacheItemAsync( string name, string providerName, @@ -114,27 +99,75 @@ namespace Volo.Abp.PermissionManagement Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}"); } + public virtual async Task IsGrantedAsync(string[] names, string providerName, string providerKey) + { + Check.NotNullOrEmpty(names, nameof(names)); + + var result = new MultiplePermissionGrantResult(); + + if (names.Length == 1) + { + var name = names.First(); + result.Result.Add(name, + await IsGrantedAsync(names.First(), providerName, providerKey) + ? PermissionGrantResult.Granted + : PermissionGrantResult.Undefined); + return result; + } + + var cacheItems = await GetCacheItemsAsync(names, providerName, providerKey); + foreach (var item in cacheItems) + { + result.Result.Add(PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(item.Key), + item.Value.IsGranted + ? PermissionGrantResult.Granted + : PermissionGrantResult.Undefined); + } + + return result; + } + protected virtual async Task>> GetCacheItemsAsync( string[] names, string providerName, string providerKey) { var cacheKeys = names.Select(x => CalculateCacheKey(x, providerName, providerKey)).ToList(); + + Logger.LogDebug($"PermissionStore.GetCacheItemAsync: {string.Join(",", cacheKeys)}"); + var cacheItems = (await Cache.GetManyAsync(cacheKeys)).ToList(); if (cacheItems.All(x => x.Value != null)) { + Logger.LogDebug($"Found in the cache: {string.Join(",", cacheKeys)}"); return cacheItems; } - return cacheItems.Where(x => x.Value != null) - .Union(await SetCacheItemsAsync(providerName, providerKey, cacheItems.Where(x => x.Value == null))) - .ToList(); + var notCacheKeys = cacheItems.Where(x => x.Value == null).Select(x => x.Key).ToList(); + + Logger.LogDebug($"Not found in the cache: {string.Join(",", notCacheKeys)}"); + + var newCacheItems = await SetCacheItemsAsync(providerName, providerKey, notCacheKeys); + + var result = new List>(); + foreach (var key in cacheKeys) + { + var item = newCacheItems.FirstOrDefault(x => x.Key == key); + if (item.Value == null) + { + item = cacheItems.FirstOrDefault(x => x.Key == key); + } + + result.Add(new KeyValuePair(key, item.Value)); + } + + return result; } protected virtual async Task>> SetCacheItemsAsync( string providerName, string providerKey, - IEnumerable> notCacheItems) + IEnumerable cacheKeys) { var permissions = PermissionDefinitionManager.GetPermissions(); @@ -162,7 +195,7 @@ namespace Volo.Abp.PermissionManagement Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}"); - return cacheItems.Where(x => notCacheItems.Any(y => x.Key == y.Key)).ToList(); + return cacheItems.Where(x => cacheKeys.Contains(x.Key)).ToList(); } protected virtual string CalculateCacheKey(string name, string providerName, string providerKey) From fd7295ccd69313d58514bf84fceda1f0661ca1d8 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 9 Nov 2020 21:33:24 +0800 Subject: [PATCH 3/7] Add unit test for multiple IsGrantedAsync. --- .../Permissions/IPermissionChecker.cs | 3 +-- .../Abp/PermissionManagement/PermissionStore.cs | 2 +- .../PermissionGrantCacheItem_Tests.cs | 16 ++++++++++++++++ .../PermissionStore_Tests.cs | 16 +++++++++++++--- 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionGrantCacheItem_Tests.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs index 91987b408d..a172e8da95 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Security.Claims; +using System.Security.Claims; using System.Threading.Tasks; using JetBrains.Annotations; diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs index 9add7eb85b..dced272f01 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs @@ -119,7 +119,7 @@ namespace Volo.Abp.PermissionManagement foreach (var item in cacheItems) { result.Result.Add(PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(item.Key), - item.Value.IsGranted + item.Value != null && item.Value.IsGranted ? PermissionGrantResult.Granted : PermissionGrantResult.Undefined); } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionGrantCacheItem_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionGrantCacheItem_Tests.cs new file mode 100644 index 0000000000..d06c012cfa --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionGrantCacheItem_Tests.cs @@ -0,0 +1,16 @@ +using Shouldly; +using Xunit; + +namespace Volo.Abp.PermissionManagement +{ + public class PermissionGrantCacheItem_Tests + { + [Fact] + public void GetPermissionNameFormCacheKeyOrNull() + { + var key = PermissionGrantCacheItem.CalculateCacheKey("aaa", "bbb", "ccc"); + PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(key).ShouldBe("aaa"); + PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull("aaabbbccc").ShouldBeNull(); + } + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionStore_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionStore_Tests.cs index 965899ede9..ee0ef168c1 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionStore_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionStore_Tests.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Linq; using System.Threading.Tasks; using Shouldly; using Volo.Abp.Authorization.Permissions; @@ -28,7 +26,19 @@ namespace Volo.Abp.PermissionManagement (await _permissionStore.IsGrantedAsync("MyPermission1NotExist", UserPermissionValueProvider.ProviderName, PermissionTestDataBuilder.User1Id.ToString())).ShouldBeFalse(); + } + + [Fact] + public async Task IsGranted_Multiple() + { + var result = await _permissionStore.IsGrantedAsync(new[] {"MyPermission1", "MyPermission1NotExist"}, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()); + + result.Result.Count.ShouldBe(2); + result.Result.FirstOrDefault(x => x.Key == "MyPermission1").Value.ShouldBe(PermissionGrantResult.Granted); + result.Result.FirstOrDefault(x => x.Key == "MyPermission1NotExist").Value.ShouldBe(PermissionGrantResult.Undefined); } } } From 3af83c9368fca90ecf09670fbb5f1a76d6f79c33 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 10 Nov 2020 11:45:20 +0800 Subject: [PATCH 4/7] Make ISettingProvider support batch get. --- .../Mvc/Client/RemoteSettingProvider.cs | 8 +- .../AbpApplicationConfigurationAppService.cs | 13 ++- .../ConfigurationSettingValueProvider.cs | 11 ++- .../DefaultValueSettingValueProvider.cs | 13 ++- .../Settings/GlobalSettingValueProvider.cs | 13 ++- .../Volo/Abp/Settings/ISettingProvider.cs | 2 + .../Volo/Abp/Settings/ISettingStore.cs | 9 +- .../Abp/Settings/ISettingValueProvider.cs | 7 +- .../Volo/Abp/Settings/NullSettingStore.cs | 11 ++- .../Volo/Abp/Settings/SettingProvider.cs | 44 +++++++--- .../Volo/Abp/Settings/SettingValueProvider.cs | 7 +- .../Settings/TenantSettingValueProvider.cs | 9 +- .../Abp/Settings/UserSettingValueProvider.cs | 14 ++- .../Abp/Settings/TestSettingValueProvider.cs | 8 +- .../PermissionManagement/PermissionStore.cs | 8 +- .../ISettingManagementStore.cs | 6 +- .../Abp/SettingManagement/SettingCacheItem.cs | 12 ++- .../SettingManagementStore.cs | 87 +++++++++++++++++++ .../Abp/SettingManagement/SettingStore.cs | 8 +- .../SettingManagementStore_Tests.cs | 22 +++++ 20 files changed, 267 insertions(+), 45 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs index db3ea6e9a6..89db44b43d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs @@ -14,13 +14,19 @@ namespace Volo.Abp.AspNetCore.Mvc.Client { ConfigurationClient = configurationClient; } - + public async Task GetOrNullAsync(string name) { var configuration = await ConfigurationClient.GetAsync(); return configuration.Setting.Values.GetOrDefault(name); } + public async Task> GetAllAsync(string[] names) + { + var configuration = await ConfigurationClient.GetAsync(); + return names.Select(x => new SettingValue(x, configuration.Setting.Values.GetOrDefault(x))).ToList(); + } + public async Task> GetAllAsync() { var configuration = await ConfigurationClient.GetAsync(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs index e02132a84a..eab7d968a9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs @@ -251,14 +251,13 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations Values = new Dictionary() }; - foreach (var settingDefinition in _settingDefinitionManager.GetAll()) - { - if (!settingDefinition.IsVisibleToClients) - { - continue; - } + var settingDefinitions = _settingDefinitionManager.GetAll().Where(x => x.IsVisibleToClients); + + var settingValues = await _settingProvider.GetAllAsync(settingDefinitions.Select(x => x.Name).ToArray()); - result.Values[settingDefinition.Name] = await _settingProvider.GetOrNullAsync(settingDefinition.Name); + foreach (var settingValue in settingValues) + { + result.Values[settingValue.Name] = settingValue.Value; } return result; diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ConfigurationSettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ConfigurationSettingValueProvider.cs index 70f2a6c346..ec5fa91eac 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ConfigurationSettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ConfigurationSettingValueProvider.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Volo.Abp.DependencyInjection; @@ -23,5 +25,10 @@ namespace Volo.Abp.Settings { return Task.FromResult(Configuration[ConfigurationNamePrefix + setting.Name]); } + + public Task> GetAllAsync(SettingDefinition[] settings) + { + return Task.FromResult(settings.Select(x => new SettingValue(x.Name, Configuration[ConfigurationNamePrefix + x.Name])).ToList()); + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/DefaultValueSettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/DefaultValueSettingValueProvider.cs index 201e4f26c4..5575ed3f23 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/DefaultValueSettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/DefaultValueSettingValueProvider.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace Volo.Abp.Settings { @@ -8,7 +10,7 @@ namespace Volo.Abp.Settings public override string Name => ProviderName; - public DefaultValueSettingValueProvider(ISettingStore settingStore) + public DefaultValueSettingValueProvider(ISettingStore settingStore) : base(settingStore) { @@ -18,5 +20,10 @@ namespace Volo.Abp.Settings { return Task.FromResult(setting.DefaultValue); } + + public override Task> GetAllAsync(SettingDefinition[] settings) + { + return Task.FromResult(settings.Select(x => new SettingValue(x.Name, x.DefaultValue)).ToList()); + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/GlobalSettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/GlobalSettingValueProvider.cs index 1a69a4ba90..48ad3492ef 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/GlobalSettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/GlobalSettingValueProvider.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace Volo.Abp.Settings { @@ -8,7 +10,7 @@ namespace Volo.Abp.Settings public override string Name => ProviderName; - public GlobalSettingValueProvider(ISettingStore settingStore) + public GlobalSettingValueProvider(ISettingStore settingStore) : base(settingStore) { } @@ -17,5 +19,10 @@ namespace Volo.Abp.Settings { return SettingStore.GetOrNullAsync(setting.Name, Name, null); } + + public override Task> GetAllAsync(SettingDefinition[] settings) + { + return SettingStore.GetAllAsync(settings.Select(x => x.Name).ToArray(), Name, null); + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingProvider.cs index 608cf49105..3979c6be6b 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingProvider.cs @@ -8,6 +8,8 @@ namespace Volo.Abp.Settings { Task GetOrNullAsync([NotNull]string name); + Task> GetAllAsync([NotNull]string[] names); + Task> GetAllAsync(); } } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingStore.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingStore.cs index 69e6319a2f..2ad7055e96 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingStore.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingStore.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using JetBrains.Annotations; namespace Volo.Abp.Settings @@ -10,5 +11,11 @@ namespace Volo.Abp.Settings [CanBeNull] string providerName, [CanBeNull] string providerKey ); + + Task> GetAllAsync( + [NotNull] string[] names, + [CanBeNull] string providerName, + [CanBeNull] string providerKey + ); } } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingValueProvider.cs index ab63f47d17..1f64197373 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingValueProvider.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using JetBrains.Annotations; namespace Volo.Abp.Settings @@ -8,5 +9,7 @@ namespace Volo.Abp.Settings string Name { get; } Task GetOrNullAsync([NotNull] SettingDefinition setting); + + Task> GetAllAsync([NotNull] SettingDefinition[] settings); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/NullSettingStore.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/NullSettingStore.cs index 8699fae972..58fbf5627f 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/NullSettingStore.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/NullSettingStore.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.DependencyInjection; @@ -19,5 +21,10 @@ namespace Volo.Abp.Settings { return Task.FromResult((string) null); } + + public Task> GetAllAsync(string[] names, string providerName, string providerKey) + { + return Task.FromResult(names.Select(x => new SettingValue(x, null)).ToList()); + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs index 5ef67cbc21..f7cf9fbb1c 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs @@ -43,29 +43,45 @@ namespace Volo.Abp.Settings return value; } - public virtual async Task> GetAllAsync() + public async Task> GetAllAsync(string[] names) { - var settingValues = new Dictionary(); - var settingDefinitions = SettingDefinitionManager.GetAll(); + var result = new List(); + var settingDefinitions = SettingDefinitionManager.GetAll().Where(x => names.Contains(x.Name)).ToList(); - foreach (var provider in SettingValueProviderManager.Providers) + foreach (var provider in Enumerable.Reverse(SettingValueProviderManager.Providers)) { - foreach (var setting in settingDefinitions) + var settingValues = await provider.GetAllAsync(settingDefinitions.Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)).ToArray()); + + var notNullValues = settingValues.Where(x => x.Value != null).ToList(); + foreach (var settingValue in notNullValues) { - var value = await provider.GetOrNullAsync(setting); - if (value != null) + var value = settingValue; + var settingDefinition = settingDefinitions.First(x => x.Name == value.Name); + if (settingDefinition.IsEncrypted) { - if (setting.IsEncrypted) - { - value = SettingEncryptionService.Decrypt(setting, value); - } - - settingValues[setting.Name] = new SettingValue(setting.Name, value); + settingValue.Value = SettingEncryptionService.Decrypt(settingDefinition, settingValue.Value); } + + result.Add(new SettingValue(settingValue.Name, settingValue.Value)); } + + settingDefinitions.RemoveAll(x => notNullValues.Any(v => v.Name == x.Name)); + } + + return result; + } + + public virtual async Task> GetAllAsync() + { + var settingValues = new List(); + var settingDefinitions = SettingDefinitionManager.GetAll(); + + foreach (var setting in settingDefinitions) + { + settingValues.Add(new SettingValue(setting.Name, await GetOrNullAsync(setting.Name))); } - return settingValues.Values.ToList(); + return settingValues; } protected virtual async Task GetOrNullValueFromProvidersAsync( diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProvider.cs index 91be8549ab..a286d8dba8 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValueProvider.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings @@ -15,5 +16,7 @@ namespace Volo.Abp.Settings } public abstract Task GetOrNullAsync(SettingDefinition setting); + + public abstract Task> GetAllAsync(SettingDefinition[] settings); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/TenantSettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/TenantSettingValueProvider.cs index 4fa876ae80..6286356a04 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/TenantSettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/TenantSettingValueProvider.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.MultiTenancy; namespace Volo.Abp.Settings @@ -21,5 +23,10 @@ namespace Volo.Abp.Settings { return await SettingStore.GetOrNullAsync(setting.Name, Name, CurrentTenant.Id?.ToString()); } + + public async override Task> GetAllAsync(SettingDefinition[] settings) + { + return await SettingStore.GetAllAsync(settings.Select(x => x.Name).ToArray(), Name, CurrentTenant.Id?.ToString()); + } } } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/UserSettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/UserSettingValueProvider.cs index 0781b10433..8c337bbee4 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/UserSettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/UserSettingValueProvider.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.Users; namespace Volo.Abp.Settings @@ -26,5 +28,15 @@ namespace Volo.Abp.Settings return await SettingStore.GetOrNullAsync(setting.Name, Name, CurrentUser.Id.ToString()); } + + public async override Task> GetAllAsync(SettingDefinition[] settings) + { + if (CurrentUser.Id == null) + { + return settings.Select(x => new SettingValue(x.Name, null)).ToList(); + } + + return await SettingStore.GetAllAsync(settings.Select(x => x.Name).ToArray(), Name, CurrentUser.Id.ToString()); + } } } diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs index 2dbe1e5729..fbc2967d3b 100644 --- a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -12,7 +13,7 @@ namespace Volo.Abp.Settings public string Name => ProviderName; - public TestSettingValueProvider() + public TestSettingValueProvider() { _values = new Dictionary(); } @@ -21,5 +22,10 @@ namespace Volo.Abp.Settings { return Task.FromResult(_values.GetOrDefault(setting.Name)); } + + public Task> GetAllAsync(SettingDefinition[] settings) + { + return Task.FromResult(settings.Select(x => new SettingValue(x.Name, _values.GetOrDefault(x.Name))).ToList()); + } } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs index dced272f01..f95b7e2afa 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs @@ -118,7 +118,7 @@ namespace Volo.Abp.PermissionManagement var cacheItems = await GetCacheItemsAsync(names, providerName, providerKey); foreach (var item in cacheItems) { - result.Result.Add(PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(item.Key), + result.Result.Add(GetPermissionNameFormCacheKeyOrNull(item.Key), item.Value != null && item.Value.IsGranted ? PermissionGrantResult.Granted : PermissionGrantResult.Undefined); @@ -202,5 +202,11 @@ namespace Volo.Abp.PermissionManagement { return PermissionGrantCacheItem.CalculateCacheKey(name, providerName, providerKey); } + + protected virtual string GetPermissionNameFormCacheKeyOrNull(string key) + { + //TODO: throw ex when name is null? + return PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(key); + } } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingManagementStore.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingManagementStore.cs index eebdc69357..3c979039bb 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingManagementStore.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingManagementStore.cs @@ -10,8 +10,10 @@ namespace Volo.Abp.SettingManagement Task> GetListAsync(string providerName, string providerKey); + Task> GetListAsync(string[] names, string providerName, string providerKey); + Task SetAsync(string name, string value, string providerName, string providerKey); - + Task DeleteAsync(string name, string providerName, string providerKey); } -} \ No newline at end of file +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingCacheItem.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingCacheItem.cs index 3511df204d..88b1eebbb9 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingCacheItem.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingCacheItem.cs @@ -1,5 +1,7 @@ using System; +using System.Linq; using Volo.Abp.MultiTenancy; +using Volo.Abp.Text.Formatting; namespace Volo.Abp.SettingManagement { @@ -7,6 +9,8 @@ namespace Volo.Abp.SettingManagement [IgnoreMultiTenancy] public class SettingCacheItem { + private const string CacheKeyFormat = "pn:{0},pk:{1},n:{2}"; + public string Value { get; set; } public SettingCacheItem() @@ -21,7 +25,13 @@ namespace Volo.Abp.SettingManagement public static string CalculateCacheKey(string name, string providerName, string providerKey) { - return "pn:" + providerName + ",pk:" + providerKey + ",n:" + name; + return string.Format(CacheKeyFormat, providerName, providerKey, name); + } + + public static string GetSettingNameFormCacheKey(string cacheKey) + { + var result = FormattedStringValueExtracter.Extract(cacheKey, CacheKeyFormat, true); + return result.IsMatch ? result.Matches.Last().Value : cacheKey; } } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs index a568184f0e..0dd33f0ffd 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs @@ -118,9 +118,96 @@ namespace Volo.Abp.SettingManagement await Cache.SetManyAsync(cacheItems, considerUow: true); } + [UnitOfWork] + public async Task> GetListAsync(string[] names, string providerName, string providerKey) + { + Check.NotNullOrEmpty(names, nameof(names)); + + var result = new List(); + + if (names.Length == 1) + { + var name = names.First(); + result.Add(new SettingValue(name, (await GetCacheItemAsync(name, providerName, providerKey)).Value)); + return result; + } + + var cacheItems = await GetCacheItemsAsync(names, providerName, providerKey); + foreach (var item in cacheItems) + { + result.Add(new SettingValue(GetSettingNameFormCacheKeyOrNull(item.Key), item.Value?.Value)); + } + + return result; + } + + protected virtual async Task>> GetCacheItemsAsync(string[] names, string providerName, string providerKey) + { + var cacheKeys = names.Select(x => CalculateCacheKey(x, providerName, providerKey)).ToList(); + + var cacheItems = (await Cache.GetManyAsync(cacheKeys, considerUow: true)).ToList(); + + if (cacheItems.All(x => x.Value != null)) + { + return cacheItems; + } + + var notCacheKeys = cacheItems.Where(x => x.Value == null).Select(x => x.Key).ToList(); + + var newCacheItems = await SetCacheItemsAsync(providerName, providerKey, notCacheKeys); + + var result = new List>(); + foreach (var key in cacheKeys) + { + var item = newCacheItems.FirstOrDefault(x => x.Key == key); + if (item.Value == null) + { + item = cacheItems.FirstOrDefault(x => x.Key == key); + } + + result.Add(new KeyValuePair(key, item.Value)); + } + + return result; + } + + private async Task>> SetCacheItemsAsync( + string providerName, + string providerKey, + IEnumerable cacheKeys) + { + var settingDefinitions = SettingDefinitionManager.GetAll(); + var settingsDictionary = (await SettingRepository.GetListAsync(providerName, providerKey)) + .ToDictionary(s => s.Name, s => s.Value); + + var cacheItems = new List>(); + + foreach (var settingDefinition in settingDefinitions) + { + var settingValue = settingsDictionary.GetOrDefault(settingDefinition.Name); + cacheItems.Add( + new KeyValuePair( + CalculateCacheKey(settingDefinition.Name, providerName, providerKey), + new SettingCacheItem(settingValue) + ) + ); + } + + await Cache.SetManyAsync(cacheItems, considerUow: true); + + return cacheItems.Where(x => cacheKeys.Contains(x.Key)).ToList(); + } + + protected virtual string CalculateCacheKey(string name, string providerName, string providerKey) { return SettingCacheItem.CalculateCacheKey(name, providerName, providerKey); } + + protected virtual string GetSettingNameFormCacheKeyOrNull(string key) + { + //TODO: throw ex when name is null? + return SettingCacheItem.GetSettingNameFormCacheKey(key); + } } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingStore.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingStore.cs index c38f915bf5..ab6bb185ca 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingStore.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingStore.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Settings; @@ -17,5 +18,10 @@ namespace Volo.Abp.SettingManagement { return ManagementStore.GetOrNullAsync(name, providerName, providerKey); } + + public virtual Task> GetAllAsync(string[] names, string providerName, string providerKey) + { + return ManagementStore.GetListAsync(names, providerName, providerKey); + } } } diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManagementStore_Tests.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManagementStore_Tests.cs index 7a405faf2d..1ccadef252 100644 --- a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManagementStore_Tests.cs +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingManagementStore_Tests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using System.Threading.Tasks; using Shouldly; @@ -94,5 +95,26 @@ namespace Volo.Abp.SettingManagement } } + [Fact] + public async Task GetListAsync() + { + var result = await _settingManagementStore.GetListAsync( + new[] + { + "MySetting1", + "MySetting2", + "MySetting3", + "notExistName" + }, + GlobalSettingValueProvider.ProviderName, + null); + + result.Count.ShouldBe(4); + + result.First(x => x.Name == "MySetting1").Value.ShouldBe("42"); + result.First(x => x.Name == "MySetting2").Value.ShouldBe("default-store-value"); + result.First(x => x.Name == "MySetting3").Value.ShouldBe(null); + result.First(x => x.Name == "notExistName").Value.ShouldBe(null); + } } } From d986cc6509f91d6eaf0371610df9eeeb8fbdf5f3 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 10 Nov 2020 14:02:26 +0800 Subject: [PATCH 5/7] Refactor. --- .../Permissions/PermissionChecker.cs | 38 +++++++++---------- .../RolePermissionValueProvider.cs | 14 +++---- .../Volo/Abp/Settings/SettingProvider.cs | 3 +- .../Abp/SettingManagement/SettingCacheItem.cs | 4 +- .../SettingManagementStore.cs | 2 +- .../SettingCacheItem_Tests.cs | 16 ++++++++ 6 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingCacheItem_Tests.cs 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 3f61df0b7e..bfdcf5fd66 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 @@ -100,36 +100,34 @@ namespace Volo.Abp.Authorization.Permissions foreach (var name in names) { var permission = PermissionDefinitionManager.Get(name); - if (!permission.IsEnabled || !permission.MultiTenancySide.HasFlag(multiTenancySide)) - { - result.Result.Add(name, PermissionGrantResult.Undefined); - continue; - } result.Result.Add(name, PermissionGrantResult.Undefined); - permissionDefinitions.Add(permission); + + if (permission.IsEnabled && permission.MultiTenancySide.HasFlag(multiTenancySide)) + { + permissionDefinitions.Add(permission); + } } foreach (var provider in PermissionValueProviderManager.ValueProviders) { - var context = new PermissionValuesCheckContext(permissionDefinitions.Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)).ToList(), + var context = new PermissionValuesCheckContext( + permissionDefinitions.Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)).ToList(), claimsPrincipal); var multipleResult = await provider.CheckAsync(context); - foreach (var grantResult in multipleResult.Result) + foreach (var grantResult in multipleResult.Result.Where(grantResult => + result.Result.ContainsKey(grantResult.Key) && + result.Result[grantResult.Key] == PermissionGrantResult.Undefined && + grantResult.Value != PermissionGrantResult.Undefined)) + { + result.Result[grantResult.Key] = grantResult.Value; + permissionDefinitions.RemoveAll(x => x.Name == grantResult.Key); + } + + if (result.AllGranted || result.AllProhibited) { - if (result.Result.ContainsKey(grantResult.Key) && - result.Result[grantResult.Key] == PermissionGrantResult.Undefined && - grantResult.Value != PermissionGrantResult.Undefined) - { - result.Result[grantResult.Key] = grantResult.Value; - permissionDefinitions.RemoveAll(x => x.Name == grantResult.Key); - } - - if (result.AllGranted || result.AllProhibited) - { - break; - } + break; } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs index e8187f762a..e3ab7629a2 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs @@ -51,15 +51,13 @@ namespace Volo.Abp.Authorization.Permissions foreach (var role in roles) { var multipleResult = await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, role); - foreach (var grantResult in multipleResult.Result) + foreach (var grantResult in multipleResult.Result.Where(grantResult => + result.Result.ContainsKey(grantResult.Key) && + result.Result[grantResult.Key] == PermissionGrantResult.Undefined && + grantResult.Value != PermissionGrantResult.Undefined)) { - if (result.Result.ContainsKey(grantResult.Key) && - result.Result[grantResult.Key] == PermissionGrantResult.Undefined && - grantResult.Value != PermissionGrantResult.Undefined) - { - result.Result[grantResult.Key] = grantResult.Value; - permissionNames.RemoveAll(x => x == grantResult.Key); - } + result.Result[grantResult.Key] = grantResult.Value; + permissionNames.RemoveAll(x => x == grantResult.Key); } if (result.AllGranted || result.AllProhibited) diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs index f7cf9fbb1c..d9ebb4e757 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs @@ -55,8 +55,7 @@ namespace Volo.Abp.Settings var notNullValues = settingValues.Where(x => x.Value != null).ToList(); foreach (var settingValue in notNullValues) { - var value = settingValue; - var settingDefinition = settingDefinitions.First(x => x.Name == value.Name); + var settingDefinition = settingDefinitions.First(x => x.Name == settingValue.Name); if (settingDefinition.IsEncrypted) { settingValue.Value = SettingEncryptionService.Decrypt(settingDefinition, settingValue.Value); diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingCacheItem.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingCacheItem.cs index 88b1eebbb9..3b6b968e19 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingCacheItem.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingCacheItem.cs @@ -28,10 +28,10 @@ namespace Volo.Abp.SettingManagement return string.Format(CacheKeyFormat, providerName, providerKey, name); } - public static string GetSettingNameFormCacheKey(string cacheKey) + public static string GetSettingNameFormCacheKeyOrNull(string cacheKey) { var result = FormattedStringValueExtracter.Extract(cacheKey, CacheKeyFormat, true); - return result.IsMatch ? result.Matches.Last().Value : cacheKey; + return result.IsMatch ? result.Matches.Last().Value : null; } } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs index 0dd33f0ffd..baad579594 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs @@ -207,7 +207,7 @@ namespace Volo.Abp.SettingManagement protected virtual string GetSettingNameFormCacheKeyOrNull(string key) { //TODO: throw ex when name is null? - return SettingCacheItem.GetSettingNameFormCacheKey(key); + return SettingCacheItem.GetSettingNameFormCacheKeyOrNull(key); } } } diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingCacheItem_Tests.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingCacheItem_Tests.cs new file mode 100644 index 0000000000..390851e08e --- /dev/null +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/SettingCacheItem_Tests.cs @@ -0,0 +1,16 @@ +using Shouldly; +using Xunit; + +namespace Volo.Abp.SettingManagement +{ + public class SettingCacheItem_Tests + { + [Fact] + public void GetSettingNameFormCacheKeyOrNull() + { + var key = SettingCacheItem.CalculateCacheKey("aaa", "bbb", "ccc"); + SettingCacheItem.GetSettingNameFormCacheKeyOrNull(key).ShouldBe("aaa"); + SettingCacheItem.GetSettingNameFormCacheKeyOrNull("aaabbbccc").ShouldBeNull(); + } + } +} From 7850db33bcf18e9a9bf27a347c93d015a7f01c0b Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 11 Nov 2020 13:43:19 +0800 Subject: [PATCH 6/7] Add GetListAsync repository method. --- .../Volo/Abp/Settings/SettingProvider.cs | 14 +++++++++--- .../IPermissionGrantRepository.cs | 9 +++++++- .../PermissionManagement/PermissionStore.cs | 10 ++++----- .../EfCorePermissionGrantRepository.cs | 17 +++++++++++--- .../MongoDb/MongoPermissionGrantRepository.cs | 22 ++++++++++++++----- .../PermissionGrantRepository_Tests.cs | 9 ++++++++ .../SettingManagement/ISettingRepository.cs | 4 +++- .../SettingManagementStore.cs | 9 ++++---- .../EfCoreSettingRepository.cs | 8 +++++++ .../MongoDB/MongoSettingRepository.cs | 8 ++++++- .../SettingRepository_Tests.cs | 9 ++++++++ 11 files changed, 96 insertions(+), 23 deletions(-) diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs index d9ebb4e757..52ef5c50de 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs @@ -45,9 +45,14 @@ namespace Volo.Abp.Settings public async Task> GetAllAsync(string[] names) { - var result = new List(); + var result = new Dictionary(); var settingDefinitions = SettingDefinitionManager.GetAll().Where(x => names.Contains(x.Name)).ToList(); + foreach (var definition in settingDefinitions) + { + result.Add(definition.Name, new SettingValue(definition.Name, null)); + } + foreach (var provider in Enumerable.Reverse(SettingValueProviderManager.Providers)) { var settingValues = await provider.GetAllAsync(settingDefinitions.Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)).ToArray()); @@ -61,13 +66,16 @@ namespace Volo.Abp.Settings settingValue.Value = SettingEncryptionService.Decrypt(settingDefinition, settingValue.Value); } - result.Add(new SettingValue(settingValue.Name, settingValue.Value)); + if (result.ContainsKey(settingValue.Name) && result[settingValue.Name].Value == null) + { + result[settingValue.Name].Value = settingValue.Value; + } } settingDefinitions.RemoveAll(x => notNullValues.Any(v => v.Name == x.Name)); } - return result; + return result.Values.ToList(); } public virtual async Task> GetAllAsync() diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionGrantRepository.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionGrantRepository.cs index 8c0beffd1a..7807cb4676 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionGrantRepository.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionGrantRepository.cs @@ -20,5 +20,12 @@ namespace Volo.Abp.PermissionManagement string providerKey, CancellationToken cancellationToken = default ); + + Task> GetListAsync( + string[] names, + string providerName, + string providerKey, + CancellationToken cancellationToken = default + ); } -} \ No newline at end of file +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs index f95b7e2afa..343e5f230d 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs @@ -167,14 +167,14 @@ namespace Volo.Abp.PermissionManagement protected virtual async Task>> SetCacheItemsAsync( string providerName, string providerKey, - IEnumerable cacheKeys) + List notCacheKeys) { - var permissions = PermissionDefinitionManager.GetPermissions(); + var permissions = PermissionDefinitionManager.GetPermissions().Where(x => notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name)).ToList(); - Logger.LogDebug($"Getting all granted permissions from the repository for this provider name,key: {providerName},{providerKey}"); + Logger.LogDebug($"Getting not cache granted permissions from the repository for this provider name,key: {providerName},{providerKey}"); var grantedPermissionsHashSet = new HashSet( - (await PermissionGrantRepository.GetListAsync(providerName, providerKey)).Select(p => p.Name) + (await PermissionGrantRepository.GetListAsync(notCacheKeys.Select(GetPermissionNameFormCacheKeyOrNull).ToArray(), providerName, providerKey)).Select(p => p.Name) ); Logger.LogDebug($"Setting the cache items. Count: {permissions.Count}"); @@ -195,7 +195,7 @@ namespace Volo.Abp.PermissionManagement Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}"); - return cacheItems.Where(x => cacheKeys.Contains(x.Key)).ToList(); + return cacheItems; } protected virtual string CalculateCacheKey(string name, string providerName, string providerKey) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCorePermissionGrantRepository.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCorePermissionGrantRepository.cs index f3536605a2..1adb400307 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCorePermissionGrantRepository.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCorePermissionGrantRepository.cs @@ -9,7 +9,7 @@ using Volo.Abp.EntityFrameworkCore; namespace Volo.Abp.PermissionManagement.EntityFrameworkCore { - public class EfCorePermissionGrantRepository : EfCoreRepository, + public class EfCorePermissionGrantRepository : EfCoreRepository, IPermissionGrantRepository { public EfCorePermissionGrantRepository(IDbContextProvider dbContextProvider) @@ -19,8 +19,8 @@ namespace Volo.Abp.PermissionManagement.EntityFrameworkCore } public virtual async Task FindAsync( - string name, - string providerName, + string name, + string providerName, string providerKey, CancellationToken cancellationToken = default) { @@ -44,5 +44,16 @@ namespace Volo.Abp.PermissionManagement.EntityFrameworkCore s.ProviderKey == providerKey ).ToListAsync(GetCancellationToken(cancellationToken)); } + + public virtual async Task> GetListAsync(string[] names, string providerName, string providerKey, + CancellationToken cancellationToken = default) + { + return await DbSet + .Where(s => + names.Contains(s.Name) && + s.ProviderName == providerName && + s.ProviderKey == providerKey + ).ToListAsync(GetCancellationToken(cancellationToken)); + } } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/MongoPermissionGrantRepository.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/MongoPermissionGrantRepository.cs index e51d9ecf7c..4e641f6016 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/MongoPermissionGrantRepository.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/MongoPermissionGrantRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver; @@ -11,15 +12,15 @@ namespace Volo.Abp.PermissionManagement.MongoDB { public class MongoPermissionGrantRepository : MongoDbRepository, IPermissionGrantRepository { - public MongoPermissionGrantRepository(IMongoDbContextProvider dbContextProvider) + public MongoPermissionGrantRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) { } public virtual async Task FindAsync( - string name, - string providerName, + string name, + string providerName, string providerKey, CancellationToken cancellationToken = default) { @@ -33,7 +34,7 @@ namespace Volo.Abp.PermissionManagement.MongoDB } public virtual async Task> GetListAsync( - string providerName, + string providerName, string providerKey, CancellationToken cancellationToken = default) { @@ -43,5 +44,16 @@ namespace Volo.Abp.PermissionManagement.MongoDB s.ProviderKey == providerKey ).ToListAsync(GetCancellationToken(cancellationToken)); } + + public virtual async Task> GetListAsync(string[] names, string providerName, string providerKey, + CancellationToken cancellationToken = default) + { + return await GetMongoQueryable() + .Where(s => + names.Contains(s.Name) && + s.ProviderName == providerName && + s.ProviderKey == providerKey + ).ToListAsync(GetCancellationToken(cancellationToken)); + } } -} \ No newline at end of file +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionGrantRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionGrantRepository_Tests.cs index e27be7e426..6aca51987d 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionGrantRepository_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionGrantRepository_Tests.cs @@ -32,5 +32,14 @@ namespace Volo.Abp.PermissionManagement permissionGrants.ShouldContain(p => p.Name == "MyPermission1"); } + + [Fact] + public async Task GetList_With_Names() + { + var permissionGrants = await PermissionGrantRepository.GetListAsync(new []{"MyPermission1", "MyPermission3"},UserPermissionValueProvider.ProviderName, PermissionTestDataBuilder.User1Id.ToString()); + + permissionGrants.ShouldContain(p => p.Name == "MyPermission1"); + permissionGrants.ShouldContain(p => p.Name == "MyPermission3"); + } } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingRepository.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingRepository.cs index 6eeffae426..a1e40f3a14 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingRepository.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingRepository.cs @@ -10,5 +10,7 @@ namespace Volo.Abp.SettingManagement Task FindAsync(string name, string providerName, string providerKey); Task> GetListAsync(string providerName, string providerKey); + + Task> GetListAsync(string[] names, string providerName, string providerKey); } -} \ No newline at end of file +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs index baad579594..536bbaa532 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs @@ -174,10 +174,11 @@ namespace Volo.Abp.SettingManagement private async Task>> SetCacheItemsAsync( string providerName, string providerKey, - IEnumerable cacheKeys) + List notCacheKeys) { - var settingDefinitions = SettingDefinitionManager.GetAll(); - var settingsDictionary = (await SettingRepository.GetListAsync(providerName, providerKey)) + var settingDefinitions = SettingDefinitionManager.GetAll().Where(x => notCacheKeys.Any(k => GetSettingNameFormCacheKeyOrNull(k) == x.Name)); + + var settingsDictionary = (await SettingRepository.GetListAsync(notCacheKeys.Select(GetSettingNameFormCacheKeyOrNull).ToArray(), providerName, providerKey)) .ToDictionary(s => s.Name, s => s.Value); var cacheItems = new List>(); @@ -195,7 +196,7 @@ namespace Volo.Abp.SettingManagement await Cache.SetManyAsync(cacheItems, considerUow: true); - return cacheItems.Where(x => cacheKeys.Contains(x.Key)).ToList(); + return cacheItems; } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/EfCoreSettingRepository.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/EfCoreSettingRepository.cs index 66fe5e2eff..12999e5e1c 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/EfCoreSettingRepository.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/EfCoreSettingRepository.cs @@ -30,5 +30,13 @@ namespace Volo.Abp.SettingManagement.EntityFrameworkCore s => s.ProviderName == providerName && s.ProviderKey == providerKey ).ToListAsync(); } + + public virtual async Task> GetListAsync(string[] names, string providerName, string providerKey) + { + return await DbSet + .Where( + s => names.Contains(s.Name) && s.ProviderName == providerName && s.ProviderKey == providerKey + ).ToListAsync(); + } } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/MongoSettingRepository.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/MongoSettingRepository.cs index 8ad74b914a..845e9b3a7b 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/MongoSettingRepository.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/MongoSettingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using MongoDB.Driver; using MongoDB.Driver.Linq; @@ -25,5 +26,10 @@ namespace Volo.Abp.SettingManagement.MongoDB { return await GetMongoQueryable().Where(s => s.ProviderName == providerName && s.ProviderKey == providerKey).ToListAsync(); } + + public virtual async Task> GetListAsync(string[] names, string providerName, string providerKey) + { + return await GetMongoQueryable().Where(s => names.Contains(s.Name) && s.ProviderName == providerName && s.ProviderKey == providerKey).ToListAsync(); + } } -} \ No newline at end of file +} diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.TestBase/Volo/Abp/SettingManagement/SettingRepository_Tests.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.TestBase/Volo/Abp/SettingManagement/SettingRepository_Tests.cs index 5dad99a0ca..1d448f3154 100644 --- a/modules/setting-management/test/Volo.Abp.SettingManagement.TestBase/Volo/Abp/SettingManagement/SettingRepository_Tests.cs +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.TestBase/Volo/Abp/SettingManagement/SettingRepository_Tests.cs @@ -49,5 +49,14 @@ namespace Volo.Abp.SettingManagement settings.ShouldContain(s => s.Name == "MySetting1" && s.Value == "42"); settings.ShouldContain(s => s.Name == "MySetting2" && s.Value == "default-store-value"); } + + [Fact] + public async Task GetList_With_Names() + { + var settings = await SettingRepository.GetListAsync(new []{"MySetting1", "MySetting2"} ,GlobalSettingValueProvider.ProviderName, null); + settings.Any().ShouldBeTrue(); + settings.ShouldContain(s => s.Name == "MySetting1" && s.Value == "42"); + settings.ShouldContain(s => s.Name == "MySetting2" && s.Value == "default-store-value"); + } } } From 9dd0e22504ba57acf85e2aa0988a12e9e7090288 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 11 Nov 2020 15:59:56 +0800 Subject: [PATCH 7/7] Switch to host side in multiple check method. --- .../Permissions/ClientPermissionValueProvider.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs index 7422046263..ac76733524 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs @@ -46,7 +46,10 @@ namespace Volo.Abp.Authorization.Permissions return new MultiplePermissionGrantResult(permissionNames);; } - return await PermissionStore.IsGrantedAsync(permissionNames, Name, clientId); + using (CurrentTenant.Change(null)) + { + return await PermissionStore.IsGrantedAsync(permissionNames, Name, clientId); + } } } }