Merge pull request #8640 from abpframework/auto-merge/rel-4-3/307

Merge branch dev with rel-4.3
pull/8655/head
maliming 5 years ago committed by GitHub
commit 30f76eb194
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -383,6 +383,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Compone
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Bundling.Abstractions", "src\Volo.Abp.AspNetCore.Mvc.UI.Bundling.Abstractions\Volo.Abp.AspNetCore.Mvc.UI.Bundling.Abstractions.csproj", "{E9CE58DB-0789-4D18-8B63-474F7D7B14B4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Authorization.Abstractions", "src\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj", "{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Abstractions", "src\Volo.Abp.TextTemplating.Abstractions\Volo.Abp.TextTemplating.Abstractions.csproj", "{184E859A-282D-44D7-B8E9-FEA874644013}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Scriban", "src\Volo.Abp.TextTemplating.Scriban\Volo.Abp.TextTemplating.Scriban.csproj", "{228723E6-FA6D-406B-B8F8-C9BCC547AF8E}"
@ -1151,6 +1153,10 @@ Global
{E9CE58DB-0789-4D18-8B63-474F7D7B14B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9CE58DB-0789-4D18-8B63-474F7D7B14B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9CE58DB-0789-4D18-8B63-474F7D7B14B4}.Release|Any CPU.Build.0 = Release|Any CPU
{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA}.Release|Any CPU.Build.0 = Release|Any CPU
{184E859A-282D-44D7-B8E9-FEA874644013}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{184E859A-282D-44D7-B8E9-FEA874644013}.Debug|Any CPU.Build.0 = Debug|Any CPU
{184E859A-282D-44D7-B8E9-FEA874644013}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1364,6 +1370,7 @@ Global
{863C18F9-2407-49F9-9ADC-F6229AF3B385} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{B4B6B7DE-9798-4007-B1DF-7EE7929E392A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{E9CE58DB-0789-4D18-8B63-474F7D7B14B4} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{184E859A-282D-44D7-B8E9-FEA874644013} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{228723E6-FA6D-406B-B8F8-C9BCC547AF8E} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{42EA6F06-2D78-4D18-8AC4-8F2AB7E6DA19} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Volo.Abp.Authorization.Abstractions</AssemblyName>
<PackageId>Volo.Abp.Authorization.Abstractions</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="$(MicrosoftPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,13 @@
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Authorization
{
[DependsOn(
typeof(AbpMultiTenancyModule)
)]
public class AbpAuthorizationAbstractionsModule : AbpModule
{
}
}

@ -8,10 +8,13 @@ namespace Volo.Abp.Authorization.Permissions
public ITypeList<IPermissionValueProvider> ValueProviders { get; }
public ITypeList<IPermissionStateProvider> GlobalStateProviders { get; }
public AbpPermissionOptions()
{
DefinitionProviders = new TypeList<IPermissionDefinitionProvider>();
ValueProviders = new TypeList<IPermissionValueProvider>();
GlobalStateProviders = new TypeList<IPermissionStateProvider>();
}
}
}

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace Volo.Abp.Authorization.Permissions
{
public interface IPermissionStateManager
{
Task<bool> IsEnabledAsync(PermissionDefinition permission);
}
}

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace Volo.Abp.Authorization.Permissions
{
public interface IPermissionStateProvider
{
Task<bool> IsEnabledAsync(PermissionStateContext context);
}
}

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

@ -10,16 +10,16 @@ namespace Volo.Abp.Authorization.Permissions
{
public IServiceProvider ServiceProvider { get; }
internal Dictionary<string, PermissionGroupDefinition> Groups { get; }
public Dictionary<string, PermissionGroupDefinition> Groups { get; }
internal PermissionDefinitionContext(IServiceProvider serviceProvider)
public PermissionDefinitionContext(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
Groups = new Dictionary<string, PermissionGroupDefinition>();
}
public virtual PermissionGroupDefinition AddGroup(
string name,
string name,
ILocalizableString displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both)
{
@ -87,4 +87,4 @@ namespace Volo.Abp.Authorization.Permissions
return null;
}
}
}
}

@ -0,0 +1,19 @@
using JetBrains.Annotations;
namespace Volo.Abp.Authorization.Permissions
{
public static class PermissionDefinitionExtensions
{
public static PermissionDefinition AddStateProviders(
[NotNull] this PermissionDefinition permissionDefinition,
[NotNull] params IPermissionStateProvider[] permissionStateProviders)
{
Check.NotNull(permissionDefinition, nameof(permissionDefinition));
Check.NotNull(permissionStateProviders, nameof(permissionStateProviders));
permissionDefinition.StateProviders.AddRange(permissionStateProviders);
return permissionDefinition;
}
}
}

@ -0,0 +1,11 @@
using System;
namespace Volo.Abp.Authorization.Permissions
{
public class PermissionStateContext
{
public IServiceProvider ServiceProvider { get; set; }
public PermissionDefinition Permission { get; set; }
}
}

@ -14,18 +14,17 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="$(MicrosoftPackageVersion)" />
</ItemGroup>
<ItemGroup>
<None Remove="Volo\Abp\Authorization\Localization\*.json" />
<EmbeddedResource Include="Volo\Abp\Authorization\Localization\*.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" />
</ItemGroup>

@ -8,17 +8,16 @@ using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Security;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Authorization
{
[DependsOn(
typeof(AbpAuthorizationAbstractionsModule),
typeof(AbpSecurityModule),
typeof(AbpLocalizationModule),
typeof(AbpMultiTenancyModule)
)]
typeof(AbpLocalizationModule)
)]
public class AbpAuthorizationModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)

@ -15,17 +15,20 @@ namespace Volo.Abp.Authorization.Permissions
protected ICurrentPrincipalAccessor PrincipalAccessor { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IPermissionValueProviderManager PermissionValueProviderManager { get; }
protected IPermissionStateManager PermissionStateManager { get; }
public PermissionChecker(
ICurrentPrincipalAccessor principalAccessor,
IPermissionDefinitionManager permissionDefinitionManager,
ICurrentTenant currentTenant,
IPermissionValueProviderManager permissionValueProviderManager)
IPermissionValueProviderManager permissionValueProviderManager,
IPermissionStateManager permissionStateManager)
{
PrincipalAccessor = principalAccessor;
PermissionDefinitionManager = permissionDefinitionManager;
CurrentTenant = currentTenant;
PermissionValueProviderManager = permissionValueProviderManager;
PermissionStateManager = permissionStateManager;
}
public virtual async Task<bool> IsGrantedAsync(string name)
@ -46,6 +49,11 @@ namespace Volo.Abp.Authorization.Permissions
return false;
}
if (!await PermissionStateManager.IsEnabledAsync(permission))
{
return false;
}
var multiTenancySide = claimsPrincipal?.GetMultiTenancySide()
?? CurrentTenant.GetMultiTenancySide();
@ -103,7 +111,9 @@ namespace Volo.Abp.Authorization.Permissions
result.Result.Add(name, PermissionGrantResult.Undefined);
if (permission.IsEnabled && permission.MultiTenancySide.HasFlag(multiTenancySide))
if (permission.IsEnabled &&
await PermissionStateManager.IsEnabledAsync(permission) &&
permission.MultiTenancySide.HasFlag(multiTenancySide))
{
permissionDefinitions.Add(permission);
}

@ -0,0 +1,51 @@
using System;
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 PermissionStateManager : IPermissionStateManager, ITransientDependency
{
protected IServiceProvider ServiceProvider { get; }
protected AbpPermissionOptions Options { get; }
public PermissionStateManager(IServiceProvider serviceProvider, IOptions<AbpPermissionOptions> options)
{
ServiceProvider = serviceProvider;
Options = options.Value;
}
public async Task<bool> IsEnabledAsync(PermissionDefinition permission)
{
using (var scope = ServiceProvider.CreateScope())
{
var context = new PermissionStateContext
{
Permission = permission,
ServiceProvider = scope.ServiceProvider.GetRequiredService<ICachedServiceProvider>()
};
foreach (var provider in permission.StateProviders)
{
if (!await provider.IsEnabledAsync(context))
{
return false;
}
}
foreach (IPermissionStateProvider provider in Options.GlobalStateProviders.Select(x => ServiceProvider.GetRequiredService(x)))
{
if (!await provider.IsEnabledAsync(context))
{
return false;
}
}
return true;
}
}
}
}

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

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

@ -23,6 +23,7 @@
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.Validation\Volo.Abp.Validation.csproj" />
<ProjectReference Include="..\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj" />
</ItemGroup>
</Project>

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using Volo.Abp.Authorization;
using Volo.Abp.Features.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
@ -14,7 +15,8 @@ namespace Volo.Abp.Features
[DependsOn(
typeof(AbpLocalizationModule),
typeof(AbpMultiTenancyModule),
typeof(AbpValidationModule)
typeof(AbpValidationModule),
typeof(AbpAuthorizationAbstractionsModule)
)]
public class AbpFeaturesModule : AbpModule
{

@ -0,0 +1,28 @@
using JetBrains.Annotations;
using Volo.Abp.Authorization.Permissions;
namespace Volo.Abp.Features
{
public static class FeatureDefinitionExtensions
{
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.AddStateProviders(
new RequireFeaturesPermissionStateProvider(requiresAll, features)
);
}
}
}

@ -0,0 +1,32 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
namespace Volo.Abp.Features
{
public class RequireFeaturesPermissionStateProvider : IPermissionStateProvider
{
private readonly string[] _featureNames;
private readonly bool _requiresAll;
public RequireFeaturesPermissionStateProvider(params string[] featureNames)
: this(true, featureNames)
{
}
public RequireFeaturesPermissionStateProvider(bool requiresAll, params string[] featureNames)
{
Check.NotNullOrEmpty(featureNames, nameof(featureNames));
_requiresAll = requiresAll;
_featureNames = featureNames;
}
public async Task<bool> IsEnabledAsync(PermissionStateContext context)
{
var feature = context.ServiceProvider.GetRequiredService<IFeatureChecker>();
return await feature.IsEnabledAsync(_requiresAll, _featureNames);
}
}
}

@ -22,6 +22,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
<ProjectReference Include="..\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" />
<ProjectReference Include="..\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj" />
</ItemGroup>
</Project>

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization;
using Volo.Abp.GlobalFeatures.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
@ -9,7 +10,8 @@ namespace Volo.Abp.GlobalFeatures
{
[DependsOn(
typeof(AbpLocalizationModule),
typeof(AbpVirtualFileSystemModule)
typeof(AbpVirtualFileSystemModule),
typeof(AbpAuthorizationAbstractionsModule)
)]
public class AbpGlobalFeaturesModule : AbpModule
{

@ -0,0 +1,29 @@
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)
{
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.AddStateProviders(
new RequireGlobalFeaturesPermissionStateProvider(requiresAll, globalFeatures)
);
}
}
}

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

@ -0,0 +1,63 @@
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;
using Xunit;
namespace Volo.Abp.Authorization
{
public abstract class PermissionStateProvider_Tests : AuthorizationTestBase
{
protected IPermissionStateManager PermissionStateManager { get; }
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
protected ICurrentPrincipalAccessor CurrentPrincipalAccessor { get; }
public PermissionStateProvider_Tests()
{
PermissionStateManager = GetRequiredService<IPermissionStateManager>();
PermissionDefinitionManager = GetRequiredService<IPermissionDefinitionManager>();
CurrentPrincipalAccessor = GetRequiredService<ICurrentPrincipalAccessor>();
}
}
public class SpecifyPermissionStateProvider : PermissionStateProvider_Tests
{
[Fact]
public async Task PermissionState_Test()
{
var myPermission1 = PermissionDefinitionManager.Get("MyPermission1");
myPermission1.StateProviders.ShouldContain(x => x.GetType() == typeof(TestRequireEditionPermissionStateProvider));
(await PermissionStateManager.IsEnabledAsync(myPermission1)).ShouldBeFalse();
using (CurrentPrincipalAccessor.Change(new Claim(AbpClaimTypes.EditionId, Guid.NewGuid().ToString())))
{
(await PermissionStateManager.IsEnabledAsync(myPermission1)).ShouldBeTrue();
}
}
}
public class GlobalPermissionStateProvider : PermissionStateProvider_Tests
{
protected override void AfterAddApplication(IServiceCollection services)
{
services.Configure<AbpPermissionOptions>(options => options.GlobalStateProviders.Add<TestGlobalRequireRolePermissionStateProvider>());
}
[Fact]
public async Task Global_PermissionState_Test()
{
var myPermission2 = PermissionDefinitionManager.Get("MyPermission2");
(await PermissionStateManager.IsEnabledAsync(myPermission2)).ShouldBeFalse();
using (CurrentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "admin")))
{
(await PermissionStateManager.IsEnabledAsync(myPermission2)).ShouldBeTrue();
}
}
}
}

@ -0,0 +1,17 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Authorization
{
public class TestGlobalRequireRolePermissionStateProvider : IPermissionStateProvider, ITransientDependency
{
public Task<bool> IsEnabledAsync(PermissionStateContext context)
{
var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
return Task.FromResult(currentPrincipalAccessor.Principal != null && currentPrincipalAccessor.Principal.IsInRole("admin"));
}
}
}

@ -0,0 +1,17 @@
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Authorization
{
public class TestRequireEditionPermissionStateProvider : IPermissionStateProvider
{
public Task<bool> IsEnabledAsync(PermissionStateContext context)
{
var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
return Task.FromResult(currentPrincipalAccessor.Principal?.FindEditionId() != null);
}
}
}

@ -12,11 +12,14 @@ namespace Volo.Abp.Authorization.TestServices
{
getGroup = context.AddGroup("TestGetGroup");
}
var group = context.AddGroup("TestGroup");
group.AddPermission("MyAuthorizedService1");
group.AddPermission("MyPermission1").AddStateProviders(new TestRequireEditionPermissionStateProvider());
group.AddPermission("MyPermission2");
group.GetPermissionOrNull("MyAuthorizedService1").ShouldNotBeNull();
context.RemoveGroup("TestGetGroup");

@ -14,18 +14,20 @@ namespace Volo.Abp.PermissionManagement
public class PermissionAppService : ApplicationService, IPermissionAppService
{
protected PermissionManagementOptions Options { get; }
protected IPermissionManager PermissionManager { get; }
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
protected IPermissionStateManager PermissionStateManager { get; }
public PermissionAppService(
IPermissionManager permissionManager,
IPermissionManager permissionManager,
IPermissionDefinitionManager permissionDefinitionManager,
IOptions<PermissionManagementOptions> options)
IOptions<PermissionManagementOptions> options,
IPermissionStateManager permissionStateManager)
{
Options = options.Value;
PermissionManager = permissionManager;
PermissionDefinitionManager = permissionDefinitionManager;
PermissionStateManager = permissionStateManager;
}
public virtual async Task<GetPermissionListResultDto> GetAsync(string providerName, string providerKey)
@ -56,6 +58,11 @@ namespace Volo.Abp.PermissionManagement
continue;
}
if (!await PermissionStateManager.IsEnabledAsync(permission))
{
continue;
}
if (permission.Providers.Any() && !permission.Providers.Contains(providerName))
{
continue;

@ -18,6 +18,8 @@ namespace Volo.Abp.PermissionManagement
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
protected IPermissionStateManager PermissionStateManager { get; }
protected IGuidGenerator GuidGenerator { get; }
protected ICurrentTenant CurrentTenant { get; }
@ -25,23 +27,25 @@ namespace Volo.Abp.PermissionManagement
protected IReadOnlyList<IPermissionManagementProvider> ManagementProviders => _lazyProviders.Value;
protected PermissionManagementOptions Options { get; }
protected IDistributedCache<PermissionGrantCacheItem> Cache { get; }
private readonly Lazy<List<IPermissionManagementProvider>> _lazyProviders;
public PermissionManager(
IPermissionDefinitionManager permissionDefinitionManager,
IPermissionStateManager permissionStateManager,
IPermissionGrantRepository permissionGrantRepository,
IServiceProvider serviceProvider,
IGuidGenerator guidGenerator,
IOptions<PermissionManagementOptions> options,
ICurrentTenant currentTenant,
ICurrentTenant currentTenant,
IDistributedCache<PermissionGrantCacheItem> cache)
{
GuidGenerator = guidGenerator;
CurrentTenant = currentTenant;
Cache = cache;
PermissionStateManager = permissionStateManager;
PermissionGrantRepository = permissionGrantRepository;
PermissionDefinitionManager = permissionDefinitionManager;
Options = options.Value;
@ -76,7 +80,7 @@ namespace Volo.Abp.PermissionManagement
{
var permission = PermissionDefinitionManager.Get(permissionName);
if (!permission.IsEnabled)
if (!permission.IsEnabled || !await PermissionStateManager.IsEnabledAsync(permission))
{
//TODO: BusinessException
throw new ApplicationException($"The permission named '{permission.Name}' is disabled!");
@ -109,7 +113,7 @@ namespace Volo.Abp.PermissionManagement
await provider.SetAsync(permissionName, providerKey, isGranted);
}
public virtual async Task<PermissionGrant> UpdateProviderKeyAsync(PermissionGrant permissionGrant, string providerKey)
{
using (CurrentTenant.Change(permissionGrant.TenantId))
@ -123,7 +127,7 @@ namespace Volo.Abp.PermissionManagement
)
);
}
permissionGrant.ProviderKey = providerKey;
return await PermissionGrantRepository.UpdateAsync(permissionGrant);
}
@ -146,6 +150,11 @@ namespace Volo.Abp.PermissionManagement
return result;
}
if (!await PermissionStateManager.IsEnabledAsync(permission))
{
return result;
}
if (!permission.MultiTenancySide.HasFlag(CurrentTenant.GetMultiTenancySide()))
{
return result;

@ -18,7 +18,7 @@ namespace Volo.Abp.PermissionManagement
protected override void AfterAddApplication(IServiceCollection services)
{
var currentUser = Substitute.For<ICurrentUser>();
//currentUser.Id.Returns(ci => CurrentUserId);
currentUser.Roles.Returns(new []{ "admin" });
currentUser.IsAuthenticated.Returns(true);
services.AddSingleton(currentUser);

@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;
using Xunit;
namespace Volo.Abp.PermissionManagement.Application.Tests.Volo.Abp.PermissionManagement
@ -13,11 +15,13 @@ namespace Volo.Abp.PermissionManagement.Application.Tests.Volo.Abp.PermissionMan
{
private readonly IPermissionAppService _permissionAppService;
private readonly IPermissionGrantRepository _permissionGrantRepository;
private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;
public PermissionAppService_Tests()
{
_permissionAppService = GetRequiredService<IPermissionAppService>();
_permissionGrantRepository = GetRequiredService<IPermissionGrantRepository>();
_currentPrincipalAccessor = GetRequiredService<ICurrentPrincipalAccessor>();
}
[Fact]
@ -35,7 +39,15 @@ namespace Volo.Abp.PermissionManagement.Application.Tests.Volo.Abp.PermissionMan
permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission2");
permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission2.ChildPermission1");
permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission3");
permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission4");
permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyPermission5");
using (_currentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "super-admin")))
{
(await _permissionAppService.GetAsync(UserPermissionValueProvider.ProviderName, PermissionTestDataBuilder.User1Id.ToString())).Groups.First().Permissions
.ShouldContain(x => x.Name == "MyPermission5");
}
}
[Fact]

@ -11,10 +11,12 @@ namespace Volo.Abp.PermissionManagement
public class PermissionChecker_User_Tests : PermissionTestBase
{
private readonly IPermissionChecker _permissionChecker;
private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;
public PermissionChecker_User_Tests()
{
_permissionChecker = GetRequiredService<IPermissionChecker>();
_currentPrincipalAccessor = GetRequiredService<ICurrentPrincipalAccessor>();
}
[Fact]
@ -64,6 +66,27 @@ namespace Volo.Abp.PermissionManagement
)).ShouldBeFalse();
}
[Fact]
public async Task Should_Return_False_For_Granted_Current_User_If_The_Permission_State_Is_Disabled()
{
(await _permissionChecker.IsGrantedAsync(
CreatePrincipal(PermissionTestDataBuilder.User1Id, Guid.NewGuid()),
"MyPermission5"
)).ShouldBeFalse();
}
[Fact]
public async Task Should_Return_True_For_Granted_Current_User_If_The_Permission_State_Is_Enabled()
{
using (_currentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "super-admin")))
{
(await _permissionChecker.IsGrantedAsync(
CreatePrincipal(PermissionTestDataBuilder.User1Id, Guid.NewGuid()),
"MyPermission5"
)).ShouldBeTrue();
}
}
private static ClaimsPrincipal CreatePrincipal(Guid? userId, Guid? tenantId = null)
{
var claimsIdentity = new ClaimsIdentity();

@ -48,6 +48,15 @@ namespace Volo.Abp.PermissionManagement
User1Id.ToString()
)
);
await _permissionGrantRepository.InsertAsync(
new PermissionGrant(
_guidGenerator.Create(),
"MyPermission5",
UserPermissionValueProvider.ProviderName,
User1Id.ToString()
)
);
}
}
}
}

@ -18,6 +18,8 @@ namespace Volo.Abp.PermissionManagement
testGroup.AddPermission("MyPermission3", multiTenancySide: MultiTenancySides.Host);
testGroup.AddPermission("MyPermission4", multiTenancySide: MultiTenancySides.Host).WithProviders(UserPermissionValueProvider.ProviderName);
testGroup.AddPermission("MyPermission5").AddStateProviders(new TestRequireRolePermissionStateProvider("super-admin"));
}
}
}

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.PermissionManagement
{
public class TestRequireRolePermissionStateProvider : IPermissionStateProvider
{
private readonly List<string> _allowRoles = new List<string>();
public TestRequireRolePermissionStateProvider(params string[] roles)
{
_allowRoles.AddRange(roles);
}
public Task<bool> IsEnabledAsync(PermissionStateContext context)
{
var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
return Task.FromResult(currentPrincipalAccessor.Principal != null && _allowRoles.Any(role => currentPrincipalAccessor.Principal.IsInRole(role)));
}
}
}

@ -63,6 +63,7 @@ $projects = (
"framework/src/Volo.Abp.AspNetCore.TestBase",
"framework/src/Volo.Abp.Auditing",
"framework/src/Volo.Abp.Authorization",
"framework/src/Volo.Abp.Authorization.Abstractions",
"framework/src/Volo.Abp.Autofac",
"framework/src/Volo.Abp.Autofac.WebAssembly",
"framework/src/Volo.Abp.AutoMapper",

Loading…
Cancel
Save