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