diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 67d2fa2573..bdc2745705 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1141,6 +1143,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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1334,6 +1340,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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/FodyWeavers.xml b/framework/src/Volo.Abp.Authorization.Abstractions/FodyWeavers.xml new file mode 100644 index 0000000000..1715698ccd --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/FodyWeavers.xsd b/framework/src/Volo.Abp.Authorization.Abstractions/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo.Abp.Authorization.Abstractions.csproj b/framework/src/Volo.Abp.Authorization.Abstractions/Volo.Abp.Authorization.Abstractions.csproj new file mode 100644 index 0000000000..0eebcdf77a --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo.Abp.Authorization.Abstractions.csproj @@ -0,0 +1,25 @@ + + + + + + + netstandard2.0 + Volo.Abp.Authorization.Abstractions + Volo.Abp.Authorization.Abstractions + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + + diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AbpAuthorizationAbstractionsModule.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AbpAuthorizationAbstractionsModule.cs new file mode 100644 index 0000000000..a2c8b43fbd --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AbpAuthorizationAbstractionsModule.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization +{ + [DependsOn( + typeof(AbpMultiTenancyModule) + )] + public class AbpAuthorizationAbstractionsModule : AbpModule + { + + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AlwaysAllowAuthorizationService.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AlwaysAllowAuthorizationService.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AlwaysAllowAuthorizationService.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AlwaysAllowAuthorizationService.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AlwaysAllowMethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AlwaysAllowMethodInvocationAuthorizationService.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AlwaysAllowMethodInvocationAuthorizationService.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AlwaysAllowMethodInvocationAuthorizationService.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IAbpAuthorizationPolicyProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/IAbpAuthorizationPolicyProvider.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IAbpAuthorizationPolicyProvider.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/IAbpAuthorizationPolicyProvider.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IAbpAuthorizationService.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/IAbpAuthorizationService.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IAbpAuthorizationService.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/IAbpAuthorizationService.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IMethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/IMethodInvocationAuthorizationService.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IMethodInvocationAuthorizationService.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/IMethodInvocationAuthorizationService.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/MethodInvocationAuthorizationContext.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationContext.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/MethodInvocationAuthorizationContext.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/PermissionRequirement.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/PermissionRequirement.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/PermissionRequirement.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/PermissionRequirement.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/PermissionRequirementHandler.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/PermissionRequirementHandler.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/PermissionRequirementHandler.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/PermissionRequirementHandler.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs similarity index 75% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs index ce9dc06798..eb2ac920ac 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs @@ -8,10 +8,13 @@ namespace Volo.Abp.Authorization.Permissions public ITypeList ValueProviders { get; } + public ITypeList GlobalStateProviders { get; } + public AbpPermissionOptions() { DefinitionProviders = new TypeList(); ValueProviders = new TypeList(); + GlobalStateProviders = new TypeList(); } } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AlwaysAllowPermissionChecker.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionChecker.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionProvider.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionProvider.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionProvider.cs diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs new file mode 100644 index 0000000000..6195e02545 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions +{ + public interface IPermissionStateManager + { + Task IsEnabledAsync(PermissionDefinition permission); + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs new file mode 100644 index 0000000000..7bc3087f50 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions +{ + public interface IPermissionStateProvider + { + Task IsEnabledAsync(PermissionStateContext context); + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionStore.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStore.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionStore.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStore.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProviderManager.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionValueProviderManager.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionValueProviderManager.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionValueProviderManager.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/MultiplePermissionGrantResult.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/NullPermissionStore.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs similarity index 97% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs index 38873fe1b8..ac525367ad 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs @@ -31,6 +31,8 @@ namespace Volo.Abp.Authorization.Permissions /// public List Providers { get; } //TODO: Rename to AllowedProviders? + public List StateProviders { get; } + public ILocalizableString DisplayName { get => _displayName; @@ -86,6 +88,7 @@ namespace Volo.Abp.Authorization.Permissions Properties = new Dictionary(); Providers = new List(); + StateProviders = new List(); _children = new List(); } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs similarity index 93% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs index 4e52cdc2ee..4d5b39393f 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs @@ -10,16 +10,16 @@ namespace Volo.Abp.Authorization.Permissions { public IServiceProvider ServiceProvider { get; } - internal Dictionary Groups { get; } + public Dictionary Groups { get; } - internal PermissionDefinitionContext(IServiceProvider serviceProvider) + public PermissionDefinitionContext(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; Groups = new Dictionary(); } 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; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContextExtensions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContextExtensions.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContextExtensions.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContextExtensions.cs diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs new file mode 100644 index 0000000000..7e5de5a1f1 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs @@ -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; + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionProvider.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionProvider.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionProvider.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGrantInfo.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionGrantInfo.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGrantInfo.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionGrantInfo.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGrantResult.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionGrantResult.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGrantResult.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionGrantResult.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionStateContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionStateContext.cs new file mode 100644 index 0000000000..565e0afe99 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionStateContext.cs @@ -0,0 +1,11 @@ +using System; + +namespace Volo.Abp.Authorization.Permissions +{ + public class PermissionStateContext + { + public IServiceProvider ServiceProvider { get; set; } + + public PermissionDefinition Permission { get; set; } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueCheckContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionValueCheckContext.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueCheckContext.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionValueCheckContext.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionValueProvider.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValuesCheckContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionValuesCheckContext.cs similarity index 100% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValuesCheckContext.cs rename to framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionValuesCheckContext.cs diff --git a/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj b/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj index 66dd574322..be5c6f8898 100644 --- a/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj +++ b/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj @@ -14,18 +14,17 @@ - - - - + + + + - diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs index b4d5795b9c..a821401c4b 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs @@ -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) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs index bfdcf5fd66..f180a00bd7 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs @@ -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 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); } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs new file mode 100644 index 0000000000..957ed3c7a6 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs @@ -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 options) + { + ServiceProvider = serviceProvider; + Options = options.Value; + } + + public async Task IsEnabledAsync(PermissionDefinition permission) + { + using (var scope = ServiceProvider.CreateScope()) + { + var context = new PermissionStateContext + { + Permission = permission, + ServiceProvider = scope.ServiceProvider.GetRequiredService() + }; + + 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; + } + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProvider.cs new file mode 100644 index 0000000000..5e24d547e0 --- /dev/null +++ b/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 CachedServices { get; } + + public CachedServiceProvider(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + + CachedServices = new Dictionary + { + {typeof(IServiceProvider), serviceProvider} + }; + } + + public object GetService(Type serviceType) + { + return CachedServices.GetOrAdd( + serviceType, + () => ServiceProvider.GetService(serviceType) + ); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs new file mode 100644 index 0000000000..be8a3df18d --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs @@ -0,0 +1,15 @@ +using System; + +namespace Volo.Abp.DependencyInjection +{ + /// + /// 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. + /// + public interface ICachedServiceProvider : IServiceProvider + { + + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj b/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj index 3bea3ea77f..3b58621b45 100644 --- a/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj +++ b/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj @@ -23,6 +23,7 @@ + diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs index 70c6e7f37d..44546bb59b 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs @@ -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 { diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs new file mode 100644 index 0000000000..a213232f2f --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs @@ -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) + ); + } + } +} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs new file mode 100644 index 0000000000..0fee54c598 --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs @@ -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 IsEnabledAsync(PermissionStateContext context) + { + var feature = context.ServiceProvider.GetRequiredService(); + return await feature.IsEnabledAsync(_requiresAll, _featureNames); + } + } +} diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo.Abp.GlobalFeatures.csproj b/framework/src/Volo.Abp.GlobalFeatures/Volo.Abp.GlobalFeatures.csproj index a082ba3c6f..456366b542 100644 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo.Abp.GlobalFeatures.csproj +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo.Abp.GlobalFeatures.csproj @@ -23,6 +23,7 @@ + diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/AbpGlobalFeaturesModule.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/AbpGlobalFeaturesModule.cs index b861fd7693..127fc6d953 100644 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/AbpGlobalFeaturesModule.cs +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/AbpGlobalFeaturesModule.cs @@ -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 { diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs new file mode 100644 index 0000000000..200f002e07 --- /dev/null +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs @@ -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) + ); + } + + } +} diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs new file mode 100644 index 0000000000..40df2a14b3 --- /dev/null +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs @@ -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 IsEnabledAsync(PermissionStateContext context) + { + bool isEnabled = _requiresAll + ? _globalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x)) + : _globalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x)); + + return Task.FromResult(isEnabled); + } + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs new file mode 100644 index 0000000000..f7ab858ac1 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs @@ -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(); + PermissionDefinitionManager = GetRequiredService(); + CurrentPrincipalAccessor = GetRequiredService(); + } + } + + 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(options => options.GlobalStateProviders.Add()); + } + + [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(); + } + } + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs new file mode 100644 index 0000000000..6e3b58d2de --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs @@ -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 IsEnabledAsync(PermissionStateContext context) + { + var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); + return Task.FromResult(currentPrincipalAccessor.Principal != null && currentPrincipalAccessor.Principal.IsInRole("admin")); + } + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs new file mode 100644 index 0000000000..a793c84431 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs @@ -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 IsEnabledAsync(PermissionStateContext context) + { + var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); + return Task.FromResult(currentPrincipalAccessor.Principal?.FindEditionId() != null); + } + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs index 8cff4c361f..d67cf8febc 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs @@ -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"); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs index 2da5ae693b..4bc73a6f86 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs @@ -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 options) + IOptions options, + IPermissionStateManager permissionStateManager) { Options = options.Value; PermissionManager = permissionManager; PermissionDefinitionManager = permissionDefinitionManager; + PermissionStateManager = permissionStateManager; } public virtual async Task 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; diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs index 1f1e28dfd4..c178a6ae0e 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs @@ -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 ManagementProviders => _lazyProviders.Value; protected PermissionManagementOptions Options { get; } - + protected IDistributedCache Cache { get; } private readonly Lazy> _lazyProviders; public PermissionManager( IPermissionDefinitionManager permissionDefinitionManager, + IPermissionStateManager permissionStateManager, IPermissionGrantRepository permissionGrantRepository, IServiceProvider serviceProvider, IGuidGenerator guidGenerator, IOptions options, - ICurrentTenant currentTenant, + ICurrentTenant currentTenant, IDistributedCache 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 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; diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementApplicationTestBase.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementApplicationTestBase.cs index 7102b8f851..57cb20ea28 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementApplicationTestBase.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementApplicationTestBase.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.PermissionManagement protected override void AfterAddApplication(IServiceCollection services) { var currentUser = Substitute.For(); - //currentUser.Id.Returns(ci => CurrentUserId); + currentUser.Roles.Returns(new []{ "admin" }); currentUser.IsAuthenticated.Returns(true); services.AddSingleton(currentUser); diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs index fe528cbc3c..9782e23986 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs @@ -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(); _permissionGrantRepository = GetRequiredService(); + _currentPrincipalAccessor = GetRequiredService(); } [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] diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionChecker_User_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionChecker_User_Tests.cs index 0d455d11d8..e897f409fb 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionChecker_User_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionChecker_User_Tests.cs @@ -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(); + _currentPrincipalAccessor = GetRequiredService(); } [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(); diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionTestDataBuilder.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionTestDataBuilder.cs index e763c24d0b..0c504e3a97 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionTestDataBuilder.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionTestDataBuilder.cs @@ -48,6 +48,15 @@ namespace Volo.Abp.PermissionManagement User1Id.ToString() ) ); + + await _permissionGrantRepository.InsertAsync( + new PermissionGrant( + _guidGenerator.Create(), + "MyPermission5", + UserPermissionValueProvider.ProviderName, + User1Id.ToString() + ) + ); } } -} \ No newline at end of file +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs index c6de42ac3b..d2256a5868 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs @@ -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")); } } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs new file mode 100644 index 0000000000..56e34f2894 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs @@ -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 _allowRoles = new List(); + + public TestRequireRolePermissionStateProvider(params string[] roles) + { + _allowRoles.AddRange(roles); + } + + public Task IsEnabledAsync(PermissionStateContext context) + { + var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); + return Task.FromResult(currentPrincipalAccessor.Principal != null && _allowRoles.Any(role => currentPrincipalAccessor.Principal.IsInRole(role))); + } + } +} diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index c0e82e3486..715d25d7ab 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -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",