From 74d6bdbe2cca4d8b5f9c8b54c5acfbf77a509796 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 11 Nov 2025 15:13:06 +0800 Subject: [PATCH] Add resource permission management interfaces and implementations --- .../Permissions/AbpPermissionOptions.cs | 4 + .../Resources/IResourcePermissionChecker.cs | 63 +------ .../Resources/IResourcePermissionStore.cs | 67 +++++++ .../IResourcePermissionValueProvider.cs | 13 ++ ...IResourcePermissionValueProviderManager.cs | 8 + .../Resources/NullResourcePermissionStore.cs | 44 +++++ .../Resources/ResourcePermissionGrantInfo.cs | 17 ++ ...s => ResourcePermissionStoreExtensions.cs} | 36 ++-- .../ResourcePermissionValueCheckContext.cs | 25 +++ .../ResourcePermissionValueProvider.cs | 20 +++ .../ResourcePermissionValuesCheckContext.cs | 41 +++++ .../Resources/ResourcePermissionChecker.cs | 170 ++++++++++++++++++ ...ntityResourcePermissionStoreExtensions.cs} | 40 ++--- 13 files changed, 456 insertions(+), 92 deletions(-) create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionStore.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProvider.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProviderManager.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/NullResourcePermissionStore.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionGrantInfo.cs rename framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/{ResourcePermissionCheckerExtensions.cs => ResourcePermissionStoreExtensions.cs} (75%) create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueCheckContext.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProvider.cs create mode 100644 framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValuesCheckContext.cs create mode 100644 framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs rename framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/{EntityResourcePermissionCheckerExtensions.cs => EntityResourcePermissionStoreExtensions.cs} (70%) diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs index 4bdd7c0bb8..c240e1ac07 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Volo.Abp.Authorization.Permissions.Resources; using Volo.Abp.Collections; namespace Volo.Abp.Authorization.Permissions; @@ -9,6 +10,8 @@ public class AbpPermissionOptions public ITypeList ValueProviders { get; } + public ITypeList ResourceValueProviders { get; } + public HashSet DeletedPermissions { get; } public HashSet DeletedPermissionGroups { get; } @@ -17,6 +20,7 @@ public class AbpPermissionOptions { DefinitionProviders = new TypeList(); ValueProviders = new TypeList(); + ResourceValueProviders = new TypeList(); DeletedPermissions = new HashSet(); DeletedPermissionGroups = new HashSet(); diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionChecker.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionChecker.cs index 4e8229d605..5b3bf1eee1 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionChecker.cs @@ -1,61 +1,16 @@ -using System.Collections.Generic; +using System.Security.Claims; using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.Authorization.Permissions.Resources; public interface IResourcePermissionChecker { - /// - /// Checks if the given permission is granted for the given resource. - /// - /// The name of the permission. - /// The name of the resource. - /// Resource key - /// - /// True if the permission is granted. - /// - Task IsGrantedAsync( - string permissionName, - string resourceName, - string resourceKey - ); - - /// - /// Gets all permissions for the given resource. - /// - /// Resource name - /// Resource key - /// - /// A dictionary of permission names and their states. - /// - Task> GetPermissionsAsync( - string resourceName, - string resourceKey - ); - - /// - /// Gets all granted permissions for the given resource. - /// - /// Resource name - /// Resource key - /// - /// An array of granted permission names. - /// - Task GetGrantedPermissionsAsync( - string resourceName, - string resourceKey - ); + Task IsGrantedAsync([NotNull] string name, string resourceName, string resourceKey); - /// - /// Retrieves the keys of resources for which the specified permission is granted. - /// - /// The name of the resource. - /// The name of the permission. - /// - /// An array of resource keys where the specified permission is granted. - /// - Task GetGrantedResourceKeysAsync( - string resourceName, - string permissionName - ); -} \ No newline at end of file + Task IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, [NotNull] string name, string resourceName, string resourceKey); + + Task IsGrantedAsync([NotNull] string[] names, string resourceName, string resourceKey); + + Task IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, [NotNull] string[] names, string resourceName, string resourceKey); +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionStore.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionStore.cs new file mode 100644 index 0000000000..94ae94c5db --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionStore.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public interface IResourcePermissionStore +{ + /// + /// Checks if the given permission is granted for the given resource. + /// + /// The name of the permission. + /// The name of the resource. + /// Resource key + /// + /// True if the permission is granted. + /// + Task IsGrantedAsync( + string name, + string resourceName, + string resourceKey + ); + + Task IsGrantedAsync( + string[] names, + string resourceName, + string resourceKey + ); + + /// + /// Gets all permissions for the given resource. + /// + /// Resource name + /// Resource key + /// + /// A dictionary of permission names and their states. + /// + Task> GetPermissionsAsync( + string resourceName, + string resourceKey + ); + + /// + /// Gets all granted permissions for the given resource. + /// + /// Resource name + /// Resource key + /// + /// An array of granted permission names. + /// + Task GetGrantedPermissionsAsync( + string resourceName, + string resourceKey + ); + + /// + /// Retrieves the keys of resources for which the specified permission is granted. + /// + /// The name of the resource. + /// The name of the permission. + /// + /// An array of resource keys where the specified permission is granted. + /// + Task GetGrantedResourceKeysAsync( + string resourceName, + string name + ); +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProvider.cs new file mode 100644 index 0000000000..655b2cda6e --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProvider.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public interface IResourcePermissionValueProvider +{ + string Name { get; } + + //TODO: Rename to GetResult? (CheckAsync throws exception by naming convention) + Task CheckAsync(ResourcePermissionValueCheckContext context); + + Task CheckAsync(ResourcePermissionValuesCheckContext context); +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProviderManager.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProviderManager.cs new file mode 100644 index 0000000000..e07e63d06a --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProviderManager.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public interface IResourcePermissionValueProviderManager +{ + IReadOnlyList ValueProviders { get; } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/NullResourcePermissionStore.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/NullResourcePermissionStore.cs new file mode 100644 index 0000000000..0b5ce51d2e --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/NullResourcePermissionStore.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class NullResourcePermissionStore : IResourcePermissionStore, ISingletonDependency +{ + public ILogger Logger { get; set; } + + public NullResourcePermissionStore() + { + Logger = NullLogger.Instance; + } + + public Task IsGrantedAsync(string name, string resourceName, string resourceKey) + { + return TaskCache.FalseResult; + } + + public Task IsGrantedAsync(string[] names, string resourceName, string resourceKey) + { + return Task.FromResult(new MultiplePermissionGrantResult(names, PermissionGrantResult.Prohibited)); + } + + public Task> GetPermissionsAsync(string resourceName, string resourceKey) + { + return Task.FromResult((IDictionary)new Dictionary()); + } + + public Task GetGrantedPermissionsAsync(string resourceName, string resourceKey) + { + return Task.FromResult(Array.Empty()); + } + + public Task GetGrantedResourceKeysAsync(string resourceName, string name) + { + return Task.FromResult(Array.Empty()); + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionGrantInfo.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionGrantInfo.cs new file mode 100644 index 0000000000..9977c5eb2a --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionGrantInfo.cs @@ -0,0 +1,17 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionGrantInfo : PermissionGrantInfo +{ + public string ResourceName { get; } + + public string ResourceKey { get; } + + public ResourcePermissionGrantInfo([NotNull] string name, bool isGranted, string resourceName, string resourceKey, string? providerName = null, string? providerKey = null) + : base(name, isGranted, providerName, providerKey) + { + ResourceName = resourceName; + ResourceKey = resourceKey; + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionCheckerExtensions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionStoreExtensions.cs similarity index 75% rename from framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionCheckerExtensions.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionStoreExtensions.cs index fa73aa428f..2333737595 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionCheckerExtensions.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionStoreExtensions.cs @@ -3,30 +3,30 @@ using System.Threading.Tasks; namespace Volo.Abp.Authorization.Permissions.Resources; -public static class ResourcePermissionCheckerExtensions +public static class ResourcePermissionStoreExtensions { /// /// Checks if a specific permission is granted for a resource with a given key. /// /// The type of the resource. - /// The resource permission checker instance. + /// The resource permission checker instance. /// The name of the permission to check. /// The resource instance to check permission for. /// The unique key identifying the resource instance. /// A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the permission is granted. public static Task IsGrantedAsync( - this IResourcePermissionChecker resourcePermissionChecker, + this IResourcePermissionStore resourcePermissionStore, string permissionName, TResource resource, object resourceKey ) { - Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); Check.NotNull(resource, nameof(resource)); Check.NotNull(resourceKey, nameof(resourceKey)); - return resourcePermissionChecker.IsGrantedAsync( + return resourcePermissionStore.IsGrantedAsync( permissionName, typeof(TResource).FullName!, resourceKey.ToString()! @@ -37,21 +37,21 @@ public static class ResourcePermissionCheckerExtensions /// Retrieves a dictionary of permissions and their granted statuses for a specific resource. /// /// The type of the resource. - /// The resource permission checker instance. + /// The resource permission checker instance. /// The resource instance for which permissions are being checked. /// The unique key identifying the resource instance. /// A task that represents the asynchronous operation. The task result contains a dictionary where keys are permission names and values indicate whether the corresponding permission is granted. public static Task> GetPermissionsAsync( - this IResourcePermissionChecker resourcePermissionChecker, + this IResourcePermissionStore resourcePermissionStore, TResource resource, object resourceKey ) { - Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); Check.NotNull(resource, nameof(resource)); Check.NotNull(resourceKey, nameof(resourceKey)); - return resourcePermissionChecker.GetPermissionsAsync( + return resourcePermissionStore.GetPermissionsAsync( typeof(TResource).FullName!, resourceKey.ToString()! ); @@ -61,21 +61,21 @@ public static class ResourcePermissionCheckerExtensions /// Retrieves the list of granted permissions for a specific resource with a given key. /// /// The type of the resource. - /// The resource permission checker instance. + /// The resource permission checker instance. /// The resource instance to retrieve permissions for. /// The unique key identifying the resource instance. /// A task that represents the asynchronous operation. The task result contains an array of strings representing the granted permissions. public static Task GetGrantedPermissionsAsync( - this IResourcePermissionChecker resourcePermissionChecker, + this IResourcePermissionStore resourcePermissionStore, TResource resource, object resourceKey ) { - Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); Check.NotNull(resource, nameof(resource)); Check.NotNull(resourceKey, nameof(resourceKey)); - return resourcePermissionChecker.GetGrantedPermissionsAsync( + return resourcePermissionStore.GetGrantedPermissionsAsync( typeof(TResource).FullName!, resourceKey.ToString()! ); @@ -85,23 +85,23 @@ public static class ResourcePermissionCheckerExtensions /// Retrieves the keys of the resources granted a specific permission. /// /// The type of the resource. - /// The resource permission checker instance. + /// The resource permission checker instance. /// The resource instance to check granted permissions for. /// The name of the permission to check. /// A task that represents the asynchronous operation. The task result contains an array of strings representing the granted resource keys. public static Task GetGrantedResourceKeysAsync( - this IResourcePermissionChecker resourcePermissionChecker, + this IResourcePermissionStore resourcePermissionStore, TResource resource, string permissionName ) { - Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); Check.NotNull(resource, nameof(resource)); Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); - return resourcePermissionChecker.GetGrantedResourceKeysAsync( + return resourcePermissionStore.GetGrantedResourceKeysAsync( typeof(TResource).FullName!, permissionName ); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueCheckContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueCheckContext.cs new file mode 100644 index 0000000000..54e7f80e35 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueCheckContext.cs @@ -0,0 +1,25 @@ +using System.Security.Claims; +using JetBrains.Annotations; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionValueCheckContext : PermissionValueCheckContext +{ + [NotNull] + public string ResourceName { get; } + + [NotNull] + public string ResourceKey { get; } + + public ResourcePermissionValueCheckContext([NotNull] PermissionDefinition permission, string resourceName, string resourceKey) + : this(permission, null, resourceName, resourceKey) + { + } + + public ResourcePermissionValueCheckContext([NotNull] PermissionDefinition permission, ClaimsPrincipal? principal, string resourceName, string resourceKey) + : base(permission, principal) + { + ResourceName = resourceName; + ResourceKey = resourceKey; + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProvider.cs new file mode 100644 index 0000000000..9275502696 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProvider.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public abstract class ResourcePermissionValueProvider : IResourcePermissionValueProvider, ITransientDependency +{ + public abstract string Name { get; } + + protected IResourcePermissionStore PermissionStore { get; } + + protected ResourcePermissionValueProvider(IResourcePermissionStore permissionStore) + { + PermissionStore = permissionStore; + } + + public abstract Task CheckAsync(ResourcePermissionValueCheckContext context); + + public abstract Task CheckAsync(ResourcePermissionValuesCheckContext context); +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValuesCheckContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValuesCheckContext.cs new file mode 100644 index 0000000000..7de44b1a0d --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValuesCheckContext.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Security.Claims; +using JetBrains.Annotations; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionValuesCheckContext : PermissionValuesCheckContext +{ + [NotNull] + public string ResourceName { get; } + + [NotNull] + public string ResourceKey { get; } + + public ResourcePermissionValuesCheckContext([NotNull] PermissionDefinition permission,string resourceName, string resourceKey) + : this([permission], null, resourceName, resourceKey) + { + + } + + + public ResourcePermissionValuesCheckContext([NotNull] PermissionDefinition permission, ClaimsPrincipal? principal, string resourceName, string resourceKey) + : this([permission], principal, resourceName, resourceKey) + { + + } + + public ResourcePermissionValuesCheckContext([NotNull] List permissions, string resourceName, string resourceKey) + : this(permissions, null, resourceName, resourceKey) + { + ResourceName = resourceName; + ResourceKey = resourceKey; + } + + public ResourcePermissionValuesCheckContext([NotNull] List permissions, ClaimsPrincipal? principal, string resourceName, string resourceKey) + : base(permissions, principal) + { + ResourceName = resourceName; + ResourceKey = resourceKey; + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs new file mode 100644 index 0000000000..09b2e7c3bc --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs @@ -0,0 +1,170 @@ +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Security.Principal; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionChecker : IResourcePermissionChecker, ITransientDependency +{ + protected IPermissionDefinitionManager PermissionDefinitionManager { get; } + protected ICurrentPrincipalAccessor PrincipalAccessor { get; } + protected ICurrentTenant CurrentTenant { get; } + protected IResourcePermissionValueProviderManager PermissionValueProviderManager { get; } + protected ISimpleStateCheckerManager StateCheckerManager { get; } + + public ResourcePermissionChecker( + ICurrentPrincipalAccessor principalAccessor, + IPermissionDefinitionManager permissionDefinitionManager, + ICurrentTenant currentTenant, + IResourcePermissionValueProviderManager permissionValueProviderManager, + ISimpleStateCheckerManager stateCheckerManager) + { + PrincipalAccessor = principalAccessor; + PermissionDefinitionManager = permissionDefinitionManager; + CurrentTenant = currentTenant; + PermissionValueProviderManager = permissionValueProviderManager; + StateCheckerManager = stateCheckerManager; + } + + public virtual async Task IsGrantedAsync(string name, string resourceName, string resourceKey) + { + return await IsGrantedAsync(PrincipalAccessor.Principal, name, resourceName, resourceKey); + } + + public virtual async Task IsGrantedAsync( + ClaimsPrincipal? claimsPrincipal, + string name, + string resourceName, + string resourceKey) + { + Check.NotNull(name, nameof(name)); + + var permission = await PermissionDefinitionManager.GetOrNullAsync(name); + if (permission == null) + { + return false; + } + + if (!permission.IsEnabled) + { + return false; + } + + if (!await StateCheckerManager.IsEnabledAsync(permission)) + { + return false; + } + + var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() + ?? CurrentTenant.GetMultiTenancySide(); + + if (!permission.MultiTenancySide.HasFlag(multiTenancySide)) + { + return false; + } + + var isGranted = false; + var context = new ResourcePermissionValueCheckContext(permission, claimsPrincipal, resourceName, resourceKey); + foreach (var provider in PermissionValueProviderManager.ValueProviders) + { + if (context.Permission.Providers.Any() && + !context.Permission.Providers.Contains(provider.Name)) + { + continue; + } + + var result = await provider.CheckAsync(context); + + if (result == PermissionGrantResult.Granted) + { + isGranted = true; + } + else if (result == PermissionGrantResult.Prohibited) + { + return false; + } + } + + return isGranted; + } + + public async Task IsGrantedAsync(string[] names, string resourceName, string resourceKey) + { + return await IsGrantedAsync(PrincipalAccessor.Principal, names, resourceName,resourceKey); + } + + public async Task IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, string[] names, string resourceName, string resourceKey) + { + Check.NotNull(names, nameof(names)); + + var result = new MultiplePermissionGrantResult(); + if (!names.Any()) + { + return result; + } + + var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() ?? + CurrentTenant.GetMultiTenancySide(); + + var permissionDefinitions = new List(); + foreach (var name in names) + { + var permission = await PermissionDefinitionManager.GetOrNullAsync(name); + if (permission == null) + { + result.Result.Add(name, PermissionGrantResult.Prohibited); + continue; + } + + result.Result.Add(name, PermissionGrantResult.Undefined); + + if (permission.IsEnabled && + await StateCheckerManager.IsEnabledAsync(permission) && + permission.MultiTenancySide.HasFlag(multiTenancySide)) + { + permissionDefinitions.Add(permission); + } + } + + foreach (var provider in PermissionValueProviderManager.ValueProviders) + { + var permissions = permissionDefinitions + .Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)) + .ToList(); + + if (permissions.IsNullOrEmpty()) + { + continue; + } + + var context = new ResourcePermissionValuesCheckContext( + permissions, + claimsPrincipal, + resourceName, + resourceKey); + + 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; + } +} diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionCheckerExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionStoreExtensions.cs similarity index 70% rename from framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionCheckerExtensions.cs rename to framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionStoreExtensions.cs index 6a3ff5e6b1..67be57a747 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionCheckerExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionStoreExtensions.cs @@ -6,28 +6,28 @@ using Volo.Abp.Domain.Entities; namespace Volo.Abp.Authorization.Permissions.Resources; -public static class EntityResourcePermissionCheckerExtensions +public static class EntityResourcePermissionStoreExtensions { /// /// Checks if the specified permission is granted for the given entity. /// /// The type of the entity. - /// The resource permission checker instance. + /// The resource permission checker instance. /// The name of the permission to check. /// The entity for which the permission is being checked. /// A task that represents the asynchronous operation. The task result is a boolean indicating whether the permission is granted. public static Task IsGrantedAsync( - this IResourcePermissionChecker resourcePermissionChecker, + this IResourcePermissionStore resourcePermissionStore, string permissionName, TEntity entity ) where TEntity : class, IEntity { - Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); Check.NotNull(entity, nameof(entity)); - return resourcePermissionChecker.IsGrantedAsync( + return resourcePermissionStore.IsGrantedAsync( permissionName, typeof(TEntity).FullName!, entity.GetKeys().JoinAsString(",") @@ -38,19 +38,19 @@ public static class EntityResourcePermissionCheckerExtensions /// Retrieves a dictionary of permissions and their granted status for the specified entity. /// /// The type of the entity. - /// The resource permission checker instance. + /// The resource permission checker instance. /// The entity for which the permissions are being retrieved. /// A dictionary where the keys are permission names and the values are booleans indicating whether the permission is granted. public static Task> GetPermissionsAsync( - this IResourcePermissionChecker resourcePermissionChecker, + this IResourcePermissionStore resourcePermissionStore, TEntity entity ) where TEntity : class, IEntity { - Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); Check.NotNull(entity, nameof(entity)); - return resourcePermissionChecker.GetPermissionsAsync( + return resourcePermissionStore.GetPermissionsAsync( typeof(TEntity).FullName!, entity.GetKeys().JoinAsString(",") ); @@ -60,19 +60,19 @@ public static class EntityResourcePermissionCheckerExtensions /// Retrieves an array of granted permissions for a specific entity. /// /// The type of the entity. - /// The resource permission checker instance. + /// The resource permission checker instance. /// The entity for which the permissions are being checked. /// An array of granted permission names as strings. public static Task GetGrantedPermissionsAsync( - this IResourcePermissionChecker resourcePermissionChecker, + this IResourcePermissionStore resourcePermissionStore, TEntity entity ) where TEntity : class, IEntity { - Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); Check.NotNull(entity, nameof(entity)); - return resourcePermissionChecker.GetGrantedPermissionsAsync( + return resourcePermissionStore.GetGrantedPermissionsAsync( typeof(TEntity).FullName!, entity.GetKeys().JoinAsString(",") ); @@ -83,26 +83,26 @@ public static class EntityResourcePermissionCheckerExtensions /// /// The type of the entity. /// The type of the entity's primary key. - /// The resource permission checker instance. + /// The resource permission checker instance. /// The name of the permission to check. /// An array of entity IDs (of type ) for which the permission is granted. - public async static Task GetGrantedEntityIdsAsync( - this IResourcePermissionChecker resourcePermissionChecker, + public static async Task GetGrantedEntityIdsAsync( + this IResourcePermissionStore resourcePermissionStore, string permissionName ) where TEntity : class, IEntity { - Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); - var keys = await resourcePermissionChecker.GetGrantedResourceKeysAsync( + var keys = await resourcePermissionStore.GetGrantedResourceKeysAsync( typeof(TEntity).FullName!, permissionName ); - + return keys .Select(x => Convert.ChangeType(x, typeof(TKey))) .Cast() .ToArray(); } -} \ No newline at end of file +}