Browse Source

Refactor StaticPermissionDefinitionStore to use caches

pull/24493/head
maliming 1 month ago
parent
commit
cf9f31719c
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 134
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/StaticPermissionDefinitionStore.cs

134
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/StaticPermissionDefinitionStore.cs

@ -6,76 +6,72 @@ using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.StaticDefinitions;
namespace Volo.Abp.Authorization.Permissions; namespace Volo.Abp.Authorization.Permissions;
public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, ISingletonDependency public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, ISingletonDependency
{ {
protected IDictionary<string, PermissionGroupDefinition> PermissionGroupDefinitions => _lazyPermissionGroupDefinitions.Value.Item1; protected IServiceProvider ServiceProvider { get; }
private readonly Lazy<(Dictionary<string, PermissionGroupDefinition>, List<PermissionDefinition>)> _lazyPermissionGroupDefinitions;
protected IDictionary<string, PermissionDefinition> PermissionDefinitions => _lazyPermissionDefinitions.Value;
private readonly Lazy<Dictionary<string, PermissionDefinition>> _lazyPermissionDefinitions;
protected IList<PermissionDefinition> ResourcePermissionDefinitions => _lazyPermissionGroupDefinitions.Value.Item2;
protected AbpPermissionOptions Options { get; } protected AbpPermissionOptions Options { get; }
protected IStaticDefinitionCache<PermissionGroupDefinition, (Dictionary<string, PermissionGroupDefinition>, List<PermissionDefinition>)> GroupCache { get; }
private readonly IServiceProvider _serviceProvider; protected IStaticDefinitionCache<PermissionDefinition, Dictionary<string, PermissionDefinition>> DefinitionCache { get; }
public StaticPermissionDefinitionStore( public StaticPermissionDefinitionStore(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IOptions<AbpPermissionOptions> options) IOptions<AbpPermissionOptions> options,
IStaticDefinitionCache<PermissionGroupDefinition, (Dictionary<string, PermissionGroupDefinition>, List<PermissionDefinition>)> groupCache,
IStaticDefinitionCache<PermissionDefinition, Dictionary<string, PermissionDefinition>> definitionCache)
{ {
_serviceProvider = serviceProvider; ServiceProvider = serviceProvider;
Options = options.Value; Options = options.Value;
GroupCache = groupCache;
DefinitionCache = definitionCache;
}
_lazyPermissionDefinitions = new Lazy<Dictionary<string, PermissionDefinition>>( public async Task<PermissionDefinition?> GetOrNullAsync(string name)
CreatePermissionDefinitions, {
isThreadSafe: true var defs = await GetPermissionDefinitionsAsync();
); return defs.GetOrDefault(name);
_lazyPermissionGroupDefinitions = new Lazy<(Dictionary<string, PermissionGroupDefinition>, List<PermissionDefinition>)>(
CreatePermissionGroupDefinitions,
isThreadSafe: true
);
} }
protected virtual Dictionary<string, PermissionDefinition> CreatePermissionDefinitions() public virtual async Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync()
{ {
var permissions = new Dictionary<string, PermissionDefinition>(); var defs = await GetPermissionDefinitionsAsync();
return defs.Values.ToImmutableList();
}
foreach (var groupDefinition in PermissionGroupDefinitions.Values) public virtual async Task<PermissionDefinition?> GetResourcePermissionOrNullAsync(string resourceName, string name)
{ {
foreach (var permission in groupDefinition.Permissions) var (_, resourcePermissions) = await GetPermissionGroupDefinitionsAsync();
{ return resourcePermissions.FirstOrDefault(p => p.ResourceName == resourceName && p.Name == name);
AddPermissionToDictionaryRecursively(permissions, permission); }
}
}
return permissions; public virtual async Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync()
{
var (_, resourcePermissions) = await GetPermissionGroupDefinitionsAsync();
return resourcePermissions.ToImmutableList();
} }
protected virtual void AddPermissionToDictionaryRecursively( public async Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync()
Dictionary<string, PermissionDefinition> permissions,
PermissionDefinition permission)
{ {
if (permissions.ContainsKey(permission.Name)) var (groups, _) = await GetPermissionGroupDefinitionsAsync();
{ return groups.Values.ToImmutableList();
throw new AbpException("Duplicate permission name: " + permission.Name); }
}
permissions[permission.Name] = permission; protected virtual async Task<(Dictionary<string, PermissionGroupDefinition>, List<PermissionDefinition>)> GetPermissionGroupDefinitionsAsync()
{
return await GroupCache.GetOrCreateAsync(CreatePermissionGroupDefinitionsAsync);
}
foreach (var child in permission.Children) protected virtual async Task<Dictionary<string, PermissionDefinition>> GetPermissionDefinitionsAsync()
{ {
AddPermissionToDictionaryRecursively(permissions, child); return await DefinitionCache.GetOrCreateAsync(CreatePermissionDefinitionsAsync);
}
} }
protected virtual (Dictionary<string, PermissionGroupDefinition>, List<PermissionDefinition>) CreatePermissionGroupDefinitions() protected virtual Task<(Dictionary<string, PermissionGroupDefinition>, List<PermissionDefinition>)> CreatePermissionGroupDefinitionsAsync()
{ {
using (var scope = _serviceProvider.CreateScope()) using (var scope = ServiceProvider.CreateScope())
{ {
var context = new PermissionDefinitionContext(scope.ServiceProvider); var context = new PermissionDefinitionContext(scope.ServiceProvider);
@ -104,38 +100,40 @@ public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore,
context.CurrentProvider = null; context.CurrentProvider = null;
return (context.Groups, context.ResourcePermissions); return Task.FromResult((context.Groups, context.ResourcePermissions));
} }
} }
public Task<PermissionDefinition?> GetOrNullAsync(string name) protected virtual async Task<Dictionary<string, PermissionDefinition>> CreatePermissionDefinitionsAsync()
{ {
return Task.FromResult(PermissionDefinitions.GetOrDefault(name)); var permissions = new Dictionary<string, PermissionDefinition>();
}
public virtual Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() var (groups, _) = await GetPermissionGroupDefinitionsAsync();
{ foreach (var groupDefinition in groups.Values)
return Task.FromResult<IReadOnlyList<PermissionDefinition>>( {
PermissionDefinitions.Values.ToImmutableList() foreach (var permission in groupDefinition.Permissions)
); {
} AddPermissionToDictionaryRecursively(permissions, permission);
}
}
public virtual Task<PermissionDefinition?> GetResourcePermissionOrNullAsync(string resourceName, string name) return permissions;
{
return Task.FromResult<PermissionDefinition?>(ResourcePermissionDefinitions.FirstOrDefault(p => p.ResourceName == resourceName && p.Name == name));
} }
public virtual Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() protected virtual void AddPermissionToDictionaryRecursively(
Dictionary<string, PermissionDefinition> permissions,
PermissionDefinition permission)
{ {
return Task.FromResult<IReadOnlyList<PermissionDefinition>>( if (permissions.ContainsKey(permission.Name))
ResourcePermissionDefinitions.ToImmutableList() {
); throw new AbpException("Duplicate permission name: " + permission.Name);
} }
public Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() permissions[permission.Name] = permission;
{
return Task.FromResult<IReadOnlyList<PermissionGroupDefinition>>( foreach (var child in permission.Children)
PermissionGroupDefinitions.Values.ToImmutableList() {
); AddPermissionToDictionaryRecursively(permissions, child);
}
} }
} }

Loading…
Cancel
Save