Browse Source

Added initial permission management infrastructure.

pull/206/head
Halil İbrahim Kalkan 9 years ago
parent
commit
b17a190264
  1. 9
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs
  2. 13
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs
  3. 7
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionProvider.cs
  4. 21
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionManager.cs
  5. 17
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionStore.cs
  6. 16
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs
  7. 39
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs
  8. 28
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs
  9. 38
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs
  10. 76
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionManager.cs
  11. 9
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionProvider.cs
  12. 19
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGrantInfo.cs
  13. 184
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionManager.cs
  14. 8
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionManagerSyncExtensions.cs
  15. 17
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionOptions.cs
  16. 23
      src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs
  17. 10
      src/Volo.Abp.Settings/Volo/Abp/Settings/NullSettingStore.cs
  18. 2
      src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs
  19. 12
      src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinitionManager.cs
  20. 6
      src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs

9
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs

@ -0,0 +1,9 @@
namespace Volo.Abp.Authorization.Permissions
{
public interface IPermissionDefinitionContext
{
PermissionDefinition GetOrNull(string name);
void Add(params PermissionDefinition[] definitions);
}
}

13
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs

@ -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();
}
}

7
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionProvider.cs

@ -0,0 +1,7 @@
namespace Volo.Abp.Authorization.Permissions
{
public interface IPermissionDefinitionProvider
{
void Define(IPermissionDefinitionContext context);
}
}

21
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionManager.cs

@ -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);
}
}

17
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionStore.cs

@ -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);
}
}

16
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs

@ -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);
}
}

39
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs

@ -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;
}
}
}

28
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs

@ -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};
}
}
}

38
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs

@ -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;
}
}
}
}

76
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionManager.cs

@ -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;
}
}
}

9
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionProvider.cs

@ -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);
}
}

19
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGrantInfo.cs

@ -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;
}
}
}

184
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionManager.cs

@ -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);
}
}
}
}
}

8
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionManagerSyncExtensions.cs

@ -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.
}
}

17
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionOptions.cs

@ -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>();
}
}
}

23
src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs

@ -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);
}
}

10
src/Volo.Abp.Settings/Volo/Abp/Settings/NullSettingStore.cs

@ -1,11 +1,20 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Settings namespace Volo.Abp.Settings
{ {
public class NullSettingStore : ISettingStore, ISingletonDependency public class NullSettingStore : ISettingStore, ISingletonDependency
{ {
public ILogger<NullSettingStore> Logger { get; set; }
public NullSettingStore()
{
Logger = NullLogger<NullSettingStore>.Instance;
}
public Task<string> GetOrNullAsync(string name, string providerName, string providerKey) public Task<string> GetOrNullAsync(string name, string providerName, string providerKey)
{ {
return Task.FromResult((string) null); return Task.FromResult((string) null);
@ -13,6 +22,7 @@ namespace Volo.Abp.Settings
public Task SetAsync(string name, string value, string providerName, string providerKey) public Task SetAsync(string name, string value, string providerName, string providerKey)
{ {
Logger.LogWarning($"Setting the value for {name} is not possible because current setting store is {nameof(NullSettingStore)}");
return Task.CompletedTask; return Task.CompletedTask;
} }

2
src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs

@ -30,6 +30,8 @@
/// </summary> /// </summary>
public object CustomData { get; set; } public object CustomData { get; set; }
//TODO: Add Properties dictionary for custom stuff (and remove CustomData)
public SettingDefinition( public SettingDefinition(
string name, string name,
string defaultValue = null, string defaultValue = null,

12
src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinitionManager.cs

@ -33,17 +33,17 @@ namespace Volo.Abp.Settings
{ {
Check.NotNull(name, nameof(name)); Check.NotNull(name, nameof(name));
var settingDefinition = GetOrNull(name); var setting = GetOrNull(name);
if (settingDefinition == null) if (setting == null)
{ {
throw new AbpException("Undefined setting: " + name); throw new AbpException("Undefined setting: " + name);
} }
return settingDefinition; return setting;
} }
public IReadOnlyList<SettingDefinition> GetAll() public virtual IReadOnlyList<SettingDefinition> GetAll()
{ {
return SettingDefinitions.Value.Values.ToImmutableList(); return SettingDefinitions.Value.Values.ToImmutableList();
} }
@ -53,7 +53,7 @@ namespace Volo.Abp.Settings
return SettingDefinitions.Value.GetOrDefault(name); return SettingDefinitions.Value.GetOrDefault(name);
} }
private List<ISettingDefinitionProvider> CreateSettingProviders() protected virtual List<ISettingDefinitionProvider> CreateSettingProviders()
{ {
return Options return Options
.DefinitionProviders .DefinitionProviders
@ -61,7 +61,7 @@ namespace Volo.Abp.Settings
.ToList(); .ToList();
} }
private IDictionary<string, SettingDefinition> CreateSettingDefinitions() protected virtual IDictionary<string, SettingDefinition> CreateSettingDefinitions()
{ {
var settings = new Dictionary<string, SettingDefinition>(); var settings = new Dictionary<string, SettingDefinition>();

6
src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs

@ -16,15 +16,11 @@ namespace Volo.Abp.Settings
protected SettingOptions Options { get; } protected SettingOptions Options { get; }
protected ISettingStore SettingStore { get; }
public SettingManager( public SettingManager(
IOptions<SettingOptions> options, IOptions<SettingOptions> options,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
ISettingDefinitionManager settingDefinitionManager, ISettingDefinitionManager settingDefinitionManager)
ISettingStore settingStore)
{ {
SettingStore = settingStore;
SettingDefinitionManager = settingDefinitionManager; SettingDefinitionManager = settingDefinitionManager;
Options = options.Value; Options = options.Value;

Loading…
Cancel
Save