mirror of https://github.com/abpframework/abp.git
committed by
GitHub
254 changed files with 7691 additions and 255 deletions
@ -0,0 +1,8 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public interface IHasResourcePermissions : IKeyedObject |
||||
|
{ |
||||
|
Dictionary<string, bool> ResourcePermissions { get; } |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using System.Security.Claims; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public interface IResourcePermissionChecker |
||||
|
{ |
||||
|
Task<bool> IsGrantedAsync( |
||||
|
string name, |
||||
|
string resourceName, |
||||
|
string resourceKey |
||||
|
); |
||||
|
|
||||
|
Task<bool> IsGrantedAsync( |
||||
|
ClaimsPrincipal? claimsPrincipal, |
||||
|
string name, |
||||
|
string resourceName, |
||||
|
string resourceKey |
||||
|
); |
||||
|
|
||||
|
Task<MultiplePermissionGrantResult> IsGrantedAsync( |
||||
|
string[] names, |
||||
|
string resourceName, |
||||
|
string resourceKey |
||||
|
); |
||||
|
|
||||
|
Task<MultiplePermissionGrantResult> IsGrantedAsync( |
||||
|
ClaimsPrincipal? claimsPrincipal, |
||||
|
string[] names, |
||||
|
string resourceName, |
||||
|
string resourceKey |
||||
|
); |
||||
|
} |
||||
@ -0,0 +1,83 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public interface IResourcePermissionStore |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Checks if the given permission is granted for the given resource.
|
||||
|
/// </summary>
|
||||
|
/// <param name="name">The name of the permission.</param>
|
||||
|
/// <param name="resourceName">The name of the resource.</param>
|
||||
|
/// <param name="resourceKey">Resource key</param>
|
||||
|
/// <param name="providerName">The name of the provider.</param>
|
||||
|
/// <param name="providerKey">The key of the provider.</param>
|
||||
|
/// <returns>
|
||||
|
/// True if the permission is granted.
|
||||
|
/// </returns>
|
||||
|
Task<bool> IsGrantedAsync( |
||||
|
string name, |
||||
|
string resourceName, |
||||
|
string resourceKey, |
||||
|
string providerName, |
||||
|
string providerKey |
||||
|
); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks if the given permissions are granted for the given resource.
|
||||
|
/// </summary>
|
||||
|
/// <param name="names">The name of the permissions.</param>
|
||||
|
/// <param name="resourceName">The name of the resource.</param>
|
||||
|
/// <param name="resourceKey">Resource key</param>
|
||||
|
/// <param name="providerName">The name of the provider.</param>
|
||||
|
/// <param name="providerKey">The key of the provider.</param>
|
||||
|
/// <returns>
|
||||
|
/// A <see cref="MultiplePermissionGrantResult"/> object containing the grant results for each permission.
|
||||
|
/// </returns>
|
||||
|
Task<MultiplePermissionGrantResult> IsGrantedAsync( |
||||
|
string[] names, |
||||
|
string resourceName, |
||||
|
string resourceKey, |
||||
|
string providerName, |
||||
|
string providerKey |
||||
|
); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets all permissions for the given resource.
|
||||
|
/// </summary>
|
||||
|
/// <param name="resourceName">Resource name</param>
|
||||
|
/// <param name="resourceKey">Resource key</param>
|
||||
|
/// <returns>
|
||||
|
/// A <see cref="MultiplePermissionGrantResult"/> object containing the grant results for each permission.
|
||||
|
/// </returns>
|
||||
|
Task<MultiplePermissionGrantResult> GetPermissionsAsync( |
||||
|
string resourceName, |
||||
|
string resourceKey |
||||
|
); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets all granted permissions for the given resource.
|
||||
|
/// </summary>
|
||||
|
/// <param name="resourceName">Resource name</param>
|
||||
|
/// <param name="resourceKey">Resource key</param>
|
||||
|
/// <returns>
|
||||
|
/// An array of granted permission names.
|
||||
|
/// </returns>
|
||||
|
Task<string[]> GetGrantedPermissionsAsync( |
||||
|
string resourceName, |
||||
|
string resourceKey |
||||
|
); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Retrieves the keys of resources for which the specified permission is granted.
|
||||
|
/// </summary>
|
||||
|
/// <param name="resourceName">The name of the resource.</param>
|
||||
|
/// <param name="name">The name of the permission.</param>
|
||||
|
/// <returns>
|
||||
|
/// An array of resource keys where the specified permission is granted.
|
||||
|
/// </returns>
|
||||
|
Task<string[]> GetGrantedResourceKeysAsync( |
||||
|
string resourceName, |
||||
|
string name |
||||
|
); |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public interface IResourcePermissionValueProvider |
||||
|
{ |
||||
|
string Name { get; } |
||||
|
|
||||
|
Task<PermissionGrantResult> CheckAsync(ResourcePermissionValueCheckContext context); |
||||
|
|
||||
|
Task<MultiplePermissionGrantResult> CheckAsync(ResourcePermissionValuesCheckContext context); |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public interface IResourcePermissionValueProviderManager |
||||
|
{ |
||||
|
IReadOnlyList<IResourcePermissionValueProvider> ValueProviders { get; } |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
using System; |
||||
|
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<NullResourcePermissionStore> Logger { get; set; } |
||||
|
|
||||
|
public NullResourcePermissionStore() |
||||
|
{ |
||||
|
Logger = NullLogger<NullResourcePermissionStore>.Instance; |
||||
|
} |
||||
|
|
||||
|
public Task<bool> IsGrantedAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) |
||||
|
{ |
||||
|
return TaskCache.FalseResult; |
||||
|
} |
||||
|
|
||||
|
public Task<MultiplePermissionGrantResult> IsGrantedAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) |
||||
|
{ |
||||
|
return Task.FromResult(new MultiplePermissionGrantResult(names, PermissionGrantResult.Prohibited)); |
||||
|
} |
||||
|
|
||||
|
public Task<MultiplePermissionGrantResult> GetPermissionsAsync(string resourceName, string resourceKey) |
||||
|
{ |
||||
|
return Task.FromResult(new MultiplePermissionGrantResult()); |
||||
|
} |
||||
|
|
||||
|
public Task<string[]> GetGrantedPermissionsAsync(string resourceName, string resourceKey) |
||||
|
{ |
||||
|
return Task.FromResult(Array.Empty<string>()); |
||||
|
} |
||||
|
|
||||
|
public Task<string[]> GetGrantedResourceKeysAsync(string resourceName, string name) |
||||
|
{ |
||||
|
return Task.FromResult(Array.Empty<string>()); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,34 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public static class ResourcePermissionCheckerExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Checks if a specific permission is granted for a resource with a given key.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TResource">The type of the resource.</typeparam>
|
||||
|
/// <param name="resourcePermissionChecker">The resource permission checker instance.</param>
|
||||
|
/// <param name="permissionName">The name of the permission to check.</param>
|
||||
|
/// <param name="resource">The resource instance to check permission 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 a boolean value indicating whether the permission is granted.</returns>
|
||||
|
public static Task<bool> IsGrantedAsync<TResource>( |
||||
|
this IResourcePermissionChecker resourcePermissionChecker, |
||||
|
string permissionName, |
||||
|
TResource resource, |
||||
|
object resourceKey |
||||
|
) |
||||
|
{ |
||||
|
Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); |
||||
|
Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); |
||||
|
Check.NotNull(resource, nameof(resource)); |
||||
|
Check.NotNull(resourceKey, nameof(resourceKey)); |
||||
|
|
||||
|
return resourcePermissionChecker.IsGrantedAsync( |
||||
|
permissionName, |
||||
|
typeof(TResource).FullName!, |
||||
|
resourceKey.ToString()! |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public class ResourcePermissionGrantInfo : PermissionGrantInfo |
||||
|
{ |
||||
|
public string ResourceName { get; } |
||||
|
|
||||
|
public string ResourceKey { get; } |
||||
|
|
||||
|
public ResourcePermissionGrantInfo( |
||||
|
string name, |
||||
|
bool isGranted, |
||||
|
string resourceName, |
||||
|
string resourceKey, |
||||
|
string? providerName = null, |
||||
|
string? providerKey = null) |
||||
|
: base(name, isGranted, providerName, providerKey) |
||||
|
{ |
||||
|
ResourceName = resourceName; |
||||
|
ResourceKey = resourceKey; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public static class ResourcePermissionStoreExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Retrieves the list of granted permissions for a specific resource with a given key.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TResource">The type of the resource.</typeparam>
|
||||
|
/// <param name="resourcePermissionStore">The resource permission store instance.</param>
|
||||
|
/// <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 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 |
||||
|
) |
||||
|
{ |
||||
|
Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); |
||||
|
Check.NotNull(resource, nameof(resource)); |
||||
|
Check.NotNull(resourceKey, nameof(resourceKey)); |
||||
|
|
||||
|
var result = await resourcePermissionStore.GetPermissionsAsync( |
||||
|
typeof(TResource).FullName!, |
||||
|
resourceKey.ToString()! |
||||
|
); |
||||
|
|
||||
|
return result.Result.ToDictionary(x => x.Key, x => x.Value == PermissionGrantResult.Granted); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Retrieves the keys of the resources granted a specific permission.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TResource">The type of the resource.</typeparam>
|
||||
|
/// <param name="resourcePermissionStore">The resource permission store instance.</param>
|
||||
|
/// <param name="resource">The resource instance to check granted permissions for.</param>
|
||||
|
/// <param name="permissionName">The name of the permission to check.</param>
|
||||
|
/// <returns>A task that represents the asynchronous operation. The task result contains an array of strings representing the granted resource keys.</returns>
|
||||
|
public static Task<string[]> GetGrantedResourceKeysAsync<TResource>( |
||||
|
this IResourcePermissionStore resourcePermissionStore, |
||||
|
TResource resource, |
||||
|
string permissionName |
||||
|
) |
||||
|
{ |
||||
|
Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); |
||||
|
Check.NotNull(resource, nameof(resource)); |
||||
|
Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); |
||||
|
|
||||
|
return resourcePermissionStore.GetGrantedResourceKeysAsync( |
||||
|
typeof(TResource).FullName!, |
||||
|
permissionName |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public class ResourcePermissionValueCheckContext : PermissionValueCheckContext |
||||
|
{ |
||||
|
public string ResourceName { get; } |
||||
|
|
||||
|
public string ResourceKey { get; } |
||||
|
|
||||
|
public ResourcePermissionValueCheckContext(PermissionDefinition permission, string resourceName, string resourceKey) |
||||
|
: this(permission, null, resourceName, resourceKey) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public ResourcePermissionValueCheckContext(PermissionDefinition permission, ClaimsPrincipal? principal, string resourceName, string resourceKey) |
||||
|
: base(permission, principal) |
||||
|
{ |
||||
|
ResourceName = resourceName; |
||||
|
ResourceKey = resourceKey; |
||||
|
} |
||||
|
} |
||||
@ -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 ResourcePermissionStore { get; } |
||||
|
|
||||
|
protected ResourcePermissionValueProvider(IResourcePermissionStore resourcePermissionStore) |
||||
|
{ |
||||
|
ResourcePermissionStore = resourcePermissionStore; |
||||
|
} |
||||
|
|
||||
|
public abstract Task<PermissionGrantResult> CheckAsync(ResourcePermissionValueCheckContext context); |
||||
|
|
||||
|
public abstract Task<MultiplePermissionGrantResult> CheckAsync(ResourcePermissionValuesCheckContext context); |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public class ResourcePermissionValuesCheckContext : PermissionValuesCheckContext |
||||
|
{ |
||||
|
public string ResourceName { get; } |
||||
|
|
||||
|
public string ResourceKey { get; } |
||||
|
|
||||
|
public ResourcePermissionValuesCheckContext(PermissionDefinition permission,string resourceName, string resourceKey) |
||||
|
: this([permission], null, resourceName, resourceKey) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
public ResourcePermissionValuesCheckContext(PermissionDefinition permission, ClaimsPrincipal? principal, string resourceName, string resourceKey) |
||||
|
: this([permission], principal, resourceName, resourceKey) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public ResourcePermissionValuesCheckContext(List<PermissionDefinition> permissions, string resourceName, string resourceKey) |
||||
|
: this(permissions, null, resourceName, resourceKey) |
||||
|
{ |
||||
|
ResourceName = resourceName; |
||||
|
ResourceKey = resourceKey; |
||||
|
} |
||||
|
|
||||
|
public ResourcePermissionValuesCheckContext(List<PermissionDefinition> permissions, ClaimsPrincipal? principal, string resourceName, string resourceKey) |
||||
|
: base(permissions, principal) |
||||
|
{ |
||||
|
ResourceName = resourceName; |
||||
|
ResourceKey = resourceKey; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization; |
||||
|
|
||||
|
public class ResourcePermissionRequirement : IAuthorizationRequirement |
||||
|
{ |
||||
|
public string PermissionName { get; } |
||||
|
|
||||
|
public ResourcePermissionRequirement([NotNull] string permissionName) |
||||
|
{ |
||||
|
Check.NotNull(permissionName, nameof(permissionName)); |
||||
|
|
||||
|
PermissionName = permissionName; |
||||
|
} |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return $"ResourcePermissionRequirement: {PermissionName}"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
namespace Microsoft.Extensions.DependencyInjection; |
||||
|
|
||||
|
public static class KeyedObjectResourcePermissionExtenstions |
||||
|
{ |
||||
|
public static IServiceCollection AddKeyedObjectResourcePermissionAuthorization(this IServiceCollection services) |
||||
|
{ |
||||
|
services.AddSingleton<IAuthorizationHandler, KeyedObjectResourcePermissionRequirementHandler>(); |
||||
|
return services; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public static class KeyedObjectResourcePermissionCheckerExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Checks if the specified permission is granted for the given resource.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TResource">The type of the object.</typeparam>
|
||||
|
/// <param name="resourcePermissionChecker">The resource permission checker instance.</param>
|
||||
|
/// <param name="permissionName">The name of the permission to check.</param>
|
||||
|
/// <param name="resource">The resource 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<TResource>(this IResourcePermissionChecker resourcePermissionChecker, string permissionName, TResource resource) |
||||
|
where TResource : class, IKeyedObject |
||||
|
{ |
||||
|
Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); |
||||
|
Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); |
||||
|
Check.NotNull(resource, nameof(resource)); |
||||
|
|
||||
|
return resourcePermissionChecker.IsGrantedAsync( |
||||
|
permissionName, |
||||
|
resource, |
||||
|
resource.GetObjectKey() ?? throw new AbpException("The resource doesn't have a key.") |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public class KeyedObjectResourcePermissionRequirementHandler : AuthorizationHandler<ResourcePermissionRequirement, IKeyedObject> |
||||
|
{ |
||||
|
protected readonly IResourcePermissionChecker PermissionChecker; |
||||
|
|
||||
|
public KeyedObjectResourcePermissionRequirementHandler(IResourcePermissionChecker permissionChecker) |
||||
|
{ |
||||
|
PermissionChecker = permissionChecker; |
||||
|
} |
||||
|
|
||||
|
protected override async Task HandleRequirementAsync( |
||||
|
AuthorizationHandlerContext context, |
||||
|
ResourcePermissionRequirement requirement, |
||||
|
IKeyedObject? resource) |
||||
|
{ |
||||
|
if (resource == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var resourceName = resource.GetType().FullName!; |
||||
|
var resourceKey = resource.GetObjectKey() ?? throw new AbpException("The resource doesn't have a key."); |
||||
|
|
||||
|
if (await PermissionChecker.IsGrantedAsync(context.User, requirement.PermissionName, resourceName, resourceKey)) |
||||
|
{ |
||||
|
context.Succeed(requirement); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public static class KeyedObjectResourcePermissionStoreExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Retrieves an array of granted permissions for a specific 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 checked.</param>
|
||||
|
/// <returns>An array of granted permission names as strings.</returns>
|
||||
|
public static async Task<string[]> GetGrantedPermissionsAsync<TResource>( |
||||
|
this IResourcePermissionStore resourcePermissionStore, |
||||
|
TResource resource |
||||
|
) |
||||
|
where TResource : class, IKeyedObject |
||||
|
{ |
||||
|
Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); |
||||
|
Check.NotNull(resource, nameof(resource)); |
||||
|
|
||||
|
return (await GetPermissionsAsync(resourcePermissionStore, resource)).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="TEntity">The type of the entity.</typeparam>
|
||||
|
/// <param name="resourcePermissionStore">The resource permission store 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 async Task<IDictionary<string, bool>> GetPermissionsAsync<TEntity>( |
||||
|
this IResourcePermissionStore resourcePermissionStore, |
||||
|
TEntity entity |
||||
|
) |
||||
|
where TEntity : class, IKeyedObject |
||||
|
{ |
||||
|
Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); |
||||
|
Check.NotNull(entity, nameof(entity)); |
||||
|
|
||||
|
return await resourcePermissionStore.GetPermissionsAsync( |
||||
|
entity, |
||||
|
entity.GetObjectKey() ?? throw new AbpException("The entity doesn't have a key.") |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,173 @@ |
|||||
|
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<PermissionDefinition> StateCheckerManager { get; } |
||||
|
protected IPermissionChecker PermissionChecker { get; } |
||||
|
|
||||
|
public ResourcePermissionChecker( |
||||
|
ICurrentPrincipalAccessor principalAccessor, |
||||
|
IPermissionDefinitionManager permissionDefinitionManager, |
||||
|
ICurrentTenant currentTenant, |
||||
|
IResourcePermissionValueProviderManager permissionValueProviderManager, |
||||
|
ISimpleStateCheckerManager<PermissionDefinition> stateCheckerManager, |
||||
|
IPermissionChecker permissionChecker) |
||||
|
{ |
||||
|
PrincipalAccessor = principalAccessor; |
||||
|
PermissionDefinitionManager = permissionDefinitionManager; |
||||
|
CurrentTenant = currentTenant; |
||||
|
PermissionValueProviderManager = permissionValueProviderManager; |
||||
|
StateCheckerManager = stateCheckerManager; |
||||
|
PermissionChecker = permissionChecker; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<bool> IsGrantedAsync(string name, string resourceName, string resourceKey) |
||||
|
{ |
||||
|
return await IsGrantedAsync(PrincipalAccessor.Principal, name, resourceName, resourceKey); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<bool> IsGrantedAsync( |
||||
|
ClaimsPrincipal? claimsPrincipal, |
||||
|
string name, |
||||
|
string resourceName, |
||||
|
string resourceKey) |
||||
|
{ |
||||
|
Check.NotNull(name, nameof(name)); |
||||
|
|
||||
|
var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(resourceName, 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<MultiplePermissionGrantResult> IsGrantedAsync(string[] names, string resourceName, string resourceKey) |
||||
|
{ |
||||
|
return await IsGrantedAsync(PrincipalAccessor.Principal, names, resourceName, resourceKey); |
||||
|
} |
||||
|
|
||||
|
public async Task<MultiplePermissionGrantResult> 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<PermissionDefinition>(); |
||||
|
foreach (var name in names) |
||||
|
{ |
||||
|
var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(resourceName, 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; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
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; } |
||||
|
protected IResourcePermissionStore ResourcePermissionStore { get; } |
||||
|
protected IPermissionChecker PermissionChecker { get; } |
||||
|
|
||||
|
public ResourcePermissionPopulator( |
||||
|
IPermissionDefinitionManager permissionDefinitionManager, |
||||
|
IResourcePermissionChecker resourcePermissionChecker, |
||||
|
IResourcePermissionStore resourcePermissionStore, |
||||
|
IPermissionChecker permissionChecker) |
||||
|
{ |
||||
|
PermissionDefinitionManager = permissionDefinitionManager; |
||||
|
ResourcePermissionChecker = resourcePermissionChecker; |
||||
|
ResourcePermissionStore = resourcePermissionStore; |
||||
|
PermissionChecker = permissionChecker; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task PopulateAsync<TResource>(TResource resource, string resourceName) |
||||
|
where TResource : IHasResourcePermissions |
||||
|
{ |
||||
|
await PopulateAsync([resource], resourceName); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task PopulateAsync<TResource>(List<TResource> resources, string resourceName) |
||||
|
where TResource : IHasResourcePermissions |
||||
|
{ |
||||
|
Check.NotNull(resources, nameof(resources)); |
||||
|
Check.NotNullOrWhiteSpace(resourceName, nameof(resourceName)); |
||||
|
|
||||
|
var resopurcePermissions = (await PermissionDefinitionManager.GetResourcePermissionsAsync()) |
||||
|
.Where(x => x.ResourceName == resourceName) |
||||
|
.ToArray(); |
||||
|
|
||||
|
foreach (var resource in resources) |
||||
|
{ |
||||
|
var resourceKey = resource.GetObjectKey(); |
||||
|
if (resourceKey.IsNullOrEmpty()) |
||||
|
{ |
||||
|
throw new AbpException("Resource key can not be null or empty."); |
||||
|
} |
||||
|
|
||||
|
var results = await ResourcePermissionChecker.IsGrantedAsync(resopurcePermissions.Select(x => x.Name).ToArray(), resourceName, resourceKey); |
||||
|
foreach (var resopurcePermission in resopurcePermissions) |
||||
|
{ |
||||
|
if (resource.ResourcePermissions == null) |
||||
|
{ |
||||
|
ObjectHelper.TrySetProperty(resource, x => x.ResourcePermissions, () => new Dictionary<string, bool>()); |
||||
|
} |
||||
|
|
||||
|
var hasPermission = results.Result.TryGetValue(resopurcePermission.Name, out var granted) && granted == PermissionGrantResult.Granted; |
||||
|
resource.ResourcePermissions![resopurcePermission.Name] = hasPermission; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public class ResourcePermissionValueProviderManager : IResourcePermissionValueProviderManager, ISingletonDependency |
||||
|
{ |
||||
|
public IReadOnlyList<IResourcePermissionValueProvider> ValueProviders => _lazyProviders.Value; |
||||
|
private readonly Lazy<List<IResourcePermissionValueProvider>> _lazyProviders; |
||||
|
|
||||
|
protected AbpPermissionOptions Options { get; } |
||||
|
protected IServiceProvider ServiceProvider { get; } |
||||
|
|
||||
|
public ResourcePermissionValueProviderManager( |
||||
|
IServiceProvider serviceProvider, |
||||
|
IOptions<AbpPermissionOptions> options) |
||||
|
{ |
||||
|
Options = options.Value; |
||||
|
ServiceProvider = serviceProvider; |
||||
|
|
||||
|
_lazyProviders = new Lazy<List<IResourcePermissionValueProvider>>(GetProviders, true); |
||||
|
} |
||||
|
|
||||
|
protected virtual List<IResourcePermissionValueProvider> GetProviders() |
||||
|
{ |
||||
|
var providers = Options |
||||
|
.ResourceValueProviders |
||||
|
.Select(type => (ServiceProvider.GetRequiredService(type) as IResourcePermissionValueProvider)!) |
||||
|
.ToList(); |
||||
|
|
||||
|
var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1); |
||||
|
if(multipleProviders != null) |
||||
|
{ |
||||
|
throw new AbpException($"Duplicate resource permission value provider name detected: {multipleProviders.Key}. Providers:{Environment.NewLine}{multipleProviders.Select(p => p.GetType().FullName!).JoinAsString(Environment.NewLine)}"); |
||||
|
} |
||||
|
|
||||
|
return providers; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public class RoleResourcePermissionValueProvider : ResourcePermissionValueProvider |
||||
|
{ |
||||
|
public const string ProviderName = "R"; |
||||
|
|
||||
|
public override string Name => ProviderName; |
||||
|
|
||||
|
public RoleResourcePermissionValueProvider(IResourcePermissionStore resourcePermissionStore) |
||||
|
: base(resourcePermissionStore) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public override async Task<PermissionGrantResult> CheckAsync(ResourcePermissionValueCheckContext context) |
||||
|
{ |
||||
|
var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray(); |
||||
|
|
||||
|
if (roles == null || !roles.Any()) |
||||
|
{ |
||||
|
return PermissionGrantResult.Undefined; |
||||
|
} |
||||
|
|
||||
|
foreach (var role in roles.Distinct()) |
||||
|
{ |
||||
|
if (await ResourcePermissionStore.IsGrantedAsync(context.Permission.Name, context.ResourceName, context.ResourceKey, Name, role)) |
||||
|
{ |
||||
|
return PermissionGrantResult.Granted; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return PermissionGrantResult.Undefined; |
||||
|
} |
||||
|
|
||||
|
public override async Task<MultiplePermissionGrantResult> CheckAsync(ResourcePermissionValuesCheckContext context) |
||||
|
{ |
||||
|
var permissionNames = context.Permissions.Select(x => x.Name).Distinct().ToList(); |
||||
|
Check.NotNullOrEmpty(permissionNames, nameof(permissionNames)); |
||||
|
|
||||
|
var result = new MultiplePermissionGrantResult(permissionNames.ToArray()); |
||||
|
|
||||
|
var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray(); |
||||
|
if (roles == null || !roles.Any()) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
foreach (var role in roles.Distinct()) |
||||
|
{ |
||||
|
var multipleResult = await ResourcePermissionStore.IsGrantedAsync(permissionNames.ToArray(), context.ResourceName, context.ResourceKey, Name, role); |
||||
|
|
||||
|
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; |
||||
|
permissionNames.RemoveAll(x => x == grantResult.Key); |
||||
|
} |
||||
|
|
||||
|
if (result.AllGranted || result.AllProhibited) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if (permissionNames.IsNullOrEmpty()) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
public class UserResourcePermissionValueProvider : ResourcePermissionValueProvider |
||||
|
{ |
||||
|
public const string ProviderName = "U"; |
||||
|
|
||||
|
public override string Name => ProviderName; |
||||
|
|
||||
|
public UserResourcePermissionValueProvider(IResourcePermissionStore resourcePermissionStore) |
||||
|
: base(resourcePermissionStore) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public override async Task<PermissionGrantResult> CheckAsync(ResourcePermissionValueCheckContext context) |
||||
|
{ |
||||
|
var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value; |
||||
|
|
||||
|
if (userId == null) |
||||
|
{ |
||||
|
return PermissionGrantResult.Undefined; |
||||
|
} |
||||
|
|
||||
|
return await ResourcePermissionStore.IsGrantedAsync(context.Permission.Name, context.ResourceName, context.ResourceKey, Name, userId) |
||||
|
? PermissionGrantResult.Granted |
||||
|
: PermissionGrantResult.Undefined; |
||||
|
} |
||||
|
|
||||
|
public override async Task<MultiplePermissionGrantResult> CheckAsync(ResourcePermissionValuesCheckContext context) |
||||
|
{ |
||||
|
var permissionNames = context.Permissions.Select(x => x.Name).Distinct().ToArray(); |
||||
|
Check.NotNullOrEmpty(permissionNames, nameof(permissionNames)); |
||||
|
|
||||
|
var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value; |
||||
|
if (userId == null) |
||||
|
{ |
||||
|
return new MultiplePermissionGrantResult(permissionNames); |
||||
|
} |
||||
|
|
||||
|
return await ResourcePermissionStore.IsGrantedAsync(permissionNames, context.ResourceName, context.ResourceKey, Name, userId); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
namespace Volo.Abp; |
||||
|
|
||||
|
public interface IKeyedObject |
||||
|
{ |
||||
|
string? GetObjectKey(); |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
|
||||
|
namespace Volo.Abp; |
||||
|
|
||||
|
public static class KeyedObjectHelper |
||||
|
{ |
||||
|
public static string EncodeCompositeKey(params object?[] keys) |
||||
|
{ |
||||
|
var raw = keys.JoinAsString("||"); |
||||
|
var bytes = Encoding.UTF8.GetBytes(raw); |
||||
|
var base64 = Convert.ToBase64String(bytes); |
||||
|
var base64Url = base64 |
||||
|
.Replace("+", "-") |
||||
|
.Replace("/", "_") |
||||
|
.TrimEnd('='); |
||||
|
|
||||
|
return base64Url; |
||||
|
} |
||||
|
|
||||
|
public static string DecodeCompositeKey(string encoded) |
||||
|
{ |
||||
|
var base64 = encoded |
||||
|
.Replace("-", "+") |
||||
|
.Replace("_", "/"); |
||||
|
|
||||
|
switch (encoded.Length % 4) |
||||
|
{ |
||||
|
case 2: base64 += "=="; break; |
||||
|
case 3: base64 += "="; break; |
||||
|
} |
||||
|
|
||||
|
var bytes = Convert.FromBase64String(base64); |
||||
|
var raw = Encoding.UTF8.GetString(bytes); |
||||
|
|
||||
|
return raw; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Authorization.Permissions.Resources; |
||||
|
using Volo.Abp.Authorization.TestServices.Resources; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization; |
||||
|
|
||||
|
public class ResourcePermissionChecker_Tests: AuthorizationTestBase |
||||
|
{ |
||||
|
private readonly IResourcePermissionChecker _resourcePermissionChecker; |
||||
|
|
||||
|
public ResourcePermissionChecker_Tests() |
||||
|
{ |
||||
|
_resourcePermissionChecker = GetRequiredService<IResourcePermissionChecker>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task IsGrantedAsync() |
||||
|
{ |
||||
|
(await _resourcePermissionChecker.IsGrantedAsync("MyResourcePermission5", TestEntityResource.ResourceName, TestEntityResource.ResourceKey5)).ShouldBe(true); |
||||
|
(await _resourcePermissionChecker.IsGrantedAsync("UndefinedResourcePermission", TestEntityResource.ResourceName, TestEntityResource.ResourceKey5)).ShouldBe(false); |
||||
|
(await _resourcePermissionChecker.IsGrantedAsync("MyResourcePermission8", TestEntityResource.ResourceName, TestEntityResource.ResourceKey5)).ShouldBe(false); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task IsGranted_Multiple_Result_Async() |
||||
|
{ |
||||
|
var result = await _resourcePermissionChecker.IsGrantedAsync(new [] |
||||
|
{ |
||||
|
"MyResourcePermission1", |
||||
|
"MyResourcePermission2", |
||||
|
"UndefinedPermission", |
||||
|
"MyResourcePermission3", |
||||
|
"MyResourcePermission4", |
||||
|
"MyResourcePermission5", |
||||
|
"MyResourcePermission8" |
||||
|
}, TestEntityResource.ResourceName, TestEntityResource.ResourceKey5); |
||||
|
|
||||
|
result.Result["MyResourcePermission1"].ShouldBe(PermissionGrantResult.Undefined); |
||||
|
result.Result["MyResourcePermission2"].ShouldBe(PermissionGrantResult.Prohibited); |
||||
|
result.Result["UndefinedPermission"].ShouldBe(PermissionGrantResult.Prohibited); |
||||
|
result.Result["MyResourcePermission3"].ShouldBe(PermissionGrantResult.Granted); |
||||
|
result.Result["MyResourcePermission4"].ShouldBe(PermissionGrantResult.Prohibited); |
||||
|
result.Result["MyResourcePermission5"].ShouldBe(PermissionGrantResult.Granted); |
||||
|
result.Result["MyResourcePermission8"].ShouldBe(PermissionGrantResult.Prohibited); |
||||
|
|
||||
|
result = await _resourcePermissionChecker.IsGrantedAsync(new [] |
||||
|
{ |
||||
|
"MyResourcePermission6", |
||||
|
}, TestEntityResource.ResourceName, TestEntityResource.ResourceKey6); |
||||
|
|
||||
|
result.Result["MyResourcePermission6"].ShouldBe(PermissionGrantResult.Granted); |
||||
|
|
||||
|
result = await _resourcePermissionChecker.IsGrantedAsync(new [] |
||||
|
{ |
||||
|
"MyResourcePermission7", |
||||
|
}, TestEntityResource.ResourceName, TestEntityResource.ResourceKey7); |
||||
|
result.Result["MyResourcePermission7"].ShouldBe(PermissionGrantResult.Granted); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Authorization.Permissions.Resources; |
||||
|
using Volo.Abp.Authorization.TestServices.Resources; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization; |
||||
|
|
||||
|
public class ResourcePermissionPopulator_Tests : AuthorizationTestBase |
||||
|
{ |
||||
|
private readonly ResourcePermissionPopulator _resourcePermissionPopulator; |
||||
|
|
||||
|
public ResourcePermissionPopulator_Tests() |
||||
|
{ |
||||
|
_resourcePermissionPopulator = GetRequiredService<ResourcePermissionPopulator>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task PopulateAsync() |
||||
|
{ |
||||
|
var testResourceObject = new TestEntityResource(TestEntityResource.ResourceKey5); |
||||
|
testResourceObject.ResourcePermissions.IsNullOrEmpty().ShouldBeTrue(); |
||||
|
|
||||
|
await _resourcePermissionPopulator.PopulateAsync<TestEntityResource>( |
||||
|
testResourceObject, |
||||
|
TestEntityResource.ResourceName |
||||
|
); |
||||
|
|
||||
|
testResourceObject.ResourcePermissions.ShouldNotBeNull(); |
||||
|
testResourceObject.ResourcePermissions.Count.ShouldBe(8); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission1"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission2"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission3"].ShouldBe(true); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission4"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission5"].ShouldBe(true); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission6"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission7"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission8"].ShouldBe(false); |
||||
|
|
||||
|
testResourceObject = new TestEntityResource(TestEntityResource.ResourceKey6); |
||||
|
testResourceObject.ResourcePermissions.IsNullOrEmpty().ShouldBeTrue(); |
||||
|
|
||||
|
await _resourcePermissionPopulator.PopulateAsync<TestEntityResource>( |
||||
|
testResourceObject, |
||||
|
TestEntityResource.ResourceName |
||||
|
); |
||||
|
|
||||
|
testResourceObject.ResourcePermissions.ShouldNotBeNull(); |
||||
|
testResourceObject.ResourcePermissions.Count.ShouldBe(8); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission1"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission2"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission3"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission4"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission5"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission6"].ShouldBe(true); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission7"].ShouldBe(false); |
||||
|
testResourceObject.ResourcePermissions["MyResourcePermission8"].ShouldBe(false); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Authorization.Permissions.Resources; |
||||
|
using Volo.Abp.Authorization.TestServices.Resources; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization; |
||||
|
|
||||
|
public class ResourcePermissionValueProviderManager_Tests: AuthorizationTestBase |
||||
|
{ |
||||
|
private readonly IResourcePermissionValueProviderManager _resourcePermissionValueProviderManager; |
||||
|
|
||||
|
public ResourcePermissionValueProviderManager_Tests() |
||||
|
{ |
||||
|
_resourcePermissionValueProviderManager = GetRequiredService<IResourcePermissionValueProviderManager>(); |
||||
|
} |
||||
|
|
||||
|
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
||||
|
{ |
||||
|
options.Services.Configure<AbpPermissionOptions>(permissionOptions => |
||||
|
{ |
||||
|
permissionOptions.ResourceValueProviders.Add<TestDuplicateResourcePermissionValueProvider>(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Throw_Exception_If_Duplicate_Provider_Name_Detected() |
||||
|
{ |
||||
|
var exception = Assert.Throws<AbpException>(() => |
||||
|
{ |
||||
|
var providers = _resourcePermissionValueProviderManager.ValueProviders; |
||||
|
}); |
||||
|
|
||||
|
exception.Message.ShouldBe($"Duplicate resource permission value provider name detected: TestResourcePermissionValueProvider1. Providers:{Environment.NewLine}{typeof(TestDuplicateResourcePermissionValueProvider).FullName}{Environment.NewLine}{typeof(TestResourcePermissionValueProvider1).FullName}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class TestDuplicateResourcePermissionValueProvider : ResourcePermissionValueProvider |
||||
|
{ |
||||
|
public TestDuplicateResourcePermissionValueProvider(IResourcePermissionStore permissionStore) : base(permissionStore) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public override string Name => "TestResourcePermissionValueProvider1"; |
||||
|
|
||||
|
public override Task<PermissionGrantResult> CheckAsync(ResourcePermissionValueCheckContext context) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public override Task<MultiplePermissionGrantResult> CheckAsync(ResourcePermissionValuesCheckContext context) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,48 @@ |
|||||
|
using Shouldly; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.TestServices.Resources; |
||||
|
|
||||
|
public class AuthorizationTestResourcePermissionDefinitionProvider : PermissionDefinitionProvider |
||||
|
{ |
||||
|
public override void Define(IPermissionDefinitionContext context) |
||||
|
{ |
||||
|
var getGroup = context.GetGroupOrNull("TestGroup"); |
||||
|
if (getGroup == null) |
||||
|
{ |
||||
|
getGroup = context.AddGroup("TestGroup"); |
||||
|
} |
||||
|
getGroup.AddPermission("TestEntityManagementPermission"); |
||||
|
getGroup.AddPermission("TestEntityManagementPermission2"); |
||||
|
|
||||
|
var permission1 = context.AddResourcePermission("MyResourcePermission1", resourceName: TestEntityResource.ResourceName, "TestEntityManagementPermission"); |
||||
|
Assert.Throws<AbpException>(() => |
||||
|
{ |
||||
|
permission1.AddChild("MyResourcePermission1.ChildPermission1"); |
||||
|
}).Message.ShouldBe($"Resource permission cannot have child permissions. Resource: {TestEntityResource.ResourceName}"); |
||||
|
permission1.StateCheckers.Add(new TestRequireEditionPermissionSimpleStateChecker());; |
||||
|
permission1[PermissionDefinitionContext.KnownPropertyNames.CurrentProviderName].ShouldBe(typeof(AuthorizationTestResourcePermissionDefinitionProvider).FullName); |
||||
|
|
||||
|
context.AddResourcePermission("MyResourcePermission2", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); |
||||
|
context.AddResourcePermission("MyResourcePermission3", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); |
||||
|
context.AddResourcePermission("MyResourcePermission4", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); |
||||
|
context.AddResourcePermission("MyResourcePermission5", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); |
||||
|
context.AddResourcePermission("MyResourcePermission6", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission").WithProviders(nameof(TestResourcePermissionValueProvider1)); |
||||
|
context.AddResourcePermission("MyResourcePermission7", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission").WithProviders(nameof(TestResourcePermissionValueProvider2)); |
||||
|
context.AddResourcePermission("MyResourcePermission8", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission2"); |
||||
|
|
||||
|
Assert.Throws<AbpException>(() => |
||||
|
{ |
||||
|
context.AddResourcePermission("MyResourcePermission7", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); |
||||
|
}).Message.ShouldBe($"There is already an existing resource permission with name: MyResourcePermission7 for resource: {typeof(TestEntityResource).FullName}"); |
||||
|
|
||||
|
context.AddResourcePermission("MyResourcePermission7", resourceName: typeof(TestEntityResource2).FullName!, "TestEntityManagementPermission").WithProviders(nameof(TestResourcePermissionValueProvider2)); |
||||
|
|
||||
|
context.GetResourcePermissionOrNull(TestEntityResource.ResourceName, "MyResourcePermission1").ShouldNotBeNull(); |
||||
|
context.GetResourcePermissionOrNull(TestEntityResource.ResourceName, "MyResourcePermission7").ShouldNotBeNull(); |
||||
|
context.GetResourcePermissionOrNull(TestEntityResource2.ResourceName, "MyResourcePermission7").ShouldNotBeNull(); |
||||
|
context.GetResourcePermissionOrNull(TestEntityResource.ResourceName, "MyResourcePermission9").ShouldBeNull(); |
||||
|
context.GetResourcePermissionOrNull(TestEntityResource2.ResourceName, "MyResourcePermission6").ShouldBeNull(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Authorization.Permissions.Resources; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.TestServices.Resources; |
||||
|
|
||||
|
public class FakeResourcePermissionStore : IResourcePermissionStore, ITransientDependency |
||||
|
{ |
||||
|
public Task<bool> IsGrantedAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) |
||||
|
{ |
||||
|
return Task.FromResult((name == "MyResourcePermission3" || name == "MyResourcePermission5") && |
||||
|
resourceName == TestEntityResource.ResourceName && |
||||
|
(resourceKey == TestEntityResource.ResourceKey3 || resourceKey == TestEntityResource.ResourceKey5)); |
||||
|
} |
||||
|
|
||||
|
public Task<MultiplePermissionGrantResult> IsGrantedAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) |
||||
|
{ |
||||
|
var result = new MultiplePermissionGrantResult(); |
||||
|
foreach (var name in names) |
||||
|
{ |
||||
|
result.Result.Add(name, ((name == "MyResourcePermission3" || name == "MyResourcePermission5") && |
||||
|
resourceName == TestEntityResource.ResourceName && |
||||
|
(resourceKey == TestEntityResource.ResourceKey3 || resourceKey == TestEntityResource.ResourceKey5) |
||||
|
? PermissionGrantResult.Granted |
||||
|
: PermissionGrantResult.Prohibited)); |
||||
|
} |
||||
|
|
||||
|
return Task.FromResult(result); |
||||
|
} |
||||
|
|
||||
|
public Task<MultiplePermissionGrantResult> GetPermissionsAsync(string resourceName, string resourceKey) |
||||
|
{ |
||||
|
throw new System.NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public Task<string[]> GetGrantedPermissionsAsync(string resourceName, string resourceKey) |
||||
|
{ |
||||
|
throw new System.NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public Task<string[]> GetGrantedResourceKeysAsync(string resourceName, string name) |
||||
|
{ |
||||
|
throw new System.NotImplementedException(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.TestServices.Resources; |
||||
|
|
||||
|
public class TestEntityResource : IHasResourcePermissions |
||||
|
{ |
||||
|
public static readonly string ResourceName = typeof(TestEntityResource).FullName; |
||||
|
|
||||
|
public static readonly string ResourceKey1 = Guid.NewGuid().ToString(); |
||||
|
public static readonly string ResourceKey2 = Guid.NewGuid().ToString(); |
||||
|
public static readonly string ResourceKey3 = Guid.NewGuid().ToString(); |
||||
|
public static readonly string ResourceKey4 = Guid.NewGuid().ToString(); |
||||
|
public static readonly string ResourceKey5 = Guid.NewGuid().ToString(); |
||||
|
public static readonly string ResourceKey6 = Guid.NewGuid().ToString(); |
||||
|
public static readonly string ResourceKey7 = Guid.NewGuid().ToString(); |
||||
|
|
||||
|
private string Id { get; } |
||||
|
|
||||
|
public TestEntityResource(string id) |
||||
|
{ |
||||
|
Id = id; |
||||
|
} |
||||
|
|
||||
|
public string GetObjectKey() |
||||
|
{ |
||||
|
return Id; |
||||
|
} |
||||
|
|
||||
|
public Dictionary<string, bool> ResourcePermissions { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class TestEntityResource2 |
||||
|
{ |
||||
|
public static readonly string ResourceName = typeof(TestEntityResource2).FullName; |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.TestServices.Resources; |
||||
|
|
||||
|
public class TestResourcePermissionValueProvider1 : ResourcePermissionValueProvider |
||||
|
{ |
||||
|
public TestResourcePermissionValueProvider1(IResourcePermissionStore permissionStore) : base(permissionStore) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public override string Name => "TestResourcePermissionValueProvider1"; |
||||
|
|
||||
|
public override Task<PermissionGrantResult> CheckAsync(ResourcePermissionValueCheckContext context) |
||||
|
{ |
||||
|
var result = PermissionGrantResult.Undefined; |
||||
|
if (context.Permission.Name == "MyResourcePermission6" && |
||||
|
context.ResourceName == TestEntityResource.ResourceName && |
||||
|
context.ResourceKey == TestEntityResource.ResourceKey6) |
||||
|
{ |
||||
|
result = PermissionGrantResult.Granted; |
||||
|
} |
||||
|
|
||||
|
return Task.FromResult(result); |
||||
|
} |
||||
|
|
||||
|
public override Task<MultiplePermissionGrantResult> CheckAsync(ResourcePermissionValuesCheckContext context) |
||||
|
{ |
||||
|
var result = new MultiplePermissionGrantResult(); |
||||
|
foreach (var name in context.Permissions.Select(x => x.Name)) |
||||
|
{ |
||||
|
result.Result.Add(name, name == "MyResourcePermission6" && |
||||
|
context.ResourceName == TestEntityResource.ResourceName && |
||||
|
context.ResourceKey == TestEntityResource.ResourceKey6 |
||||
|
? PermissionGrantResult.Granted |
||||
|
: PermissionGrantResult.Undefined); |
||||
|
} |
||||
|
|
||||
|
return Task.FromResult(result); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.TestServices.Resources; |
||||
|
|
||||
|
public class TestResourcePermissionValueProvider2 : ResourcePermissionValueProvider |
||||
|
{ |
||||
|
public TestResourcePermissionValueProvider2(IResourcePermissionStore permissionStore) : base(permissionStore) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public override string Name => "TestResourcePermissionValueProvider2"; |
||||
|
|
||||
|
public override Task<PermissionGrantResult> CheckAsync(ResourcePermissionValueCheckContext context) |
||||
|
{ |
||||
|
var result = PermissionGrantResult.Undefined; |
||||
|
if (context.Permission.Name == "MyResourcePermission7" && |
||||
|
context.ResourceName == TestEntityResource.ResourceName && |
||||
|
context.ResourceKey == TestEntityResource.ResourceKey7) |
||||
|
{ |
||||
|
result = PermissionGrantResult.Granted; |
||||
|
} |
||||
|
|
||||
|
return Task.FromResult(result); |
||||
|
} |
||||
|
|
||||
|
public override Task<MultiplePermissionGrantResult> CheckAsync(ResourcePermissionValuesCheckContext context) |
||||
|
{ |
||||
|
var result = new MultiplePermissionGrantResult(); |
||||
|
foreach (var name in context.Permissions.Select(x => x.Name)) |
||||
|
{ |
||||
|
result.Result.Add(name, name == "MyResourcePermission7" && |
||||
|
context.ResourceName == TestEntityResource.ResourceName && |
||||
|
context.ResourceKey == TestEntityResource.ResourceKey7 |
||||
|
? PermissionGrantResult.Granted |
||||
|
: PermissionGrantResult.Undefined); |
||||
|
} |
||||
|
|
||||
|
return Task.FromResult(result); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
using System; |
||||
|
using Shouldly; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp; |
||||
|
|
||||
|
public class KeyedObjectHelper_Tests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void EncodeCompositeKey() |
||||
|
{ |
||||
|
var encoded = KeyedObjectHelper.EncodeCompositeKey("Book", "123"); |
||||
|
encoded.ShouldBe("Qm9va3x8MTIz"); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void DecodeCompositeKey() |
||||
|
{ |
||||
|
var decoded = KeyedObjectHelper.DecodeCompositeKey("Qm9va3x8MTIz"); |
||||
|
decoded.ShouldBe("Book||123"); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Encode_Decode_CompositeKey() |
||||
|
{ |
||||
|
var encoded = KeyedObjectHelper.EncodeCompositeKey("User", 42, Guid.Empty); |
||||
|
var decoded = KeyedObjectHelper.DecodeCompositeKey(encoded); |
||||
|
|
||||
|
decoded.ShouldBe($"User||42||{Guid.Empty}"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
namespace Volo.Abp.Identity; |
||||
|
|
||||
|
public class RoleLookupCountInputDto |
||||
|
{ |
||||
|
public string Filter { get; set; } |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
using Volo.Abp.Application.Dtos; |
||||
|
|
||||
|
namespace Volo.Abp.Identity; |
||||
|
|
||||
|
public class RoleLookupSearchInputDto : ExtensiblePagedAndSortedResultRequestDto |
||||
|
{ |
||||
|
public string Filter { get; set; } |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue