mirror of https://github.com/abpframework/abp.git
13 changed files with 456 additions and 92 deletions
@ -1,61 +1,16 @@ |
|||||
using System.Collections.Generic; |
using System.Security.Claims; |
||||
using System.Threading.Tasks; |
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
namespace Volo.Abp.Authorization.Permissions.Resources; |
namespace Volo.Abp.Authorization.Permissions.Resources; |
||||
|
|
||||
public interface IResourcePermissionChecker |
public interface IResourcePermissionChecker |
||||
{ |
{ |
||||
/// <summary>
|
Task<bool> IsGrantedAsync([NotNull] string name, string resourceName, string resourceKey); |
||||
/// Checks if the given permission is granted for the given resource.
|
|
||||
/// </summary>
|
|
||||
/// <param name="permissionName">The name of the permission.</param>
|
|
||||
/// <param name="resourceName">The name of the resource.</param>
|
|
||||
/// <param name="resourceKey">Resource key</param>
|
|
||||
/// <returns>
|
|
||||
/// True if the permission is granted.
|
|
||||
/// </returns>
|
|
||||
Task<bool> IsGrantedAsync( |
|
||||
string permissionName, |
|
||||
string resourceName, |
|
||||
string resourceKey |
|
||||
); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets all permissions for the given resource.
|
|
||||
/// </summary>
|
|
||||
/// <param name="resourceName">Resource name</param>
|
|
||||
/// <param name="resourceKey">Resource key</param>
|
|
||||
/// <returns>
|
|
||||
/// A dictionary of permission names and their states.
|
|
||||
/// </returns>
|
|
||||
Task<IDictionary<string, bool>> 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>
|
Task<bool> IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, [NotNull] string name, string resourceName, string resourceKey); |
||||
/// Retrieves the keys of resources for which the specified permission is granted.
|
|
||||
/// </summary>
|
Task<MultiplePermissionGrantResult> IsGrantedAsync([NotNull] string[] names, string resourceName, string resourceKey); |
||||
/// <param name="resourceName">The name of the resource.</param>
|
|
||||
/// <param name="permissionName">The name of the permission.</param>
|
Task<MultiplePermissionGrantResult> IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, [NotNull] string[] names, string resourceName, string resourceKey); |
||||
/// <returns>
|
} |
||||
/// An array of resource keys where the specified permission is granted.
|
|
||||
/// </returns>
|
|
||||
Task<string[]> GetGrantedResourceKeysAsync( |
|
||||
string resourceName, |
|
||||
string permissionName |
|
||||
); |
|
||||
} |
|
||||
|
|||||
@ -0,0 +1,67 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
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>
|
||||
|
/// <returns>
|
||||
|
/// True if the permission is granted.
|
||||
|
/// </returns>
|
||||
|
Task<bool> IsGrantedAsync( |
||||
|
string name, |
||||
|
string resourceName, |
||||
|
string resourceKey |
||||
|
); |
||||
|
|
||||
|
Task<MultiplePermissionGrantResult> IsGrantedAsync( |
||||
|
string[] names, |
||||
|
string resourceName, |
||||
|
string resourceKey |
||||
|
); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets all permissions for the given resource.
|
||||
|
/// </summary>
|
||||
|
/// <param name="resourceName">Resource name</param>
|
||||
|
/// <param name="resourceKey">Resource key</param>
|
||||
|
/// <returns>
|
||||
|
/// A dictionary of permission names and their states.
|
||||
|
/// </returns>
|
||||
|
Task<IDictionary<string, bool>> 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,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<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,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<NullResourcePermissionStore> Logger { get; set; } |
||||
|
|
||||
|
public NullResourcePermissionStore() |
||||
|
{ |
||||
|
Logger = NullLogger<NullResourcePermissionStore>.Instance; |
||||
|
} |
||||
|
|
||||
|
public Task<bool> IsGrantedAsync(string name, string resourceName, string resourceKey) |
||||
|
{ |
||||
|
return TaskCache.FalseResult; |
||||
|
} |
||||
|
|
||||
|
public Task<MultiplePermissionGrantResult> IsGrantedAsync(string[] names, string resourceName, string resourceKey) |
||||
|
{ |
||||
|
return Task.FromResult(new MultiplePermissionGrantResult(names, PermissionGrantResult.Prohibited)); |
||||
|
} |
||||
|
|
||||
|
public Task<IDictionary<string, bool>> GetPermissionsAsync(string resourceName, string resourceKey) |
||||
|
{ |
||||
|
return Task.FromResult((IDictionary<string, bool>)new Dictionary<string, bool>()); |
||||
|
} |
||||
|
|
||||
|
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,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; |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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<PermissionGrantResult> CheckAsync(ResourcePermissionValueCheckContext context); |
||||
|
|
||||
|
public abstract Task<MultiplePermissionGrantResult> CheckAsync(ResourcePermissionValuesCheckContext context); |
||||
|
} |
||||
@ -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<PermissionDefinition> permissions, string resourceName, string resourceKey) |
||||
|
: this(permissions, null, resourceName, resourceKey) |
||||
|
{ |
||||
|
ResourceName = resourceName; |
||||
|
ResourceKey = resourceKey; |
||||
|
} |
||||
|
|
||||
|
public ResourcePermissionValuesCheckContext([NotNull] List<PermissionDefinition> permissions, ClaimsPrincipal? principal, string resourceName, string resourceKey) |
||||
|
: base(permissions, principal) |
||||
|
{ |
||||
|
ResourceName = resourceName; |
||||
|
ResourceKey = resourceKey; |
||||
|
} |
||||
|
} |
||||
@ -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<PermissionDefinition> StateCheckerManager { get; } |
||||
|
|
||||
|
public ResourcePermissionChecker( |
||||
|
ICurrentPrincipalAccessor principalAccessor, |
||||
|
IPermissionDefinitionManager permissionDefinitionManager, |
||||
|
ICurrentTenant currentTenant, |
||||
|
IResourcePermissionValueProviderManager permissionValueProviderManager, |
||||
|
ISimpleStateCheckerManager<PermissionDefinition> stateCheckerManager) |
||||
|
{ |
||||
|
PrincipalAccessor = principalAccessor; |
||||
|
PermissionDefinitionManager = permissionDefinitionManager; |
||||
|
CurrentTenant = currentTenant; |
||||
|
PermissionValueProviderManager = permissionValueProviderManager; |
||||
|
StateCheckerManager = stateCheckerManager; |
||||
|
} |
||||
|
|
||||
|
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.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<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.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; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue