From dbbe2545f1f14d1b5ed9c93be35a11c98ed62341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 13 Feb 2018 10:46:12 +0300 Subject: [PATCH] Permission system enhancements. --- .../IPermissionDefinitionContext.cs | 8 ++-- .../Abp/Permissions/PermissionDefinition.cs | 35 ++++++++++++-- .../PermissionDefinitionContext.cs | 48 +++++++++++++++---- .../PermissionDefinitionManager.cs | 7 +-- .../Volo/Abp/Session/AbpSessionModule.cs | 1 + .../Session/RolePermissionValueProvider.cs | 39 +++++++++++++++ .../TestPermissionDefinitionProvider.cs | 5 +- 7 files changed, 122 insertions(+), 21 deletions(-) create mode 100644 src/Volo.Abp.Session/Volo/Abp/Session/RolePermissionValueProvider.cs diff --git a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/IPermissionDefinitionContext.cs b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/IPermissionDefinitionContext.cs index 9aaf8b348f..0035821634 100644 --- a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/IPermissionDefinitionContext.cs +++ b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/IPermissionDefinitionContext.cs @@ -1,9 +1,11 @@ -namespace Volo.Abp.Permissions +using JetBrains.Annotations; + +namespace Volo.Abp.Permissions { public interface IPermissionDefinitionContext { - PermissionDefinition GetOrNull(string name); + PermissionDefinition GetOrNull([NotNull] string name); - void Add(params PermissionDefinition[] definitions); + PermissionDefinition Add([NotNull] string name); } } \ No newline at end of file diff --git a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinition.cs b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinition.cs index 8c37cf16ec..7f297c21bf 100644 --- a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinition.cs +++ b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinition.cs @@ -1,4 +1,7 @@ -namespace Volo.Abp.Permissions +using System.Collections.Generic; +using System.Collections.Immutable; + +namespace Volo.Abp.Permissions { public class PermissionDefinition { @@ -13,19 +16,41 @@ /// public PermissionDefinition Parent { get; private set; } - //TODO: Add Properties dictionary for custom stuff + public IReadOnlyList Children => _children.ToImmutableList(); + private readonly List _children; + + public Dictionary Properties { get; set; } - public PermissionDefinition(string name) + /// + /// Gets/sets a key-value on the . + /// + /// Name of the property + /// + /// Returns the value in the dictionary by given . + /// Returns null if given is not present in the dictionary. + /// + public object this[string name] + { + get => Properties.GetOrDefault(name); + set => Properties[name] = value; + } + + protected internal PermissionDefinition(string name) { Name = name; + _children = new List(); } - public PermissionDefinition CreateChild(string name) + public virtual PermissionDefinition AddChild(string name) { - return new PermissionDefinition(name) + var child = new PermissionDefinition(name) { Parent = this }; + + _children.Add(child); + + return child; } public override string ToString() diff --git a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinitionContext.cs b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinitionContext.cs index b5daa2140b..3461398012 100644 --- a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinitionContext.cs +++ b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinitionContext.cs @@ -1,19 +1,22 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; namespace Volo.Abp.Permissions { public class PermissionDefinitionContext : IPermissionDefinitionContext { - protected Dictionary Permissions { get; } + internal Dictionary Permissions { get; } - public PermissionDefinitionContext(Dictionary permissions) + public PermissionDefinitionContext() { - Permissions = permissions; + Permissions = new Dictionary(); } public virtual PermissionDefinition GetOrNull(string name) { + Check.NotNull(name, nameof(name)); + return Permissions.GetOrDefault(name); } @@ -22,16 +25,45 @@ namespace Volo.Abp.Permissions return Permissions.Values.ToImmutableList(); } - public virtual void Add(params PermissionDefinition[] definitions) + public virtual PermissionDefinition Add(string name) { - if (definitions.IsNullOrEmpty()) + Check.NotNull(name, nameof(name)); + + if (Permissions.ContainsKey(name)) + { + throw new AbpException($"There is already an existing permission with name: {name}"); + } + + return Permissions[name] = new PermissionDefinition(name); + } + + internal void HandleNewChildren() + { + Permissions.Values + .SelectMany(p => p.Children) + .ToList() + .ForEach(AddPermissionRecursively); + } + + private void AddPermissionRecursively(PermissionDefinition permission) + { + //Prevent multiple adding of same named permission. + if (Permissions.TryGetValue(permission.Name, out var existingPermission)) + { + if (existingPermission != permission) + { + throw new AbpException("Duplicate permission name detected for " + permission.Name); + } + } + else { - return; + Permissions[permission.Name] = permission; } - foreach (var definition in definitions) + //Add child permissions (recursive call) + foreach (var childPermission in permission.Children) { - Permissions[definition.Name] = definition; + AddPermissionRecursively(childPermission); } } } diff --git a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinitionManager.cs b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinitionManager.cs index e2644e28db..56527400b5 100644 --- a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinitionManager.cs +++ b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionDefinitionManager.cs @@ -65,14 +65,15 @@ namespace Volo.Abp.Permissions protected virtual IDictionary CreatePermissionDefinitions() { - var permissions = new Dictionary(); + var context = new PermissionDefinitionContext(); foreach (var provider in Providers) { - provider.Define(new PermissionDefinitionContext(permissions)); + provider.Define(context); + context.HandleNewChildren(); } - return permissions; + return context.Permissions; } } } \ No newline at end of file diff --git a/src/Volo.Abp.Session/Volo/Abp/Session/AbpSessionModule.cs b/src/Volo.Abp.Session/Volo/Abp/Session/AbpSessionModule.cs index 08fbad5d03..d9fb24a220 100644 --- a/src/Volo.Abp.Session/Volo/Abp/Session/AbpSessionModule.cs +++ b/src/Volo.Abp.Session/Volo/Abp/Session/AbpSessionModule.cs @@ -21,6 +21,7 @@ namespace Volo.Abp.Session services.Configure(options => { options.ValueProviders.Add(); + options.ValueProviders.Add(); }); services.AddAssemblyOf(); diff --git a/src/Volo.Abp.Session/Volo/Abp/Session/RolePermissionValueProvider.cs b/src/Volo.Abp.Session/Volo/Abp/Session/RolePermissionValueProvider.cs new file mode 100644 index 0000000000..a3af23959f --- /dev/null +++ b/src/Volo.Abp.Session/Volo/Abp/Session/RolePermissionValueProvider.cs @@ -0,0 +1,39 @@ +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Permissions; + +namespace Volo.Abp.Session +{ + public class RolePermissionValueProvider : PermissionValueProvider + { + public const string ProviderName = "Role"; + + public override string Name => ProviderName; + + protected ICurrentUser CurrentUser { get; } + + public RolePermissionValueProvider(IPermissionStore permissionStore, ICurrentUser currentUser) + : base(permissionStore) + { + CurrentUser = currentUser; + } + + public override async Task IsGrantedAsync(PermissionDefinition permission) + { + if (CurrentUser.Id == null || !CurrentUser.Roles.Any()) + { + return false; + } + + foreach (var role in CurrentUser.Roles) + { + if (await PermissionStore.IsGrantedAsync(permission.Name, Name, role)) + { + return true; + } + } + + return false; + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.Permissions.Tests/Volo/Abp/Permissions/TestPermissionDefinitionProvider.cs b/test/Volo.Abp.Permissions.Tests/Volo/Abp/Permissions/TestPermissionDefinitionProvider.cs index a8108aa344..c143a2e3c9 100644 --- a/test/Volo.Abp.Permissions.Tests/Volo/Abp/Permissions/TestPermissionDefinitionProvider.cs +++ b/test/Volo.Abp.Permissions.Tests/Volo/Abp/Permissions/TestPermissionDefinitionProvider.cs @@ -4,9 +4,10 @@ { public override void Define(IPermissionDefinitionContext context) { - var myPermission1 = new PermissionDefinition("MyPermission1"); + context.Add("MyPermission1"); - context.Add(myPermission1); + var myPermission2 = context.Add("MyPermission2"); + myPermission2.AddChild("MyPermission2.ChildPermission1"); } } } \ No newline at end of file