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 JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions.Resources; |
|||
|
|||
public interface IResourcePermissionChecker |
|||
{ |
|||
/// <summary>
|
|||
/// 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 |
|||
); |
|||
Task<bool> IsGrantedAsync([NotNull] string name, 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="permissionName">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 permissionName |
|||
); |
|||
} |
|||
Task<bool> IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, [NotNull] string name, string resourceName, string resourceKey); |
|||
|
|||
Task<MultiplePermissionGrantResult> IsGrantedAsync([NotNull] string[] names, string resourceName, string resourceKey); |
|||
|
|||
Task<MultiplePermissionGrantResult> IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, [NotNull] string[] names, string resourceName, string resourceKey); |
|||
} |
|||
|
|||
@ -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