Browse Source

Refactored permission state provider system

pull/8543/head
Halil İbrahim Kalkan 5 years ago
parent
commit
0399035996
  1. 3
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs
  2. 29
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs
  3. 12
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs
  4. 31
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProvider.cs
  5. 15
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs
  6. 20
      framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs
  7. 21
      framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs
  8. 21
      framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs
  9. 24
      framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs
  10. 2
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs
  11. 2
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs

3
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs

@ -31,6 +31,8 @@ namespace Volo.Abp.Authorization.Permissions
/// </summary>
public List<string> Providers { get; } //TODO: Rename to AllowedProviders?
public List<IPermissionStateProvider> StateProviders { get; }
public ILocalizableString DisplayName
{
get => _displayName;
@ -86,6 +88,7 @@ namespace Volo.Abp.Authorization.Permissions
Properties = new Dictionary<string, object>();
Providers = new List<string>();
StateProviders = new List<IPermissionStateProvider>();
_children = new List<PermissionDefinition>();
}

29
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs

@ -1,34 +1,19 @@
using System.Collections.Generic;
using JetBrains.Annotations;
using JetBrains.Annotations;
namespace Volo.Abp.Authorization.Permissions
{
public static class PermissionDefinitionExtensions
{
public const string PropertyName = "_AbpPermissionStateProviders";
public static PermissionDefinition AddStateProvider(
public static PermissionDefinition AddStateProviders(
[NotNull] this PermissionDefinition permissionDefinition,
[NotNull] params IPermissionStateProvider[] permissionStateProviders)
{
var stateProviders = permissionDefinition.GetStateProvidersInternal();
foreach (var provider in permissionStateProviders)
{
stateProviders.AddIfNotContains(provider);
}
Check.NotNull(permissionDefinition, nameof(permissionDefinition));
Check.NotNull(permissionStateProviders, nameof(permissionStateProviders));
permissionDefinition.StateProviders.AddRange(permissionStateProviders);
return permissionDefinition;
}
public static IReadOnlyList<IPermissionStateProvider> GetStateProviders([NotNull] this PermissionDefinition permissionDefinition)
{
return permissionDefinition.GetStateProvidersInternal();
}
private static List<IPermissionStateProvider> GetStateProvidersInternal([NotNull] this PermissionDefinition permissionDefinition)
{
return (List<IPermissionStateProvider>) permissionDefinition.Properties.GetOrAdd(PropertyName, () => new List<IPermissionStateProvider>());
}
}
}

12
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs

@ -25,18 +25,14 @@ namespace Volo.Abp.Authorization.Permissions
var context = new PermissionStateContext
{
Permission = permission,
ServiceProvider = scope.ServiceProvider
ServiceProvider = scope.ServiceProvider.GetRequiredService<ICachedServiceProvider>()
};
var providers = permission.GetStateProviders();
if (providers != null && providers.Any())
foreach (var provider in permission.StateProviders)
{
foreach (var provider in providers)
if (!await provider.IsEnabledAsync(context))
{
if (!await provider.IsEnabledAsync(context))
{
return false;
}
return false;
}
}

31
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProvider.cs

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.DependencyInjection
{
[ExposeServices(typeof(ICachedServiceProvider))]
public class CachedServiceProvider : ICachedServiceProvider, IScopedDependency
{
protected IServiceProvider ServiceProvider { get; }
protected IDictionary<Type, object> CachedServices { get; }
public CachedServiceProvider(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
CachedServices = new Dictionary<Type, object>
{
{typeof(IServiceProvider), serviceProvider}
};
}
public object GetService(Type serviceType)
{
return CachedServices.GetOrAdd(
serviceType,
() => ServiceProvider.GetService(serviceType)
);
}
}
}

15
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs

@ -0,0 +1,15 @@
using System;
namespace Volo.Abp.DependencyInjection
{
/// <summary>
/// Provides services by caching the resolved services.
/// It caches all type of services including transients.
/// This service's lifetime is scoped and it should be used
/// for a limited scope.
/// </summary>
public interface ICachedServiceProvider : IServiceProvider
{
}
}

20
framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs

@ -1,14 +1,28 @@
using Volo.Abp.Authorization.Permissions;
using JetBrains.Annotations;
using Volo.Abp.Authorization.Permissions;
namespace Volo.Abp.Features
{
public static class FeatureDefinitionExtensions
{
public static PermissionDefinition RequireFeatures(this PermissionDefinition permissionDefinition, params string[] features)
public static PermissionDefinition RequireFeatures(
[NotNull] this PermissionDefinition permissionDefinition,
params string[] features)
{
return permissionDefinition.RequireFeatures(true, features);
}
public static PermissionDefinition RequireFeatures(
[NotNull] this PermissionDefinition permissionDefinition,
bool requiresAll,
params string[] features)
{
Check.NotNull(permissionDefinition, nameof(permissionDefinition));
Check.NotNullOrEmpty(features, nameof(features));
return permissionDefinition.AddStateProvider(new RequireFeaturesPermissionStateProvider(features));
return permissionDefinition.AddStateProviders(
new RequireFeaturesPermissionStateProvider(requiresAll, features)
);
}
}
}

21
framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
@ -7,19 +6,27 @@ namespace Volo.Abp.Features
{
public class RequireFeaturesPermissionStateProvider : IPermissionStateProvider
{
private readonly List<string> _requireFeatures = new List<string>();
private readonly string[] _featureNames;
private readonly bool _requiresAll;
public RequireFeaturesPermissionStateProvider(params string[] requireFeatures)
public RequireFeaturesPermissionStateProvider(params string[] featureNames)
: this(true, featureNames)
{
Check.NotNullOrEmpty(requireFeatures, nameof(requireFeatures));
}
public RequireFeaturesPermissionStateProvider(bool requiresAll, params string[] featureNames)
{
Check.NotNullOrEmpty(featureNames, nameof(featureNames));
_requireFeatures.AddRange(requireFeatures);
_requiresAll = requiresAll;
_featureNames = featureNames;
}
public async Task<bool> IsEnabledAsync(PermissionStateContext context)
{
var feature = context.ServiceProvider.GetRequiredService<IFeatureChecker>();
return await feature.IsEnabledAsync(true, _requireFeatures.ToArray());
return await feature.IsEnabledAsync(_requiresAll, _featureNames);
}
}
}

21
framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs

@ -1,14 +1,29 @@
using Volo.Abp.Authorization.Permissions;
using JetBrains.Annotations;
using Volo.Abp.Authorization.Permissions;
namespace Volo.Abp.GlobalFeatures
{
public static class GlobalFeatureDefinitionExtensions
{
public static PermissionDefinition RequireGlobalFeatures(this PermissionDefinition permissionDefinition, params string[] globalFeatures)
public static PermissionDefinition RequireGlobalFeatures(
this PermissionDefinition permissionDefinition,
params string[] globalFeatures)
{
return permissionDefinition.RequireGlobalFeatures(true, globalFeatures);
}
public static PermissionDefinition RequireGlobalFeatures(
[NotNull] this PermissionDefinition permissionDefinition,
bool requiresAll,
params string[] globalFeatures)
{
Check.NotNull(permissionDefinition, nameof(permissionDefinition));
Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures));
return permissionDefinition.AddStateProvider(new RequireGlobalFeaturesPermissionStateProvider(globalFeatures));
return permissionDefinition.AddStateProviders(
new RequireGlobalFeaturesPermissionStateProvider(requiresAll, globalFeatures)
);
}
}
}

24
framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
@ -7,18 +6,29 @@ namespace Volo.Abp.GlobalFeatures
{
public class RequireGlobalFeaturesPermissionStateProvider : IPermissionStateProvider
{
private readonly List<string> _requireGlobalFeatures = new List<string>();
private readonly string[] _globalFeatureNames;
private readonly bool _requiresAll;
public RequireGlobalFeaturesPermissionStateProvider(params string[] requireGlobalFeatures)
public RequireGlobalFeaturesPermissionStateProvider(params string[] globalFeatureNames)
: this(true, globalFeatureNames)
{
Check.NotNullOrEmpty(requireGlobalFeatures, nameof(requireGlobalFeatures));
}
public RequireGlobalFeaturesPermissionStateProvider(bool requiresAll, params string[] globalFeatureNames)
{
Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames));
_requireGlobalFeatures.AddRange(requireGlobalFeatures);
_requiresAll = requiresAll;
_globalFeatureNames = globalFeatureNames;
}
public Task<bool> IsEnabledAsync(PermissionStateContext context)
{
return Task.FromResult(_requireGlobalFeatures.All(x => GlobalFeatureManager.Instance.IsEnabled(x)));
bool isEnabled = _requiresAll
? _globalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x))
: _globalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x));
return Task.FromResult(isEnabled);
}
}
}

2
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs

@ -29,7 +29,7 @@ namespace Volo.Abp.Authorization
public async Task PermissionState_Test()
{
var myPermission1 = PermissionDefinitionManager.Get("MyPermission1");
myPermission1.GetStateProviders().ShouldContain(x => x.GetType() == typeof(TestRequireEditionPermissionStateProvider));
myPermission1.StateProviders.ShouldContain(x => x.GetType() == typeof(TestRequireEditionPermissionStateProvider));
(await PermissionStateManager.IsEnabledAsync(myPermission1)).ShouldBeFalse();

2
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs

@ -17,7 +17,7 @@ namespace Volo.Abp.Authorization.TestServices
group.AddPermission("MyAuthorizedService1");
group.AddPermission("MyPermission1").AddStateProvider(new TestRequireEditionPermissionStateProvider());
group.AddPermission("MyPermission1").AddStateProviders(new TestRequireEditionPermissionStateProvider());
group.AddPermission("MyPermission2");
group.GetPermissionOrNull("MyAuthorizedService1").ShouldNotBeNull();

Loading…
Cancel
Save