mirror of https://github.com/abpframework/abp.git
8 changed files with 503 additions and 15 deletions
@ -0,0 +1,80 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Authorization.Permissions.Resources; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.PermissionManagement.Identity; |
|||
|
|||
public class RoleResourcePermissionManagementProvider : ResourcePermissionManagementProvider |
|||
{ |
|||
public override string Name => RoleResourcePermissionValueProvider.ProviderName; |
|||
|
|||
protected IUserRoleFinder UserRoleFinder { get; } |
|||
|
|||
public RoleResourcePermissionManagementProvider( |
|||
IResourcePermissionGrantRepository resourcepPrmissionGrantRepository, |
|||
IGuidGenerator guidGenerator, |
|||
ICurrentTenant currentTenant, |
|||
IUserRoleFinder userRoleFinder) |
|||
: base( |
|||
resourcepPrmissionGrantRepository, |
|||
guidGenerator, |
|||
currentTenant) |
|||
{ |
|||
UserRoleFinder = userRoleFinder; |
|||
} |
|||
|
|||
public override async Task<PermissionValueProviderGrantInfo> CheckAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
var multipleGrantInfo = await CheckAsync(new[] { name }, resourceName, resourceKey, providerName, providerKey); |
|||
|
|||
return multipleGrantInfo.Result.Values.First(); |
|||
} |
|||
|
|||
public override async Task<MultiplePermissionValueProviderGrantInfo> CheckAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
using (ResourcePermissionGrantRepository.DisableTracking()) |
|||
{ |
|||
var multiplePermissionValueProviderGrantInfo = new MultiplePermissionValueProviderGrantInfo(names); |
|||
var resourcePermissionGrants = new List<ResourcePermissionGrant>(); |
|||
|
|||
if (providerName == Name) |
|||
{ |
|||
resourcePermissionGrants.AddRange(await ResourcePermissionGrantRepository.GetListAsync(names, resourceName, resourceKey, providerName, providerKey)); |
|||
} |
|||
|
|||
if (providerName == UserResourcePermissionValueProvider.ProviderName) |
|||
{ |
|||
var userId = Guid.Parse(providerKey); |
|||
var roleNames = await UserRoleFinder.GetRoleNamesAsync(userId); |
|||
|
|||
foreach (var roleName in roleNames) |
|||
{ |
|||
resourcePermissionGrants.AddRange(await ResourcePermissionGrantRepository.GetListAsync(names, resourceName, resourceKey, Name, roleName)); |
|||
} |
|||
} |
|||
|
|||
resourcePermissionGrants = resourcePermissionGrants.Distinct().ToList(); |
|||
if (!resourcePermissionGrants.Any()) |
|||
{ |
|||
return multiplePermissionValueProviderGrantInfo; |
|||
} |
|||
|
|||
foreach (var permissionName in names) |
|||
{ |
|||
var resourcePermissionGrant = resourcePermissionGrants.FirstOrDefault(x => x.Name == permissionName); |
|||
if (resourcePermissionGrant != null) |
|||
{ |
|||
multiplePermissionValueProviderGrantInfo.Result[permissionName] = new PermissionValueProviderGrantInfo(true, resourcePermissionGrant.ProviderKey); |
|||
} |
|||
} |
|||
|
|||
return multiplePermissionValueProviderGrantInfo; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using Volo.Abp.Authorization.Permissions.Resources; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.PermissionManagement.Identity; |
|||
|
|||
public class UserResourcePermissionManagementProvider : ResourcePermissionManagementProvider |
|||
{ |
|||
public override string Name => UserResourcePermissionValueProvider.ProviderName; |
|||
|
|||
public UserResourcePermissionManagementProvider( |
|||
IResourcePermissionGrantRepository resourcePermissionGrantRepository, |
|||
IGuidGenerator guidGenerator, |
|||
ICurrentTenant currentTenant) |
|||
: base( |
|||
resourcePermissionGrantRepository, |
|||
guidGenerator, |
|||
currentTenant) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.PermissionManagement; |
|||
|
|||
public interface IResourcePermissionManagementProvider : ISingletonDependency //TODO: Consider to remove this pre-assumption
|
|||
{ |
|||
string Name { get; } |
|||
|
|||
Task<PermissionValueProviderGrantInfo> CheckAsync( |
|||
[NotNull] string name, |
|||
[NotNull] string resourceName, |
|||
[NotNull] string resourceKey, |
|||
[NotNull] string providerName, |
|||
[NotNull] string providerKey |
|||
); |
|||
|
|||
Task<MultiplePermissionValueProviderGrantInfo> CheckAsync( |
|||
[NotNull] string[] names, |
|||
[NotNull] string resourceName, |
|||
[NotNull] string resourceKey, |
|||
[NotNull] string providerName, |
|||
[NotNull] string providerKey |
|||
); |
|||
|
|||
Task SetAsync( |
|||
[NotNull] string name, |
|||
[NotNull] string resourceName, |
|||
[NotNull] string resourceKey, |
|||
[NotNull] string providerKey, |
|||
bool isGranted |
|||
); |
|||
} |
|||
@ -0,0 +1,87 @@ |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.PermissionManagement; |
|||
|
|||
public abstract class ResourcePermissionManagementProvider : IResourcePermissionManagementProvider |
|||
{ |
|||
public abstract string Name { get; } |
|||
|
|||
protected IResourcePermissionGrantRepository ResourcePermissionGrantRepository { get; } |
|||
|
|||
protected IGuidGenerator GuidGenerator { get; } |
|||
|
|||
protected ICurrentTenant CurrentTenant { get; } |
|||
|
|||
protected ResourcePermissionManagementProvider( |
|||
IResourcePermissionGrantRepository resourcePermissionGrantRepository, |
|||
IGuidGenerator guidGenerator, |
|||
ICurrentTenant currentTenant) |
|||
{ |
|||
ResourcePermissionGrantRepository = resourcePermissionGrantRepository; |
|||
GuidGenerator = guidGenerator; |
|||
CurrentTenant = currentTenant; |
|||
} |
|||
|
|||
public virtual async Task<PermissionValueProviderGrantInfo> CheckAsync(string name, string resourceName,string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
var multiplePermissionValueProviderGrantInfo = await CheckAsync(new[] { name }, resourceName, resourceKey, providerName, providerKey); |
|||
|
|||
return multiplePermissionValueProviderGrantInfo.Result.First().Value; |
|||
} |
|||
|
|||
public virtual async Task<MultiplePermissionValueProviderGrantInfo> CheckAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
using (ResourcePermissionGrantRepository.DisableTracking()) |
|||
{ |
|||
var multiplePermissionValueProviderGrantInfo = new MultiplePermissionValueProviderGrantInfo(names); |
|||
if (providerName != Name) |
|||
{ |
|||
return multiplePermissionValueProviderGrantInfo; |
|||
} |
|||
|
|||
var resourcePermissionGrants = await ResourcePermissionGrantRepository.GetListAsync(names, resourceName, resourceKey, providerName, providerKey); |
|||
|
|||
foreach (var permissionName in names) |
|||
{ |
|||
var isGrant = resourcePermissionGrants.Any(x => x.Name == permissionName); |
|||
multiplePermissionValueProviderGrantInfo.Result[permissionName] = new PermissionValueProviderGrantInfo(isGrant, providerKey); |
|||
} |
|||
|
|||
return multiplePermissionValueProviderGrantInfo; |
|||
} |
|||
} |
|||
|
|||
public virtual Task SetAsync(string name, string resourceName,string resourceKey, string providerKey, bool isGranted) |
|||
{ |
|||
return isGranted |
|||
? GrantAsync(name, resourceName, resourceKey, providerKey) |
|||
: RevokeAsync(name, resourceName, resourceKey, providerKey); |
|||
} |
|||
|
|||
protected virtual async Task GrantAsync(string name, string resourceName, string resourceKey, string providerKey) |
|||
{ |
|||
var resourcePermissionGrants = await ResourcePermissionGrantRepository.FindAsync(name, resourceName, resourceKey, Name, providerKey); |
|||
if (resourcePermissionGrants != null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
resourcePermissionGrants = new ResourcePermissionGrant(GuidGenerator.Create(), name, resourceName, resourceKey, Name, providerKey, CurrentTenant.Id); |
|||
await ResourcePermissionGrantRepository.InsertAsync(resourcePermissionGrants, true); |
|||
} |
|||
|
|||
protected virtual async Task RevokeAsync(string name, string resourceName,string resourceKey, string providerKey) |
|||
{ |
|||
var resourcePermissionGrants = await ResourcePermissionGrantRepository.FindAsync(name, resourceName, resourceKey, Name, providerKey); |
|||
if (resourcePermissionGrants == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
await ResourcePermissionGrantRepository.DeleteAsync(resourcePermissionGrants, true); |
|||
} |
|||
} |
|||
@ -0,0 +1,257 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.SimpleStateChecking; |
|||
|
|||
namespace Volo.Abp.PermissionManagement; |
|||
|
|||
public class ResourcePermissionManager : IResourcePermissionManager, ISingletonDependency |
|||
{ |
|||
protected IResourcePermissionGrantRepository ResourcePermissionGrantRepository { get; } |
|||
|
|||
protected IPermissionDefinitionManager PermissionDefinitionManager { get; } |
|||
|
|||
protected ISimpleStateCheckerManager<PermissionDefinition> SimpleStateCheckerManager { get; } |
|||
|
|||
protected IGuidGenerator GuidGenerator { get; } |
|||
|
|||
protected ICurrentTenant CurrentTenant { get; } |
|||
|
|||
protected IReadOnlyList<IResourcePermissionManagementProvider> ManagementProviders => _lazyProviders.Value; |
|||
|
|||
protected PermissionManagementOptions Options { get; } |
|||
|
|||
protected IDistributedCache<ResourcePermissionGrantCacheItem> Cache { get; } |
|||
|
|||
private readonly Lazy<List<IResourcePermissionManagementProvider>> _lazyProviders; |
|||
|
|||
public ResourcePermissionManager( |
|||
IPermissionDefinitionManager permissionDefinitionManager, |
|||
ISimpleStateCheckerManager<PermissionDefinition> simpleStateCheckerManager, |
|||
IResourcePermissionGrantRepository resourcePermissionGrantRepository, |
|||
IServiceProvider serviceProvider, |
|||
IGuidGenerator guidGenerator, |
|||
IOptions<PermissionManagementOptions> options, |
|||
ICurrentTenant currentTenant, |
|||
IDistributedCache<ResourcePermissionGrantCacheItem> cache) |
|||
{ |
|||
GuidGenerator = guidGenerator; |
|||
CurrentTenant = currentTenant; |
|||
Cache = cache; |
|||
SimpleStateCheckerManager = simpleStateCheckerManager; |
|||
ResourcePermissionGrantRepository = resourcePermissionGrantRepository; |
|||
PermissionDefinitionManager = permissionDefinitionManager; |
|||
Options = options.Value; |
|||
|
|||
_lazyProviders = new Lazy<List<IResourcePermissionManagementProvider>>( |
|||
() => Options |
|||
.ResourceManagementProviders |
|||
.Select(c => serviceProvider.GetRequiredService(c) as IResourcePermissionManagementProvider) |
|||
.ToList(), |
|||
true |
|||
); |
|||
} |
|||
|
|||
public virtual async Task<PermissionWithGrantedProviders> GetAsync(string permissionName, string resourceName, string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(permissionName); |
|||
if (permission == null) |
|||
{ |
|||
return new PermissionWithGrantedProviders(permissionName, false); |
|||
} |
|||
|
|||
return await GetInternalAsync( |
|||
permission, |
|||
resourceName, |
|||
resourceKey, |
|||
providerName, |
|||
providerKey |
|||
); |
|||
} |
|||
|
|||
public virtual async Task<MultiplePermissionWithGrantedProviders> GetAsync(string[] permissionNames, string resourceName, string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
var permissions = new List<PermissionDefinition>(); |
|||
var undefinedPermissions = new List<string>(); |
|||
|
|||
foreach (var permissionName in permissionNames) |
|||
{ |
|||
var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(permissionName); |
|||
if (permission != null) |
|||
{ |
|||
permissions.Add(permission); |
|||
} |
|||
else |
|||
{ |
|||
undefinedPermissions.Add(permissionName); |
|||
} |
|||
} |
|||
|
|||
if (!permissions.Any()) |
|||
{ |
|||
return new MultiplePermissionWithGrantedProviders(undefinedPermissions.ToArray()); |
|||
} |
|||
|
|||
var result = await GetInternalAsync( |
|||
permissions.ToArray(), |
|||
resourceName, |
|||
resourceKey, |
|||
providerName, |
|||
providerKey |
|||
); |
|||
|
|||
foreach (var undefinedPermission in undefinedPermissions) |
|||
{ |
|||
result.Result.Add(new PermissionWithGrantedProviders(undefinedPermission, false)); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public virtual async Task<List<PermissionWithGrantedProviders>> GetAllAsync(string resourceName, string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
var permissionDefinitions = (await PermissionDefinitionManager.GetResourcePermissionsAsync()).ToArray(); |
|||
|
|||
var multiplePermissionWithGrantedProviders = await GetInternalAsync(permissionDefinitions, resourceName, resourceKey, providerName, providerKey); |
|||
|
|||
return multiplePermissionWithGrantedProviders.Result; |
|||
} |
|||
|
|||
public virtual async Task SetAsync(string permissionName, string resourceName, string resourceKey, string providerName, string providerKey, bool isGranted) |
|||
{ |
|||
var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(permissionName); |
|||
if (permission == null) |
|||
{ |
|||
/* Silently ignore undefined permissions, |
|||
maybe they were removed from dynamic permission definition store */ |
|||
return; |
|||
} |
|||
|
|||
if (!permission.IsEnabled || !await SimpleStateCheckerManager.IsEnabledAsync(permission)) |
|||
{ |
|||
//TODO: BusinessException
|
|||
throw new ApplicationException($"The resource permission named '{permission.Name}' is disabled!"); |
|||
} |
|||
|
|||
if (permission.Providers.Any() && !permission.Providers.Contains(providerName)) |
|||
{ |
|||
//TODO: BusinessException
|
|||
throw new ApplicationException($"The resource permission named '{permission.Name}' has not compatible with the provider named '{providerName}'"); |
|||
} |
|||
|
|||
if (!permission.MultiTenancySide.HasFlag(CurrentTenant.GetMultiTenancySide())) |
|||
{ |
|||
//TODO: BusinessException
|
|||
throw new ApplicationException($"The resource permission named '{permission.Name}' has multitenancy side '{permission.MultiTenancySide}' which is not compatible with the current multitenancy side '{CurrentTenant.GetMultiTenancySide()}'"); |
|||
} |
|||
|
|||
var currentGrantInfo = await GetInternalAsync(permission, resourceName, resourceKey, providerName, providerKey); |
|||
if (currentGrantInfo.IsGranted == isGranted) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var provider = ManagementProviders.FirstOrDefault(m => m.Name == providerName); |
|||
if (provider == null) |
|||
{ |
|||
//TODO: BusinessException
|
|||
throw new AbpException("Unknown permission management provider: " + providerName); |
|||
} |
|||
|
|||
await provider.SetAsync(permissionName, resourceName, resourceKey, providerKey, isGranted); |
|||
} |
|||
|
|||
public virtual async Task<ResourcePermissionGrant> UpdateProviderKeyAsync(ResourcePermissionGrant resourcePermissionGrant, string resourceName, string resourceKey, string providerKey) |
|||
{ |
|||
using (CurrentTenant.Change(resourcePermissionGrant.TenantId)) |
|||
{ |
|||
//Invalidating the cache for the old key
|
|||
await Cache.RemoveAsync( |
|||
ResourcePermissionGrantCacheItem.CalculateCacheKey( |
|||
resourcePermissionGrant.Name, |
|||
resourcePermissionGrant.ResourceName, |
|||
resourcePermissionGrant.ResourceKey, |
|||
resourcePermissionGrant.ProviderName, |
|||
resourcePermissionGrant.ProviderKey |
|||
) |
|||
); |
|||
} |
|||
|
|||
resourcePermissionGrant.ProviderKey = providerKey; |
|||
return await ResourcePermissionGrantRepository.UpdateAsync(resourcePermissionGrant, true); |
|||
} |
|||
|
|||
public virtual async Task DeleteAsync(string providerName, string resourceName, string resourceKey, string providerKey) |
|||
{ |
|||
var permissionGrants = await ResourcePermissionGrantRepository.GetListAsync(providerName, resourceName, resourceKey, providerKey); |
|||
foreach (var permissionGrant in permissionGrants) |
|||
{ |
|||
await ResourcePermissionGrantRepository.DeleteAsync(permissionGrant, true); |
|||
} |
|||
} |
|||
|
|||
protected virtual async Task<PermissionWithGrantedProviders> GetInternalAsync(PermissionDefinition permission, string resourceName, string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
var multiplePermissionWithGrantedProviders = await GetInternalAsync( |
|||
new[] { permission }, |
|||
resourceName, |
|||
resourceKey, |
|||
providerName, |
|||
providerKey |
|||
); |
|||
|
|||
return multiplePermissionWithGrantedProviders.Result.First(); |
|||
} |
|||
|
|||
protected virtual async Task<MultiplePermissionWithGrantedProviders> GetInternalAsync(PermissionDefinition[] permissions, string resourceName, string resourceKey, string providerName, string providerKey) |
|||
{ |
|||
var permissionNames = permissions.Select(x => x.Name).ToArray(); |
|||
var multiplePermissionWithGrantedProviders = new MultiplePermissionWithGrantedProviders(permissionNames); |
|||
|
|||
var neededCheckPermissions = new List<PermissionDefinition>(); |
|||
|
|||
foreach (var permission in permissions |
|||
.Where(x => x.IsEnabled) |
|||
.Where(x => x.MultiTenancySide.HasFlag(CurrentTenant.GetMultiTenancySide())) |
|||
.Where(x => !x.Providers.Any() || x.Providers.Contains(providerName))) |
|||
{ |
|||
if (await SimpleStateCheckerManager.IsEnabledAsync(permission)) |
|||
{ |
|||
neededCheckPermissions.Add(permission); |
|||
} |
|||
} |
|||
|
|||
if (!neededCheckPermissions.Any()) |
|||
{ |
|||
return multiplePermissionWithGrantedProviders; |
|||
} |
|||
|
|||
foreach (var provider in ManagementProviders) |
|||
{ |
|||
permissionNames = neededCheckPermissions.Select(x => x.Name).ToArray(); |
|||
var multiplePermissionValueProviderGrantInfo = await provider.CheckAsync(permissionNames, resourceName, resourceKey, providerName, providerKey); |
|||
|
|||
foreach (var providerResultDict in multiplePermissionValueProviderGrantInfo.Result) |
|||
{ |
|||
if (providerResultDict.Value.IsGranted) |
|||
{ |
|||
var permissionWithGrantedProvider = multiplePermissionWithGrantedProviders.Result |
|||
.First(x => x.Name == providerResultDict.Key); |
|||
|
|||
permissionWithGrantedProvider.IsGranted = true; |
|||
permissionWithGrantedProvider.Providers.Add(new PermissionValueProviderInfo(provider.Name, providerResultDict.Value.ProviderKey)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return multiplePermissionWithGrantedProviders; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue