Merge pull request #6119 from abpframework/maliming/batch

Make permissions and settings support batch check/get.
pull/6153/head
Halil İbrahim Kalkan 5 years ago committed by GitHub
commit 71c4f94ff2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,4 @@
using System.Security.Claims;
using System.Security.Claims;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
@ -26,5 +26,25 @@ namespace Volo.Abp.AspNetCore.Mvc.Client
/* This provider always works for the current principal. */
return await IsGrantedAsync(name);
}
public async Task<MultiplePermissionGrantResult> 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<MultiplePermissionGrantResult> IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string[] names)
{
/* This provider always works for the current principal. */
return await IsGrantedAsync(names);
}
}
}

@ -14,13 +14,19 @@ namespace Volo.Abp.AspNetCore.Mvc.Client
{
ConfigurationClient = configurationClient;
}
public async Task<string> GetOrNullAsync(string name)
{
var configuration = await ConfigurationClient.GetAsync();
return configuration.Setting.Values.GetOrDefault(name);
}
public async Task<List<SettingValue>> GetAllAsync(string[] names)
{
var configuration = await ConfigurationClient.GetAsync();
return names.Select(x => new SettingValue(x, configuration.Setting.Values.GetOrDefault(x))).ToList();
}
public async Task<List<SettingValue>> GetAllAsync()
{
var configuration = await ConfigurationClient.GetAsync();

@ -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<AbpMultiTenancyOptions> 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<string>();
var otherPolicyNames = new List<string>();
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;
}
@ -216,14 +251,13 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
Values = new Dictionary<string, string>()
};
foreach (var settingDefinition in _settingDefinitionManager.GetAll())
{
if (!settingDefinition.IsVisibleToClients)
{
continue;
}
var settingDefinitions = _settingDefinitionManager.GetAll().Where(x => x.IsVisibleToClients);
result.Values[settingDefinition.Name] = await _settingProvider.GetOrNullAsync(settingDefinition.Name);
var settingValues = await _settingProvider.GetAllAsync(settingDefinitions.Select(x => x.Name).ToArray());
foreach (var settingValue in settingValues)
{
result.Values[settingValue.Name] = settingValue.Value;
}
return result;

@ -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<IAuthorizationHandler, PermissionRequirementHandler>();
context.Services.TryAddTransient<DefaultAuthorizationPolicyProvider>();
Configure<AbpPermissionOptions>(options =>
{
options.ValueProviders.Add<UserPermissionValueProvider>();

@ -6,7 +6,7 @@ namespace Volo.Abp.Authorization.Permissions
{
/// <summary>
/// Always allows for any permission.
///
///
/// Use IServiceCollection.AddAlwaysAllowAuthorization() to replace
/// IPermissionChecker with this class. This is useful for tests.
/// </summary>
@ -21,5 +21,15 @@ namespace Volo.Abp.Authorization.Permissions
{
return TaskCache.TrueResult;
}
public Task<MultiplePermissionGrantResult> IsGrantedAsync(string[] names)
{
return IsGrantedAsync(null, names);
}
public Task<MultiplePermissionGrantResult> IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string[] names)
{
return Task.FromResult(new MultiplePermissionGrantResult(names, PermissionGrantResult.Granted));
}
}
}

@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Volo.Abp.MultiTenancy;
using System.Linq;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Authorization.Permissions
@ -34,5 +35,21 @@ namespace Volo.Abp.Authorization.Permissions
: PermissionGrantResult.Undefined;
}
}
public async override Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context)
{
var permissionNames = context.Permissions.Select(x => x.Name).ToArray();
var clientId = context.Principal?.FindFirst(AbpClaimTypes.ClientId)?.Value;
if (clientId == null)
{
return new MultiplePermissionGrantResult(permissionNames);;
}
using (CurrentTenant.Change(null))
{
return await PermissionStore.IsGrantedAsync(permissionNames, Name, clientId);
}
}
}
}

@ -9,5 +9,9 @@ namespace Volo.Abp.Authorization.Permissions
Task<bool> IsGrantedAsync([NotNull]string name);
Task<bool> IsGrantedAsync([CanBeNull] ClaimsPrincipal claimsPrincipal, [NotNull]string name);
Task<MultiplePermissionGrantResult> IsGrantedAsync([NotNull]string[] names);
Task<MultiplePermissionGrantResult> IsGrantedAsync([CanBeNull] ClaimsPrincipal claimsPrincipal, [NotNull]string[] names);
}
}
}

@ -10,5 +10,11 @@ namespace Volo.Abp.Authorization.Permissions
[CanBeNull] string providerName,
[CanBeNull] string providerKey
);
Task<MultiplePermissionGrantResult> IsGrantedAsync(
[NotNull] string[] names,
[CanBeNull] string providerName,
[CanBeNull] string providerKey
);
}
}

@ -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<PermissionGrantResult> CheckAsync(PermissionValueCheckContext context);
Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context);
}
}
}

@ -0,0 +1,43 @@
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<string, PermissionGrantResult> Result { get; }
public MultiplePermissionGrantResult()
{
Result = new Dictionary<string, PermissionGrantResult>();
}
public MultiplePermissionGrantResult(string[] names, PermissionGrantResult grantResult = PermissionGrantResult.Undefined)
{
Check.NotNull(names, nameof(names));
Result = new Dictionary<string, PermissionGrantResult>();
foreach (var name in names)
{
Result.Add(name, grantResult);
}
}
}
}

@ -19,5 +19,10 @@ namespace Volo.Abp.Authorization.Permissions
{
return TaskCache.FalseResult;
}
public Task<MultiplePermissionGrantResult> IsGrantedAsync(string[] names, string providerName, string providerKey)
{
return Task.FromResult(new MultiplePermissionGrantResult(names, PermissionGrantResult.Prohibited));
}
}
}
}

@ -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<bool> IsGrantedAsync(
ClaimsPrincipal claimsPrincipal,
ClaimsPrincipal claimsPrincipal,
string name)
{
Check.NotNull(name, nameof(name));
@ -77,5 +78,60 @@ namespace Volo.Abp.Authorization.Permissions
return isGranted;
}
public async Task<MultiplePermissionGrantResult> IsGrantedAsync(string[] names)
{
return await IsGrantedAsync(PrincipalAccessor.Principal, names);
}
public async Task<MultiplePermissionGrantResult> IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string[] names)
{
Check.NotNull(names, nameof(names));
var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() ?? CurrentTenant.GetMultiTenancySide();
var result = new MultiplePermissionGrantResult();
if (!names.Any())
{
return result;
}
var permissionDefinitions = new List<PermissionDefinition>();
foreach (var name in names)
{
var permission = PermissionDefinitionManager.Get(name);
result.Result.Add(name, PermissionGrantResult.Undefined);
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(),
claimsPrincipal);
var multipleResult = await provider.CheckAsync(context);
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)
{
break;
}
}
return result;
}
}
}
}

@ -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<PermissionGrantResult> CheckAsync(PermissionValueCheckContext context);
public abstract Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context);
}
}
}

@ -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<PermissionDefinition> Permissions { get; }
[CanBeNull]
public ClaimsPrincipal Principal { get; }
public PermissionValuesCheckContext(
[NotNull] List<PermissionDefinition> permissions,
[CanBeNull] ClaimsPrincipal principal)
{
Check.NotNull(permissions, nameof(permissions));
Permissions = permissions;
Principal = principal;
}
}
}

@ -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,37 @@ namespace Volo.Abp.Authorization.Permissions
return PermissionGrantResult.Undefined;
}
public async override Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context)
{
var permissionNames = context.Permissions.Select(x => x.Name).ToList();
var result = new MultiplePermissionGrantResult(permissionNames.ToArray());
var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray();
if (roles == null || !roles.Any())
{
return result;
}
foreach (var role in roles)
{
var multipleResult = await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, role);
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;
permissionNames.RemoveAll(x => x == grantResult.Key);
}
if (result.AllGranted || result.AllProhibited)
{
break;
}
}
return result;
}
}
}

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Authorization.Permissions
@ -28,5 +29,18 @@ namespace Volo.Abp.Authorization.Permissions
? PermissionGrantResult.Granted
: PermissionGrantResult.Undefined;
}
public async override Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context)
{
var permissionNames = context.Permissions.Select(x => x.Name).ToArray();
var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value;
if (userId == null)
{
return new MultiplePermissionGrantResult(permissionNames);
}
return await PermissionStore.IsGrantedAsync(permissionNames, Name, userId);
}
}
}

@ -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<List<SettingValue>> GetAllAsync(SettingDefinition[] settings)
{
return Task.FromResult(settings.Select(x => new SettingValue(x.Name, Configuration[ConfigurationNamePrefix + x.Name])).ToList());
}
}
}
}

@ -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<List<SettingValue>> GetAllAsync(SettingDefinition[] settings)
{
return Task.FromResult(settings.Select(x => new SettingValue(x.Name, x.DefaultValue)).ToList());
}
}
}
}

@ -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<List<SettingValue>> GetAllAsync(SettingDefinition[] settings)
{
return SettingStore.GetAllAsync(settings.Select(x => x.Name).ToArray(), Name, null);
}
}
}
}

@ -8,6 +8,8 @@ namespace Volo.Abp.Settings
{
Task<string> GetOrNullAsync([NotNull]string name);
Task<List<SettingValue>> GetAllAsync([NotNull]string[] names);
Task<List<SettingValue>> GetAllAsync();
}
}

@ -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<List<SettingValue>> GetAllAsync(
[NotNull] string[] names,
[CanBeNull] string providerName,
[CanBeNull] string providerKey
);
}
}

@ -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<string> GetOrNullAsync([NotNull] SettingDefinition setting);
Task<List<SettingValue>> GetAllAsync([NotNull] SettingDefinition[] settings);
}
}
}

@ -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<List<SettingValue>> GetAllAsync(string[] names, string providerName, string providerKey)
{
return Task.FromResult(names.Select(x => new SettingValue(x, null)).ToList());
}
}
}
}

@ -43,29 +43,52 @@ namespace Volo.Abp.Settings
return value;
}
public virtual async Task<List<SettingValue>> GetAllAsync()
public async Task<List<SettingValue>> GetAllAsync(string[] names)
{
var settingValues = new Dictionary<string, SettingValue>();
var settingDefinitions = SettingDefinitionManager.GetAll();
var result = new Dictionary<string, SettingValue>();
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 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 settingDefinition = settingDefinitions.First(x => x.Name == settingValue.Name);
if (settingDefinition.IsEncrypted)
{
if (setting.IsEncrypted)
{
value = SettingEncryptionService.Decrypt(setting, value);
}
settingValue.Value = SettingEncryptionService.Decrypt(settingDefinition, settingValue.Value);
}
settingValues[setting.Name] = new SettingValue(setting.Name, 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.Values.ToList();
}
public virtual async Task<List<SettingValue>> GetAllAsync()
{
var settingValues = new List<SettingValue>();
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<string> GetOrNullValueFromProvidersAsync(

@ -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<string> GetOrNullAsync(SettingDefinition setting);
public abstract Task<List<SettingValue>> GetAllAsync(SettingDefinition[] settings);
}
}
}

@ -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<List<SettingValue>> GetAllAsync(SettingDefinition[] settings)
{
return await SettingStore.GetAllAsync(settings.Select(x => x.Name).ToArray(), Name, CurrentTenant.Id?.ToString());
}
}
}

@ -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<List<SettingValue>> 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());
}
}
}

@ -14,5 +14,20 @@ namespace Volo.Abp.AspNetCore.Mvc.Authorization
return Task.FromResult(result);
}
public Task<MultiplePermissionGrantResult> 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.Prohibited);
}
return Task.FromResult(result);
}
}
}

@ -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<string, string>();
}
@ -21,5 +22,10 @@ namespace Volo.Abp.Settings
{
return Task.FromResult(_values.GetOrDefault(setting.Name));
}
public Task<List<SettingValue>> GetAllAsync(SettingDefinition[] settings)
{
return Task.FromResult(settings.Select(x => new SettingValue(x.Name, _values.GetOrDefault(x.Name))).ToList());
}
}
}

@ -20,5 +20,12 @@ namespace Volo.Abp.PermissionManagement
string providerKey,
CancellationToken cancellationToken = default
);
Task<List<PermissionGrant>> GetListAsync(
string[] names,
string providerName,
string providerKey,
CancellationToken cancellationToken = default
);
}
}
}

@ -1,10 +1,14 @@
using System;
using System.Linq;
using Volo.Abp.Text.Formatting;
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()
@ -19,7 +23,13 @@ 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 GetPermissionNameFormCacheKeyOrNull(string cacheKey)
{
var result = FormattedStringValueExtracter.Extract(cacheKey, CacheKeyFormat, true);
return result.IsMatch ? result.Matches.Last().Value : null;
}
}
}
}

@ -53,9 +53,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 +68,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<string>(
@ -87,7 +87,7 @@ namespace Volo.Abp.PermissionManagement
CalculateCacheKey(permission.Name, providerName, providerKey),
new PermissionGrantCacheItem(isGranted))
);
if (permission.Name == currentName)
{
currentCacheItem.IsGranted = isGranted;
@ -95,13 +95,118 @@ namespace Volo.Abp.PermissionManagement
}
await Cache.SetManyAsync(cacheItems);
Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}");
}
public virtual async Task<MultiplePermissionGrantResult> 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(GetPermissionNameFormCacheKeyOrNull(item.Key),
item.Value != null && item.Value.IsGranted
? PermissionGrantResult.Granted
: PermissionGrantResult.Undefined);
}
return result;
}
protected virtual async Task<List<KeyValuePair<string, PermissionGrantCacheItem>>> 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;
}
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<KeyValuePair<string, PermissionGrantCacheItem>>();
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<string, PermissionGrantCacheItem>(key, item.Value));
}
return result;
}
protected virtual async Task<List<KeyValuePair<string, PermissionGrantCacheItem>>> SetCacheItemsAsync(
string providerName,
string providerKey,
List<string> notCacheKeys)
{
var permissions = PermissionDefinitionManager.GetPermissions().Where(x => notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name)).ToList();
Logger.LogDebug($"Getting not cache granted permissions from the repository for this provider name,key: {providerName},{providerKey}");
var grantedPermissionsHashSet = new HashSet<string>(
(await PermissionGrantRepository.GetListAsync(notCacheKeys.Select(GetPermissionNameFormCacheKeyOrNull).ToArray(), providerName, providerKey)).Select(p => p.Name)
);
Logger.LogDebug($"Setting the cache items. Count: {permissions.Count}");
var cacheItems = new List<KeyValuePair<string, PermissionGrantCacheItem>>();
foreach (var permission in permissions)
{
var isGranted = grantedPermissionsHashSet.Contains(permission.Name);
cacheItems.Add(new KeyValuePair<string, PermissionGrantCacheItem>(
CalculateCacheKey(permission.Name, providerName, providerKey),
new PermissionGrantCacheItem(isGranted))
);
}
await Cache.SetManyAsync(cacheItems);
Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}");
return cacheItems;
}
protected virtual string CalculateCacheKey(string name, string providerName, string providerKey)
{
return PermissionGrantCacheItem.CalculateCacheKey(name, providerName, providerKey);
}
protected virtual string GetPermissionNameFormCacheKeyOrNull(string key)
{
//TODO: throw ex when name is null?
return PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(key);
}
}
}
}

@ -9,7 +9,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.PermissionManagement.EntityFrameworkCore
{
public class EfCorePermissionGrantRepository : EfCoreRepository<IPermissionManagementDbContext, PermissionGrant, Guid>,
public class EfCorePermissionGrantRepository : EfCoreRepository<IPermissionManagementDbContext, PermissionGrant, Guid>,
IPermissionGrantRepository
{
public EfCorePermissionGrantRepository(IDbContextProvider<IPermissionManagementDbContext> dbContextProvider)
@ -19,8 +19,8 @@ namespace Volo.Abp.PermissionManagement.EntityFrameworkCore
}
public virtual async Task<PermissionGrant> 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<List<PermissionGrant>> 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));
}
}
}

@ -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<IPermissionManagementMongoDbContext, PermissionGrant, Guid>, IPermissionGrantRepository
{
public MongoPermissionGrantRepository(IMongoDbContextProvider<IPermissionManagementMongoDbContext> dbContextProvider)
public MongoPermissionGrantRepository(IMongoDbContextProvider<IPermissionManagementMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<PermissionGrant> 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<List<PermissionGrant>> 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<List<PermissionGrant>> 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));
}
}
}
}

@ -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();
}
}
}

@ -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);
}
}
}

@ -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");
}
}
}

@ -10,8 +10,10 @@ namespace Volo.Abp.SettingManagement
Task<List<SettingValue>> GetListAsync(string providerName, string providerKey);
Task<List<SettingValue>> 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);
}
}
}

@ -10,5 +10,7 @@ namespace Volo.Abp.SettingManagement
Task<Setting> FindAsync(string name, string providerName, string providerKey);
Task<List<Setting>> GetListAsync(string providerName, string providerKey);
Task<List<Setting>> GetListAsync(string[] names, string providerName, string providerKey);
}
}
}

@ -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 GetSettingNameFormCacheKeyOrNull(string cacheKey)
{
var result = FormattedStringValueExtracter.Extract(cacheKey, CacheKeyFormat, true);
return result.IsMatch ? result.Matches.Last().Value : null;
}
}
}

@ -118,9 +118,97 @@ namespace Volo.Abp.SettingManagement
await Cache.SetManyAsync(cacheItems, considerUow: true);
}
[UnitOfWork]
public async Task<List<SettingValue>> GetListAsync(string[] names, string providerName, string providerKey)
{
Check.NotNullOrEmpty(names, nameof(names));
var result = new List<SettingValue>();
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<List<KeyValuePair<string, SettingCacheItem>>> 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<KeyValuePair<string, SettingCacheItem>>();
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<string, SettingCacheItem>(key, item.Value));
}
return result;
}
private async Task<List<KeyValuePair<string, SettingCacheItem>>> SetCacheItemsAsync(
string providerName,
string providerKey,
List<string> notCacheKeys)
{
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<KeyValuePair<string, SettingCacheItem>>();
foreach (var settingDefinition in settingDefinitions)
{
var settingValue = settingsDictionary.GetOrDefault(settingDefinition.Name);
cacheItems.Add(
new KeyValuePair<string, SettingCacheItem>(
CalculateCacheKey(settingDefinition.Name, providerName, providerKey),
new SettingCacheItem(settingValue)
)
);
}
await Cache.SetManyAsync(cacheItems, considerUow: true);
return cacheItems;
}
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.GetSettingNameFormCacheKeyOrNull(key);
}
}
}

@ -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<List<SettingValue>> GetAllAsync(string[] names, string providerName, string providerKey)
{
return ManagementStore.GetListAsync(names, providerName, providerKey);
}
}
}

@ -30,5 +30,13 @@ namespace Volo.Abp.SettingManagement.EntityFrameworkCore
s => s.ProviderName == providerName && s.ProviderKey == providerKey
).ToListAsync();
}
public virtual async Task<List<Setting>> GetListAsync(string[] names, string providerName, string providerKey)
{
return await DbSet
.Where(
s => names.Contains(s.Name) && s.ProviderName == providerName && s.ProviderKey == providerKey
).ToListAsync();
}
}
}

@ -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<List<Setting>> GetListAsync(string[] names, string providerName, string providerKey)
{
return await GetMongoQueryable().Where(s => names.Contains(s.Name) && s.ProviderName == providerName && s.ProviderKey == providerKey).ToListAsync();
}
}
}
}

@ -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");
}
}
}

@ -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();
}
}
}

@ -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);
}
}
}

Loading…
Cancel
Save