Browse Source

Introduce DynamicPermissionDefinitionStoreCache (initial)

pull/13644/head
Halil İbrahim Kalkan 4 years ago
parent
commit
edbe4aa6e3
  1. 4
      framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerSerializer.cs
  2. 8
      framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerSerializer.cs
  3. 44
      framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerSerializerExtensions.cs
  4. 26
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStore.cs
  5. 111
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreCache.cs

4
framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerSerializer.cs

@ -1,3 +1,5 @@
using System.Text.Json.Nodes;
namespace Volo.Abp.SimpleStateChecking; namespace Volo.Abp.SimpleStateChecking;
public interface ISimpleStateCheckerSerializer public interface ISimpleStateCheckerSerializer
@ -5,6 +7,6 @@ public interface ISimpleStateCheckerSerializer
public string Serialize<TState>(ISimpleStateChecker<TState> checker) public string Serialize<TState>(ISimpleStateChecker<TState> checker)
where TState : IHasSimpleStateCheckers<TState>; where TState : IHasSimpleStateCheckers<TState>;
public ISimpleStateChecker<TState> Deserialize<TState>(string value) public ISimpleStateChecker<TState> Deserialize<TState>(JsonObject jsonObject)
where TState : IHasSimpleStateCheckers<TState>; where TState : IHasSimpleStateCheckers<TState>;
} }

8
framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerSerializer.cs

@ -33,15 +33,9 @@ public class SimpleStateCheckerSerializer :
} }
[CanBeNull] [CanBeNull]
public ISimpleStateChecker<TState> Deserialize<TState>(string value) public ISimpleStateChecker<TState> Deserialize<TState>(JsonObject jsonObject)
where TState : IHasSimpleStateCheckers<TState> where TState : IHasSimpleStateCheckers<TState>
{ {
var jsonObject = JsonNode.Parse(value) as JsonObject;
if (jsonObject == null)
{
throw new AbpException("The value is not a JSON object: " + value);
}
foreach (var contributor in _contributors) foreach (var contributor in _contributors)
{ {
var result = contributor.Deserialize<TState>(jsonObject); var result = contributor.Deserialize<TState>(jsonObject);

44
framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerSerializerExtensions.cs

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.Json.Nodes;
namespace Volo.Abp.SimpleStateChecking; namespace Volo.Abp.SimpleStateChecking;
@ -35,4 +37,46 @@ public static class SimpleStateCheckerSerializerExtensions
return stringBuilder.ToString(); return stringBuilder.ToString();
} }
} }
public static ISimpleStateChecker<TState>[] DeserializeArray<TState>(
this ISimpleStateCheckerSerializer serializer,
string value)
where TState : IHasSimpleStateCheckers<TState>
{
if (value.IsNullOrWhiteSpace())
{
return Array.Empty<ISimpleStateChecker<TState>>();
}
var array = JsonNode.Parse(value) as JsonArray;
if (array == null || array.Count == 0)
{
return Array.Empty<ISimpleStateChecker<TState>>();
}
if (array.Count == 1)
{
var jsonObject = array[0] as JsonObject;
if (jsonObject == null)
{
throw new AbpException("JSON value is not an array of objects: " + value);
}
return new[] { serializer.Deserialize<TState>(jsonObject) };
}
var checkers = new ISimpleStateChecker<TState>[array.Count];
for (var i = 0; i < array.Count; i++)
{
if (array[i] is not JsonObject jsonObject)
{
throw new AbpException("JSON value is not an array of objects: " + value);
}
checkers[i] = serializer.Deserialize<TState>(jsonObject);
}
return checkers;
}
} }

26
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStore.cs

@ -6,8 +6,6 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.PermissionManagement; namespace Volo.Abp.PermissionManagement;
/*
[Dependency(ReplaceServices = true)] [Dependency(ReplaceServices = true)]
public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStore, ITransientDependency public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStore, ITransientDependency
{ {
@ -24,7 +22,7 @@ public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStor
PermissionRepository = permissionRepository; PermissionRepository = permissionRepository;
PermissionDefinitionSerializer = permissionDefinitionSerializer; PermissionDefinitionSerializer = permissionDefinitionSerializer;
} }
public virtual async Task<PermissionDefinition> GetOrNullAsync(string name) public virtual async Task<PermissionDefinition> GetOrNullAsync(string name)
{ {
var permissionRecord = await PermissionRepository.FindByNameAsync(name); var permissionRecord = await PermissionRepository.FindByNameAsync(name);
@ -32,18 +30,18 @@ public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStor
{ {
return null; return null;
} }
return await PermissionDefinitionSerializer.DeserializeAsync(permissionRecord); return await PermissionDefinitionSerializer.DeserializeAsync(permissionRecord);
} }
public virtual async Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() public virtual async Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync()
{ {
var permissionRecords = await PermissionRepository.GetListAsync(); var permissionRecords = await PermissionRepository.GetListAsync();
if(permissionRecords.Count == 0) if (permissionRecords.Count == 0)
{ {
return Array.Empty<PermissionDefinition>(); return Array.Empty<PermissionDefinition>();
} }
var permissionDefinitions = new PermissionDefinition[permissionRecords.Count]; var permissionDefinitions = new PermissionDefinition[permissionRecords.Count];
for (var i = 0; i < permissionRecords.Count; i++) for (var i = 0; i < permissionRecords.Count; i++)
{ {
@ -56,24 +54,18 @@ public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStor
public virtual async Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() public virtual async Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync()
{ {
var permissionGroupRecords = await PermissionGroupRepository.GetListAsync(); var permissionGroupRecords = await PermissionGroupRepository.GetListAsync();
if(permissionGroupRecords.Count == 0) if (permissionGroupRecords.Count == 0)
{ {
return Array.Empty<PermissionGroupDefinition>(); return Array.Empty<PermissionGroupDefinition>();
} }
var permissionGroupDefinitions = new PermissionGroupDefinition[permissionGroupRecords.Count]; var permissionGroupDefinitions = new PermissionGroupDefinition[permissionGroupRecords.Count];
for (var i = 0; i < permissionGroupRecords.Count; i++) for (var i = 0; i < permissionGroupRecords.Count; i++)
{ {
permissionGroupDefinitions[i] = await PermissionDefinitionSerializer.DeserializeAsync(permissionGroupRecords[i]); permissionGroupDefinitions[i] =
await PermissionDefinitionSerializer.DeserializeAsync(permissionGroupRecords[i]);
} }
return permissionGroupDefinitions; return permissionGroupDefinitions;
} }
}
public virtual async Task StoreStaticPermissionsAsync()
{
throw new NotImplementedException();
}
}
*/

111
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreCache.cs

@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
using Volo.Abp.SimpleStateChecking;
namespace Volo.Abp.PermissionManagement;
public class DynamicPermissionDefinitionStoreCache : ISingletonDependency
{
public string CacheStamp { get; set; }
protected IDictionary<string, PermissionGroupDefinition> PermissionGroupDefinitions { get; }
protected IDictionary<string, PermissionDefinition> PermissionDefinitions { get; }
protected ISimpleStateCheckerSerializer StateCheckerSerializer { get; }
public DynamicPermissionDefinitionStoreCache(ISimpleStateCheckerSerializer stateCheckerSerializer)
{
StateCheckerSerializer = stateCheckerSerializer;
PermissionGroupDefinitions = new Dictionary<string, PermissionGroupDefinition>();
PermissionDefinitions = new Dictionary<string, PermissionDefinition>();
}
public async Task FillAsync(
List<PermissionGroupDefinitionRecord> permissionGroupRecords,
List<PermissionDefinitionRecord> permissionRecords)
{
var context = new PermissionDefinitionContext(null);
foreach (var permissionGroupRecord in permissionGroupRecords)
{
var permissionGroup = context.AddGroup(
permissionGroupRecord.Name,
new FixedLocalizableString(permissionGroupRecord.DisplayName)
);
foreach (var property in permissionGroupRecord.ExtraProperties)
{
permissionGroup[property.Key] = property.Value;
}
var permissionRecordsInThisGroup = permissionRecords.Where(p => p.GroupName == permissionGroup.Name);
foreach (var permissionRecord in permissionRecordsInThisGroup)
{
var permission = permissionGroup.AddPermission(
permissionRecord.Name,
new FixedLocalizableString(permissionRecord.DisplayName),
permissionRecord.MultiTenancySide,
permissionRecord.IsEnabled
);
if (!permissionRecord.Providers.IsNullOrWhiteSpace())
{
permission.Providers.AddRange(permissionRecord.Providers.Split(','));
}
if (!permissionRecord.StateCheckers.IsNullOrWhiteSpace())
{
var checkers = StateCheckerSerializer
.DeserializeArray<PermissionDefinition>(
permissionRecord.StateCheckers
);
permission.StateCheckers.AddRange(checkers);
}
foreach (var property in permissionRecord.ExtraProperties)
{
permission[property.Key] = property.Value;
}
//TODO: Child permissions! (with parent name setting)
}
}
}
protected virtual Dictionary<string, PermissionDefinition> CreatePermissionDefinitions()
{
var permissions = new Dictionary<string, PermissionDefinition>();
foreach (var groupDefinition in PermissionGroupDefinitions.Values)
{
foreach (var permission in groupDefinition.Permissions)
{
AddPermissionToDictionaryRecursively(permissions, permission);
}
}
return permissions;
}
protected virtual void AddPermissionToDictionaryRecursively(
Dictionary<string, PermissionDefinition> permissions,
PermissionDefinition permission)
{
if (permissions.ContainsKey(permission.Name))
{
throw new AbpException("Duplicate permission name: " + permission.Name);
}
permissions[permission.Name] = permission;
foreach (var child in permission.Children)
{
AddPermissionToDictionaryRecursively(permissions, child);
}
}
}
Loading…
Cancel
Save