mirror of https://github.com/abpframework/abp.git
20 changed files with 543 additions and 11 deletions
@ -0,0 +1,9 @@ |
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public interface IPermissionDefinitionContext |
|||
{ |
|||
PermissionDefinition GetOrNull(string name); |
|||
|
|||
void Add(params PermissionDefinition[] definitions); |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.Collections.Generic; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public interface IPermissionDefinitionManager |
|||
{ |
|||
[NotNull] |
|||
PermissionDefinition Get([NotNull] string name); |
|||
|
|||
IReadOnlyList<PermissionDefinition> GetAll(); |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public interface IPermissionDefinitionProvider |
|||
{ |
|||
void Define(IPermissionDefinitionContext context); |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
//TODO: Change fallback to inherit?
|
|||
|
|||
public interface IPermissionManager |
|||
{ |
|||
Task<bool> IsGrantedAsync([NotNull]string name); |
|||
|
|||
Task<bool> IsGrantedAsync([NotNull]string name, [NotNull] string providerName, [CanBeNull] string providerKey, bool fallback = true); |
|||
|
|||
Task<List<PermissionGrantInfo>> GetAllAsync(); |
|||
|
|||
Task<List<PermissionGrantInfo>> GetAllAsync([NotNull] string providerName, [CanBeNull] string providerKey, bool fallback = true); |
|||
|
|||
Task SetAsync([NotNull] string name, bool? isGranted, [NotNull] string providerName, [CanBeNull] string providerKey, bool forceToSet = false); |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public interface IPermissionStore |
|||
{ |
|||
Task<bool?> GetOrNullAsync([NotNull] string name, [CanBeNull] string providerName, [CanBeNull] string providerKey); |
|||
|
|||
Task SetAsync([NotNull] string name, bool isGranted, [CanBeNull] string providerName, [CanBeNull] string providerKey); |
|||
|
|||
Task<List<PermissionGrantInfo>> GetListAsync([CanBeNull] string providerName, [CanBeNull] string providerKey); |
|||
|
|||
Task DeleteAsync([NotNull] string name, [CanBeNull]string providerName, [CanBeNull]string providerKey); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public interface IPermissionValueProvider |
|||
{ |
|||
string Name { get; } |
|||
|
|||
Task<bool?> IsGrantedAsync([NotNull] PermissionDefinition permission, [CanBeNull] string providerKey); |
|||
|
|||
Task SetAsync([NotNull] PermissionDefinition permission, bool isGranted, [CanBeNull] string providerKey); |
|||
|
|||
Task ClearAsync([NotNull] PermissionDefinition permission, [CanBeNull] string providerKey); |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public class NullPermissionStore : IPermissionStore, ISingletonDependency |
|||
{ |
|||
public ILogger<NullPermissionStore> Logger { get; set; } |
|||
|
|||
public NullPermissionStore() |
|||
{ |
|||
Logger = NullLogger<NullPermissionStore>.Instance; |
|||
} |
|||
|
|||
public Task<bool?> GetOrNullAsync(string name, string providerName, string providerKey) |
|||
{ |
|||
return Task.FromResult((bool?)null); |
|||
} |
|||
|
|||
public Task SetAsync(string name, bool isGranted, string providerName, string providerKey) |
|||
{ |
|||
Logger.LogWarning($"Setting the grant value for {name} is not possible because current permission store is {nameof(NullPermissionStore)}"); |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
public Task<List<PermissionGrantInfo>> GetListAsync(string providerName, string providerKey) |
|||
{ |
|||
return Task.FromResult(new List<PermissionGrantInfo>()); |
|||
} |
|||
|
|||
public Task DeleteAsync(string name, string providerName, string providerKey) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public class PermissionDefinition |
|||
{ |
|||
/// <summary>
|
|||
/// Unique name of the permission.
|
|||
/// </summary>
|
|||
public string Name { get; } |
|||
|
|||
/// <summary>
|
|||
/// Parent of this permission if one exists.
|
|||
/// If set, this permission can be granted only if parent is granted.
|
|||
/// </summary>
|
|||
public PermissionDefinition Parent { get; private set; } |
|||
|
|||
//TODO: Add Properties dictionary for custom stuff
|
|||
|
|||
public PermissionDefinition(string name) |
|||
{ |
|||
Name = name; |
|||
} |
|||
|
|||
public PermissionDefinition CreateChild(string name) |
|||
{ |
|||
return new PermissionDefinition(name) {Parent = this}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public class PermissionDefinitionContext : IPermissionDefinitionContext |
|||
{ |
|||
protected Dictionary<string, PermissionDefinition> Permissions { get; } |
|||
|
|||
public PermissionDefinitionContext(Dictionary<string, PermissionDefinition> permissions) |
|||
{ |
|||
Permissions = permissions; |
|||
} |
|||
|
|||
public virtual PermissionDefinition GetOrNull(string name) |
|||
{ |
|||
return Permissions.GetOrDefault(name); |
|||
} |
|||
|
|||
public virtual IReadOnlyList<PermissionDefinition> GetAll() |
|||
{ |
|||
return Permissions.Values.ToImmutableList(); |
|||
} |
|||
|
|||
public virtual void Add(params PermissionDefinition[] definitions) |
|||
{ |
|||
if (definitions.IsNullOrEmpty()) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
foreach (var definition in definitions) |
|||
{ |
|||
Permissions[definition.Name] = definition; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,76 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using System.Linq; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public class PermissionDefinitionManager : IPermissionDefinitionManager, ISingletonDependency |
|||
{ |
|||
protected Lazy<List<IPermissionDefinitionProvider>> Providers { get; } |
|||
|
|||
protected Lazy<IDictionary<string, PermissionDefinition>> PermissionDefinitions { get; } |
|||
|
|||
protected PermissionOptions Options { get; } |
|||
|
|||
private readonly IServiceProvider _serviceProvider; |
|||
|
|||
public PermissionDefinitionManager( |
|||
IOptions<PermissionOptions> options, |
|||
IServiceProvider serviceProvider) |
|||
{ |
|||
_serviceProvider = serviceProvider; |
|||
Options = options.Value; |
|||
|
|||
Providers = new Lazy<List<IPermissionDefinitionProvider>>(CreatePermissionProviders, true); |
|||
PermissionDefinitions = new Lazy<IDictionary<string, PermissionDefinition>>(CreatePermissionDefinitions, true); |
|||
} |
|||
|
|||
public virtual PermissionDefinition Get(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var permission = GetOrNull(name); |
|||
|
|||
if (permission == null) |
|||
{ |
|||
throw new AbpException("Undefined permission: " + name); |
|||
} |
|||
|
|||
return permission; |
|||
} |
|||
|
|||
public virtual IReadOnlyList<PermissionDefinition> GetAll() |
|||
{ |
|||
return PermissionDefinitions.Value.Values.ToImmutableList(); |
|||
} |
|||
|
|||
public virtual PermissionDefinition GetOrNull(string name) |
|||
{ |
|||
return PermissionDefinitions.Value.GetOrDefault(name); |
|||
} |
|||
|
|||
protected virtual List<IPermissionDefinitionProvider> CreatePermissionProviders() |
|||
{ |
|||
return Options |
|||
.DefinitionProviders |
|||
.Select(p => _serviceProvider.GetRequiredService(p) as IPermissionDefinitionProvider) |
|||
.ToList(); |
|||
} |
|||
|
|||
protected virtual IDictionary<string, PermissionDefinition> CreatePermissionDefinitions() |
|||
{ |
|||
var permissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
foreach (var provider in Providers.Value) |
|||
{ |
|||
provider.Define(new PermissionDefinitionContext(permissions)); |
|||
} |
|||
|
|||
return permissions; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public abstract class PermissionDefinitionProvider : IPermissionDefinitionProvider, ISingletonDependency |
|||
{ |
|||
public abstract void Define(IPermissionDefinitionContext context); |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public class PermissionGrantInfo |
|||
{ |
|||
public string Name { get; } |
|||
|
|||
public bool IsGranted { get; } |
|||
|
|||
public PermissionGrantInfo([NotNull] string name, bool isGranted) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
Name = name; |
|||
IsGranted = isGranted; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,184 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public class PermissionManager : IPermissionManager, ISingletonDependency |
|||
{ |
|||
protected IPermissionDefinitionManager PermissionDefinitionManager { get; } |
|||
|
|||
protected Lazy<List<IPermissionValueProvider>> Providers { get; } |
|||
|
|||
protected PermissionOptions Options { get; } |
|||
|
|||
protected IPermissionStore PermissionStore { get; } |
|||
|
|||
public PermissionManager( |
|||
IOptions<PermissionOptions> options, |
|||
IServiceProvider serviceProvider, |
|||
IPermissionDefinitionManager permissionDefinitionManager, |
|||
IPermissionStore permissionStore) |
|||
{ |
|||
PermissionStore = permissionStore; |
|||
PermissionDefinitionManager = permissionDefinitionManager; |
|||
Options = options.Value; |
|||
|
|||
Providers = new Lazy<List<IPermissionValueProvider>>( |
|||
() => Options |
|||
.ValueProviders |
|||
.Select(c => serviceProvider.GetRequiredService(c) as IPermissionValueProvider) |
|||
.ToList(), |
|||
true |
|||
); |
|||
} |
|||
|
|||
public virtual Task<bool> IsGrantedAsync(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
return IsGrantedInternalAsync(name, null, null); |
|||
} |
|||
|
|||
public virtual Task<bool> IsGrantedAsync(string name, string providerName, string providerKey, bool fallback = true) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
Check.NotNull(providerName, nameof(providerName)); |
|||
|
|||
return IsGrantedInternalAsync(name, providerName, providerKey, fallback); |
|||
} |
|||
|
|||
public virtual async Task<bool> IsGrantedInternalAsync(string name, string providerName, string providerKey, bool fallback = true) |
|||
{ |
|||
var permission = PermissionDefinitionManager.Get(name); |
|||
var providers = Enumerable |
|||
.Reverse(Providers.Value); |
|||
|
|||
if (providerName != null) |
|||
{ |
|||
providers = providers.SkipWhile(c => c.Name != providerName); |
|||
} |
|||
|
|||
if (!fallback) |
|||
{ |
|||
providers = providers.TakeWhile(c => c.Name == providerName); |
|||
} |
|||
|
|||
foreach (var provider in providers) |
|||
{ |
|||
var value = await provider.IsGrantedAsync(permission, providerKey); |
|||
if (value != null) |
|||
{ |
|||
return value.Value; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
public virtual async Task<List<PermissionGrantInfo>> GetAllAsync() |
|||
{ |
|||
var permissionGrantInfos = new Dictionary<string, PermissionGrantInfo>(); |
|||
var permissionDefinitions = PermissionDefinitionManager.GetAll(); |
|||
|
|||
foreach (var provider in Providers.Value) |
|||
{ |
|||
foreach (var permission in permissionDefinitions) |
|||
{ |
|||
var value = await provider.IsGrantedAsync(permission, null); |
|||
if (value != null) |
|||
{ |
|||
permissionGrantInfos[permission.Name] = new PermissionGrantInfo(permission.Name, value.Value); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return permissionGrantInfos.Values.ToList(); |
|||
} |
|||
|
|||
public virtual async Task<List<PermissionGrantInfo>> GetAllAsync(string providerName, string providerKey, bool fallback = true) |
|||
{ |
|||
Check.NotNull(providerName, nameof(providerName)); |
|||
|
|||
var permissionGrantInfos = new Dictionary<string, PermissionGrantInfo>(); |
|||
var permissionDefinitions = PermissionDefinitionManager.GetAll(); |
|||
var providers = Enumerable.Reverse(Providers.Value) |
|||
.SkipWhile(c => c.Name != providerName); |
|||
|
|||
if (!fallback) |
|||
{ |
|||
providers = providers.TakeWhile(c => c.Name == providerName); |
|||
} |
|||
|
|||
var providerList = providers.Reverse().ToList(); |
|||
|
|||
if (providerList.Any()) |
|||
{ |
|||
foreach (var permission in permissionDefinitions) |
|||
{ |
|||
foreach (var provider in providerList) |
|||
{ |
|||
var value = await provider.IsGrantedAsync(permission, providerKey); |
|||
if (value != null) |
|||
{ |
|||
permissionGrantInfos[permission.Name] = new PermissionGrantInfo(permission.Name, value.Value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return permissionGrantInfos.Values.ToList(); |
|||
} |
|||
|
|||
public virtual async Task SetAsync(string name, bool? isGranted, string providerName, string providerKey, bool forceToSet = false) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
Check.NotNull(providerName, nameof(providerName)); |
|||
|
|||
var permission = PermissionDefinitionManager.Get(name); |
|||
|
|||
var providers = Enumerable |
|||
.Reverse(Providers.Value) |
|||
.SkipWhile(p => p.Name != providerName) |
|||
.ToList(); |
|||
|
|||
if (!providers.Any()) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (providers.Count > 1 && !forceToSet) |
|||
{ |
|||
//Clear the value if it's same as it's fallback value
|
|||
var fallbackValue = await IsGrantedInternalAsync(name, providers[1].Name, providerKey); |
|||
if (fallbackValue == isGranted) |
|||
{ |
|||
isGranted = null; |
|||
} |
|||
} |
|||
|
|||
providers = providers |
|||
.TakeWhile(p => p.Name == providerName) |
|||
.ToList(); //Getting list for case of there are more than one provider with same EntityType
|
|||
|
|||
if (isGranted == null) |
|||
{ |
|||
foreach (var provider in providers) |
|||
{ |
|||
await provider.ClearAsync(permission, providerKey); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
foreach (var provider in providers) |
|||
{ |
|||
await provider.SetAsync(permission, isGranted.Value, providerKey); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public static class PermissionManagerSyncExtensions |
|||
{ |
|||
//TODO: Add sync extension methods for all permission manager methods.
|
|||
//TODO: Also add sync extension methods for all value provider extensions.
|
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using Volo.Abp.Collections; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public class PermissionOptions |
|||
{ |
|||
public ITypeList<IPermissionDefinitionProvider> DefinitionProviders { get; } |
|||
|
|||
public ITypeList<IPermissionValueProvider> ValueProviders { get; } |
|||
|
|||
public PermissionOptions() |
|||
{ |
|||
DefinitionProviders = new TypeList<IPermissionDefinitionProvider>(); |
|||
ValueProviders = new TypeList<IPermissionValueProvider>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Authorization.Permissions |
|||
{ |
|||
public abstract class PermissionValueProvider : IPermissionValueProvider, ISingletonDependency |
|||
{ |
|||
public abstract string Name { get; } |
|||
|
|||
protected IPermissionStore PermissionStore { get; } |
|||
|
|||
protected PermissionValueProvider(IPermissionStore permissionStore) |
|||
{ |
|||
PermissionStore = permissionStore; |
|||
} |
|||
|
|||
public abstract Task<bool?> IsGrantedAsync(PermissionDefinition permission, string providerKey); |
|||
|
|||
public abstract Task SetAsync(PermissionDefinition permission, bool isGranted, string providerKey); |
|||
|
|||
public abstract Task ClearAsync(PermissionDefinition permission, string providerKey); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue