diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs index 7729093f69..5aa6ec80b0 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs @@ -17,19 +17,22 @@ public class ResourcePermissionChecker : IResourcePermissionChecker, ITransientD protected ICurrentTenant CurrentTenant { get; } protected IResourcePermissionValueProviderManager PermissionValueProviderManager { get; } protected ISimpleStateCheckerManager StateCheckerManager { get; } + protected IPermissionChecker PermissionChecker { get; } public ResourcePermissionChecker( ICurrentPrincipalAccessor principalAccessor, IPermissionDefinitionManager permissionDefinitionManager, ICurrentTenant currentTenant, IResourcePermissionValueProviderManager permissionValueProviderManager, - ISimpleStateCheckerManager stateCheckerManager) + ISimpleStateCheckerManager stateCheckerManager, + IPermissionChecker permissionChecker) { PrincipalAccessor = principalAccessor; PermissionDefinitionManager = permissionDefinitionManager; CurrentTenant = currentTenant; PermissionValueProviderManager = permissionValueProviderManager; StateCheckerManager = stateCheckerManager; + PermissionChecker = permissionChecker; } public virtual async Task IsGrantedAsync(string name, string resourceName, string resourceKey) @@ -69,6 +72,11 @@ public class ResourcePermissionChecker : IResourcePermissionChecker, ITransientD return false; } + if (!await PermissionChecker.IsGrantedAsync(claimsPrincipal, permission.ManagementPermissionName!)) + { + return false; + } + var isGranted = false; var context = new ResourcePermissionValueCheckContext(permission, claimsPrincipal, resourceName, resourceKey); foreach (var provider in PermissionValueProviderManager.ValueProviders) @@ -96,7 +104,7 @@ public class ResourcePermissionChecker : IResourcePermissionChecker, ITransientD public async Task IsGrantedAsync(string[] names, string resourceName, string resourceKey) { - return await IsGrantedAsync(PrincipalAccessor.Principal, names, resourceName,resourceKey); + return await IsGrantedAsync(PrincipalAccessor.Principal, names, resourceName, resourceKey); } public async Task IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, string[] names, string resourceName, string resourceKey) @@ -116,7 +124,8 @@ public class ResourcePermissionChecker : IResourcePermissionChecker, ITransientD foreach (var name in names) { var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(resourceName, name); - if (permission == null) + if (permission == null || + !await PermissionChecker.IsGrantedAsync(claimsPrincipal, permission.ManagementPermissionName!)) { result.Result.Add(name, PermissionGrantResult.Prohibited); continue; diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionPopulator.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionPopulator.cs index e3684263a0..24a20e3cca 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionPopulator.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionPopulator.cs @@ -9,19 +9,20 @@ namespace Volo.Abp.Authorization.Permissions.Resources; public class ResourcePermissionPopulator : ITransientDependency { protected IPermissionDefinitionManager PermissionDefinitionManager { get; } - protected IResourcePermissionChecker ResourcePermissionChecker { get; } - protected IResourcePermissionStore ResourcePermissionStore { get; } + protected IPermissionChecker PermissionChecker { get; } public ResourcePermissionPopulator( IPermissionDefinitionManager permissionDefinitionManager, IResourcePermissionChecker resourcePermissionChecker, - IResourcePermissionStore resourcePermissionStore) + IResourcePermissionStore resourcePermissionStore, + IPermissionChecker permissionChecker) { PermissionDefinitionManager = permissionDefinitionManager; ResourcePermissionChecker = resourcePermissionChecker; ResourcePermissionStore = resourcePermissionStore; + PermissionChecker = permissionChecker; } public virtual async Task PopulateAsync(TResource resource, string resourceName) @@ -36,9 +37,8 @@ public class ResourcePermissionPopulator : ITransientDependency Check.NotNull(resources, nameof(resources)); Check.NotNullOrWhiteSpace(resourceName, nameof(resourceName)); - var resopurcePermissionNames = (await PermissionDefinitionManager.GetResourcePermissionsAsync()) + var resopurcePermissions = (await PermissionDefinitionManager.GetResourcePermissionsAsync()) .Where(x => x.ResourceName == resourceName) - .Select(x => x.Name) .ToArray(); foreach (var resource in resources) @@ -48,17 +48,22 @@ public class ResourcePermissionPopulator : ITransientDependency { throw new AbpException("Resource key can not be null or empty."); } - - var results = await ResourcePermissionChecker.IsGrantedAsync(resopurcePermissionNames, resourceName, resourceKey); - foreach (var resopurcePermission in resopurcePermissionNames) + + var results = await ResourcePermissionChecker.IsGrantedAsync(resopurcePermissions.Select(x => x.Name).ToArray(), resourceName, resourceKey); + foreach (var resopurcePermission in resopurcePermissions) { + if (!await PermissionChecker.IsGrantedAsync(resopurcePermission.ManagementPermissionName!)) + { + continue; + } + if (resource.ResourcePermissions == null) { ObjectHelper.TrySetProperty(resource, x => x.ResourcePermissions, () => new Dictionary()); } - - var hasPermission = results.Result.TryGetValue(resopurcePermission, out var granted) && granted == PermissionGrantResult.Granted; - resource.ResourcePermissions![resopurcePermission] = hasPermission; + + var hasPermission = results.Result.TryGetValue(resopurcePermission.Name, out var granted) && granted == PermissionGrantResult.Granted; + resource.ResourcePermissions![resopurcePermission.Name] = hasPermission; } } } diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionChecker_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionChecker_Tests.cs index 37a624cd04..739968b603 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionChecker_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionChecker_Tests.cs @@ -21,6 +21,7 @@ public class ResourcePermissionChecker_Tests: AuthorizationTestBase { (await _resourcePermissionChecker.IsGrantedAsync("MyResourcePermission5", TestEntityResource.ResourceName, TestEntityResource.ResourceKey5)).ShouldBe(true); (await _resourcePermissionChecker.IsGrantedAsync("UndefinedResourcePermission", TestEntityResource.ResourceName, TestEntityResource.ResourceKey5)).ShouldBe(false); + (await _resourcePermissionChecker.IsGrantedAsync("MyResourcePermission8", TestEntityResource.ResourceName, TestEntityResource.ResourceKey5)).ShouldBe(false); } [Fact] @@ -33,7 +34,8 @@ public class ResourcePermissionChecker_Tests: AuthorizationTestBase "UndefinedPermission", "MyResourcePermission3", "MyResourcePermission4", - "MyResourcePermission5" + "MyResourcePermission5", + "MyResourcePermission8" }, TestEntityResource.ResourceName, TestEntityResource.ResourceKey5); result.Result["MyResourcePermission1"].ShouldBe(PermissionGrantResult.Undefined); @@ -42,11 +44,13 @@ public class ResourcePermissionChecker_Tests: AuthorizationTestBase result.Result["MyResourcePermission3"].ShouldBe(PermissionGrantResult.Granted); result.Result["MyResourcePermission4"].ShouldBe(PermissionGrantResult.Prohibited); result.Result["MyResourcePermission5"].ShouldBe(PermissionGrantResult.Granted); + result.Result["MyResourcePermission8"].ShouldBe(PermissionGrantResult.Prohibited); result = await _resourcePermissionChecker.IsGrantedAsync(new [] { "MyResourcePermission6", }, TestEntityResource.ResourceName, TestEntityResource.ResourceKey6); + result.Result["MyResourcePermission6"].ShouldBe(PermissionGrantResult.Granted); result = await _resourcePermissionChecker.IsGrantedAsync(new [] diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionPopulator_Test.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionPopulator_Test.cs new file mode 100644 index 0000000000..a4116283f8 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionPopulator_Test.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Authorization.TestServices.Resources; +using Xunit; + +namespace Volo.Abp.Authorization; + +public class ResourcePermissionPopulator_Tests : AuthorizationTestBase +{ + private readonly ResourcePermissionPopulator _resourcePermissionPopulator; + + public ResourcePermissionPopulator_Tests() + { + _resourcePermissionPopulator = GetRequiredService(); + } + + [Fact] + public async Task PopulateAsync() + { + var testResourceObject = new TestEntityResource(TestEntityResource.ResourceKey5); + testResourceObject.ResourcePermissions.IsNullOrEmpty().ShouldBeTrue(); + + await _resourcePermissionPopulator.PopulateAsync( + testResourceObject, + TestEntityResource.ResourceName + ); + + testResourceObject.ResourcePermissions.ShouldNotBeNull(); + testResourceObject.ResourcePermissions.Count.ShouldBe(7); // Does not include MyResourcePermission8 because current user has no TestEntityManagementPermission2 + testResourceObject.ResourcePermissions["MyResourcePermission1"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission2"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission3"].ShouldBe(true); + testResourceObject.ResourcePermissions["MyResourcePermission4"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission5"].ShouldBe(true); + testResourceObject.ResourcePermissions["MyResourcePermission6"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission7"].ShouldBe(false); + + testResourceObject = new TestEntityResource(TestEntityResource.ResourceKey6); + testResourceObject.ResourcePermissions.IsNullOrEmpty().ShouldBeTrue(); + + await _resourcePermissionPopulator.PopulateAsync( + testResourceObject, + TestEntityResource.ResourceName + ); + + testResourceObject.ResourcePermissions.ShouldNotBeNull(); + testResourceObject.ResourcePermissions.Count.ShouldBe(7); // Does not include MyResourcePermission8 because current user has no TestEntityManagementPermission2 + testResourceObject.ResourcePermissions["MyResourcePermission1"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission2"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission3"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission4"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission5"].ShouldBe(false); + testResourceObject.ResourcePermissions["MyResourcePermission6"].ShouldBe(true); + testResourceObject.ResourcePermissions["MyResourcePermission7"].ShouldBe(false); + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/AuthorizationTestResourcePermissionDefinitionProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/AuthorizationTestResourcePermissionDefinitionProvider.cs index c5716532e1..29a597c9b3 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/AuthorizationTestResourcePermissionDefinitionProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/AuthorizationTestResourcePermissionDefinitionProvider.cs @@ -14,6 +14,7 @@ public class AuthorizationTestResourcePermissionDefinitionProvider : PermissionD getGroup = context.AddGroup("TestGroup"); } getGroup.AddPermission("TestEntityManagementPermission"); + getGroup.AddPermission("TestEntityManagementPermission2"); var permission1 = context.AddResourcePermission("MyResourcePermission1", resourceName: TestEntityResource.ResourceName, "TestEntityManagementPermission"); Assert.Throws(() => @@ -29,6 +30,7 @@ public class AuthorizationTestResourcePermissionDefinitionProvider : PermissionD context.AddResourcePermission("MyResourcePermission5", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); context.AddResourcePermission("MyResourcePermission6", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission").WithProviders(nameof(TestResourcePermissionValueProvider1)); context.AddResourcePermission("MyResourcePermission7", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission").WithProviders(nameof(TestResourcePermissionValueProvider2)); + context.AddResourcePermission("MyResourcePermission8", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission2"); Assert.Throws(() => { diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/FakeResourcePermissionStore.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/FakeResourcePermissionStore.cs index 54ef8cd9a0..40cd542ac7 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/FakeResourcePermissionStore.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/FakeResourcePermissionStore.cs @@ -19,7 +19,7 @@ public class FakeResourcePermissionStore : IResourcePermissionStore, ITransientD var result = new MultiplePermissionGrantResult(); foreach (var name in names) { - result.Result.Add(name, (name == "MyResourcePermission3" || name == "MyResourcePermission5" && + result.Result.Add(name, ((name == "MyResourcePermission3" || name == "MyResourcePermission5") && resourceName == TestEntityResource.ResourceName && (resourceKey == TestEntityResource.ResourceKey3 || resourceKey == TestEntityResource.ResourceKey5) ? PermissionGrantResult.Granted diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestEntityResource.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestEntityResource.cs index 7325ed26d7..f703007633 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestEntityResource.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestEntityResource.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Generic; +using Volo.Abp.Authorization.Permissions.Resources; namespace Volo.Abp.Authorization.TestServices.Resources; -public class TestEntityResource +public class TestEntityResource : IHasResourcePermissions { public static readonly string ResourceName = typeof(TestEntityResource).FullName; @@ -13,6 +15,20 @@ public class TestEntityResource public static readonly string ResourceKey5 = Guid.NewGuid().ToString(); public static readonly string ResourceKey6 = Guid.NewGuid().ToString(); public static readonly string ResourceKey7 = Guid.NewGuid().ToString(); + + private string Id { get; } + + public TestEntityResource(string id) + { + Id = id; + } + + public string GetObjectKey() + { + return Id; + } + + public Dictionary ResourcePermissions { get; set; } } public class TestEntityResource2 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 6091211c3c..b41c997723 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 @@ -267,7 +267,10 @@ public class PermissionAppService : ApplicationService, IPermissionAppService } } - result.Permissions.Add(resourcePermissionGrantInfoDto); + if(resourcePermissionGrantInfoDto.Permissions.Any()) + { + result.Permissions.Add(resourcePermissionGrantInfoDto); + } } return result;