Browse Source

Implement resource permissions management with new interfaces and extension methods

pull/24374/head
maliming 3 months ago
parent
commit
7cbc6c3703
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 8
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IHasResourcePermissions.cs
  2. 27
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionCheckerExtensions.cs
  3. 24
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionStoreExtensions.cs
  4. 39
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionPopulator.cs
  5. 19
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityExtensions.cs
  6. 34
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionCheckerExtensions.cs
  7. 5
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionRequirementHandler.cs
  8. 36
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionStoreExtensions.cs
  9. 14
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs

8
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IHasResourcePermissions.cs

@ -0,0 +1,8 @@
using System.Collections.Generic;
namespace Volo.Abp.Authorization.Permissions.Resources;
public interface IHasResourcePermissions
{
public Dictionary<string, bool> ResourcePermissions { get; }
}

27
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionCheckerExtensions.cs

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading.Tasks;
namespace Volo.Abp.Authorization.Permissions.Resources;
@ -32,28 +31,4 @@ public static class ResourcePermissionCheckerExtensions
resourceKey.ToString()!
);
}
/// <summary>
/// Retrieves a dictionary of permissions and their granted statuses for a specific resource.
/// </summary>
/// <typeparam name="TResource">The type of the resource.</typeparam>
/// <param name="resourcePermissionChecker">The resource permission checker instance.</param>
/// <param name="resource">The resource instance for which permissions are being checked.</param>
/// <param name="resourceKey">The unique key identifying the resource instance.</param>
/// <returns>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.</returns>
public static Task<IDictionary<string, bool>> GetPermissionsAsync<TResource>(
this IResourcePermissionChecker resourcePermissionChecker,
TResource resource,
object resourceKey
)
{
Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker));
Check.NotNull(resource, nameof(resource));
Check.NotNull(resourceKey, nameof(resourceKey));
return resourcePermissionChecker.GetPermissionsAsync(
typeof(TResource).FullName!,
resourceKey.ToString()!
);
}
}

24
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionStoreExtensions.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Volo.Abp.Authorization.Permissions.Resources;
@ -13,7 +14,24 @@ public static class ResourcePermissionStoreExtensions
/// <param name="resource">The resource instance to retrieve permissions for.</param>
/// <param name="resourceKey">The unique key identifying the resource instance.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains an array of strings representing the granted permissions.</returns>
public static Task<string[]> GetGrantedPermissionsAsync<TResource>(
public static async Task<string[]> GetGrantedPermissionsAsync<TResource>(
this IResourcePermissionStore resourcePermissionStore,
TResource resource,
object resourceKey
)
{
return (await GetPermissionsAsync(resourcePermissionStore, resource, resourceKey)).Where(x => x.Value).Select(x => x.Key).ToArray();
}
/// <summary>
/// Retrieves a dictionary of permissions and their granted status for the specified entity.
/// </summary>
/// <typeparam name="TResource">The type of the resource.</typeparam>
/// <param name="resourcePermissionStore">The resource permission store instance.</param>
/// <param name="resource">The resource for which the permissions are being retrieved.</param>
/// <param name="resourceKey">The unique key identifying the resource instance.</param>
/// <returns>A dictionary where the keys are permission names and the values are booleans indicating whether the permission is granted.</returns>
public static async Task<IDictionary<string, bool>> GetPermissionsAsync<TResource>(
this IResourcePermissionStore resourcePermissionStore,
TResource resource,
object resourceKey
@ -23,10 +41,12 @@ public static class ResourcePermissionStoreExtensions
Check.NotNull(resource, nameof(resource));
Check.NotNull(resourceKey, nameof(resourceKey));
return resourcePermissionStore.GetGrantedPermissionsAsync(
var result = await resourcePermissionStore.GetPermissionsAsync(
typeof(TResource).FullName!,
resourceKey.ToString()!
);
return result.Result.ToDictionary(x => x.Key, x => x.Value == PermissionGrantResult.Granted);
}
/// <summary>

39
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionPopulator.cs

@ -0,0 +1,39 @@
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Authorization.Permissions.Resources;
public class ResourcePermissionPopulator : ITransientDependency
{
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
protected IResourcePermissionChecker ResourcePermissionChecker { get; }
public ResourcePermissionPopulator(IPermissionDefinitionManager permissionDefinitionManager, IResourcePermissionChecker resourcePermissionChecker)
{
PermissionDefinitionManager = permissionDefinitionManager;
ResourcePermissionChecker = resourcePermissionChecker;
}
public virtual async Task PopulateAsync(IHasResourcePermissions resource, string resourceName, string resourceKey)
{
Check.NotNull(resource, nameof(resource));
Check.NotNull(resource.ResourcePermissions, nameof(resource.ResourcePermissions));
Check.NotNullOrWhiteSpace(resourceName, nameof(resourceName));
Check.NotNullOrWhiteSpace(resourceKey, nameof(resourceKey));
var resopurcePermissionNames = (await PermissionDefinitionManager.GetResourcePermissionsAsync())
.Where(x => x.ResourceName == resourceName)
.Select(x => x.Name)
.ToArray();
var results = await ResourcePermissionChecker.IsGrantedAsync(resopurcePermissionNames, resourceName, resourceKey);
foreach (var resopurcePermission in resopurcePermissionNames)
{
var hasPermission = results.Result.TryGetValue(resopurcePermission, out var granted) &&
granted == PermissionGrantResult.Granted;
resource.ResourcePermissions[resopurcePermission] = hasPermission;
}
}
}

19
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityExtensions.cs

@ -0,0 +1,19 @@
using System.Collections.Generic;
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.Authorization.Permissions.Resources;
public static class EntityExtensions
{
public static string GetResourceName(this IEntity entity)
{
Check.NotNull(entity, nameof(entity));
return entity.GetType().FullName!;
}
public static string GetResourceKey(this IEntity entity)
{
Check.NotNull(entity, nameof(entity));
return entity.GetKeys().JoinAsString(",");
}
}

34
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionCheckerExtensions.cs

@ -1,4 +1,3 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
@ -14,11 +13,7 @@ public static class EntityResourcePermissionCheckerExtensions
/// <param name="permissionName">The name of the permission to check.</param>
/// <param name="entity">The entity for which the permission is being checked.</param>
/// <returns>A task that represents the asynchronous operation. The task result is a boolean indicating whether the permission is granted.</returns>
public static Task<bool> IsGrantedAsync<TEntity>(
this IResourcePermissionChecker resourcePermissionChecker,
string permissionName,
TEntity entity
)
public static Task<bool> IsGrantedAsync<TEntity>(this IResourcePermissionChecker resourcePermissionChecker, string permissionName, TEntity entity)
where TEntity : class, IEntity
{
Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker));
@ -27,31 +22,8 @@ public static class EntityResourcePermissionCheckerExtensions
return resourcePermissionChecker.IsGrantedAsync(
permissionName,
typeof(TEntity).FullName!,
entity.GetKeys().JoinAsString(",")
entity,
entity.GetResourceKey()
);
}
/// <summary>
/// Retrieves a dictionary of permissions and their granted status for the specified entity.
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <param name="resourcePermissionChecker">The resource permission checker instance.</param>
/// <param name="entity">The entity for which the permissions are being retrieved.</param>
/// <returns>A dictionary where the keys are permission names and the values are booleans indicating whether the permission is granted.</returns>
public static Task<IDictionary<string, bool>> GetPermissionsAsync<TEntity>(
this IResourcePermissionChecker resourcePermissionChecker,
TEntity entity
)
where TEntity : class, IEntity
{
Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker));
Check.NotNull(entity, nameof(entity));
return resourcePermissionChecker.GetPermissionsAsync(
typeof(TEntity).FullName!,
entity.GetKeys().JoinAsString(",")
);
}
}

5
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionRequirementHandler.cs

@ -1,4 +1,3 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Domain.Entities;
@ -21,8 +20,8 @@ public class EntityResourcePermissionRequirementHandler : AuthorizationHandler<R
return;
}
var resourceName = resource.GetType().FullName!;
var resourceKey = resource.GetKeys().JoinAsString(",");
var resourceName = resource.GetResourceName();
var resourceKey = resource.GetResourceKey();
if (await PermissionChecker.IsGrantedAsync(context.User, requirement.PermissionName, resourceName, resourceKey))
{
context.Succeed(requirement);

36
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Authorization/Permissions/Resources/EntityResourcePermissionStoreExtensions.cs

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
@ -15,7 +14,7 @@ public static class EntityResourcePermissionStoreExtensions
/// <param name="resourcePermissionStore">The resource permission store instance.</param>
/// <param name="entity">The entity for which the permissions are being checked.</param>
/// <returns>An array of granted permission names as strings.</returns>
public static Task<string[]> GetGrantedPermissionsAsync<TEntity>(
public static async Task<string[]> GetGrantedPermissionsAsync<TEntity>(
this IResourcePermissionStore resourcePermissionStore,
TEntity entity
)
@ -24,37 +23,28 @@ public static class EntityResourcePermissionStoreExtensions
Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore));
Check.NotNull(entity, nameof(entity));
return resourcePermissionStore.GetGrantedPermissionsAsync(
typeof(TEntity).FullName!,
entity.GetKeys().JoinAsString(",")
);
return (await GetPermissionsAsync(resourcePermissionStore, entity)).Where(x => x.Value).Select(x => x.Key).ToArray();
}
/// <summary>
/// Retrieves an array of granted entity IDs for a specific permission.
/// Retrieves a dictionary of permissions and their granted status for the specified entity.
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <typeparam name="TKey">The type of the entity's primary key.</typeparam>
/// <param name="resourcePermissionStore">The resource permission store instance.</param>
/// <param name="permissionName">The name of the permission to check.</param>
/// <returns>An array of entity IDs (of type <typeparamref name="TKey"/>) for which the permission is granted.</returns>
public static async Task<TKey[]> GetGrantedEntityIdsAsync<TEntity, TKey>(
/// <param name="entity">The entity for which the permissions are being retrieved.</param>
/// <returns>A dictionary where the keys are permission names and the values are booleans indicating whether the permission is granted.</returns>
public static async Task<IDictionary<string, bool>> GetPermissionsAsync<TEntity>(
this IResourcePermissionStore resourcePermissionStore,
string permissionName
TEntity entity
)
where TEntity : class, IEntity<TKey>
where TEntity : class, IEntity
{
Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore));
Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName));
Check.NotNull(entity, nameof(entity));
var keys = await resourcePermissionStore.GetGrantedResourceKeysAsync(
typeof(TEntity).FullName!,
permissionName
return await resourcePermissionStore.GetPermissionsAsync(
entity,
entity.GetResourceKey()
);
return keys
.Select(x => Convert.ChangeType(x, typeof(TKey)))
.Cast<TKey>()
.ToArray();
}
}

14
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs

@ -330,25 +330,15 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD
var permissionNames = permissions.Select(x => x.Name).ToArray();
var multiplePermissionWithGrantedProviders = new MultiplePermissionWithGrantedProviders(permissionNames);
var neededCheckPermissions = new List<PermissionDefinition>();
var resourcePermissions = await GetAvailablePermissionsAsync(resourceName);
foreach (var permission in resourcePermissions)
{
if (await SimpleStateCheckerManager.IsEnabledAsync(permission))
{
neededCheckPermissions.Add(permission);
}
}
if (!neededCheckPermissions.Any())
if (!resourcePermissions.Any())
{
return multiplePermissionWithGrantedProviders;
}
foreach (var provider in ManagementProviders)
{
permissionNames = neededCheckPermissions.Select(x => x.Name).ToArray();
permissionNames = resourcePermissions.Select(x => x.Name).ToArray();
var multiplePermissionValueProviderGrantInfo = await provider.CheckAsync(permissionNames, resourceName, resourceKey, providerName, providerKey);
foreach (var providerResultDict in multiplePermissionValueProviderGrantInfo.Result)

Loading…
Cancel
Save