From 5968b9e57f78b43d97ef63978f030424d28f90e2 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 25 Feb 2026 20:31:34 +0800 Subject: [PATCH] feat: Exclude unavailable providers from resource permission grants and add related tests --- .../ResourcePermissionManager.cs | 47 ++++++++++- .../ResourcePermissionManager_Tests.cs | 80 +++++++++++++++++++ 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs index cd0b006036..681aed4201 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs @@ -175,13 +175,15 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD { var resourcePermissionDefinitions = await GetAvailablePermissionsAsync(resourceName); var resourcePermissionGrants = await ResourcePermissionGrantRepository.GetPermissionsAsync(resourceName, resourceKey); + var unavailableProviderNames = await GetUnavailableManagementProviderNamesAsync(); var result = new List(); foreach (var resourcePermissionDefinition in resourcePermissionDefinitions) { var permissionWithGrantedProviders = new PermissionWithGrantedProviders(resourcePermissionDefinition.Name, false); var grantedPermissions = resourcePermissionGrants - .Where(x => x.Name == resourcePermissionDefinition.Name && x.ResourceName == resourceName && x.ResourceKey == resourceKey) + .Where(x => x.Name == resourcePermissionDefinition.Name && x.ResourceName == resourceName && x.ResourceKey == resourceKey + && !unavailableProviderNames.Contains(x.ProviderName)) .ToList(); if (grantedPermissions.Any()) @@ -210,7 +212,10 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD { var resourcePermissions = await GetAvailablePermissionsAsync(resourceName); var resourcePermissionGrants = await ResourcePermissionGrantRepository.GetPermissionsAsync(resourceName, resourceKey); - resourcePermissionGrants = resourcePermissionGrants.Where(x => resourcePermissions.Any(rp => rp.Name == x.Name)).ToList(); + var unavailableProviderNames = await GetUnavailableManagementProviderNamesAsync(); + resourcePermissionGrants = resourcePermissionGrants + .Where(x => resourcePermissions.Any(rp => rp.Name == x.Name) && !unavailableProviderNames.Contains(x.ProviderName)) + .ToList(); var resourcePermissionGrantsGroup = resourcePermissionGrants.GroupBy(x => new { x.ProviderName, x.ProviderKey }); var result = new List(); foreach (var resourcePermissionGrant in resourcePermissionGrantsGroup) @@ -349,6 +354,12 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD public virtual async Task DeleteAsync(string resourceName, string resourceKey, string providerName, string providerKey) { + var provider = ManagementProviders.FirstOrDefault(m => m.Name == providerName); + if (provider != null && !await provider.IsAvailableAsync()) + { + throw new AbpException($"The resource permission management provider '{providerName}' is not available in the current context."); + } + var permissionGrants = await ResourcePermissionGrantRepository.GetListAsync(resourceName, resourceKey, providerName, providerKey); foreach (var permissionGrant in permissionGrants) { @@ -358,6 +369,12 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD public virtual async Task DeleteAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) { + var provider = ManagementProviders.FirstOrDefault(m => m.Name == providerName); + if (provider != null && !await provider.IsAvailableAsync()) + { + throw new AbpException($"The resource permission management provider '{providerName}' is not available in the current context."); + } + var permissionGrant = await ResourcePermissionGrantRepository.FindAsync(name, resourceName, resourceKey, providerName, providerKey); if (permissionGrant != null) { @@ -429,4 +446,30 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD return multiplePermissionWithGrantedProviders; } + + protected virtual async Task> GetAvailableManagementProviderNamesAsync() + { + var names = new HashSet(); + foreach (var provider in ManagementProviders) + { + if (await provider.IsAvailableAsync()) + { + names.Add(provider.Name); + } + } + return names; + } + + protected virtual async Task> GetUnavailableManagementProviderNamesAsync() + { + var names = new HashSet(); + foreach (var provider in ManagementProviders) + { + if (!await provider.IsAvailableAsync()) + { + names.Add(provider.Name); + } + } + return names; + } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManager_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManager_Tests.cs index d09d477e2f..dc5cb4f4bd 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManager_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManager_Tests.cs @@ -391,4 +391,84 @@ public class ResourcePermissionManager_Tests : PermissionTestBase exception.Message.ShouldBe("The resource permission management provider 'TestUnavailable' is not available in the current context."); } + + [Fact] + public async Task GetAllAsync_Should_Not_Include_Grants_From_Unavailable_Provider() + { + // Grant via the available "Test" provider and the unavailable "TestUnavailable" provider + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "someKey") + ); + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "TestUnavailable", + "someKey") + ); + + var result = await _resourcePermissionManager.GetAllAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1); + + var item = result.FirstOrDefault(x => x.Name == "MyResourcePermission1"); + item.ShouldNotBeNull(); + item.IsGranted.ShouldBeTrue(); + item.Providers.ShouldContain(p => p.Name == "Test"); + item.Providers.ShouldNotContain(p => p.Name == "TestUnavailable"); + } + + [Fact] + public async Task GetAllGroupAsync_Should_Not_Include_Grants_From_Unavailable_Provider() + { + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission2", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "TestUnavailable", + "someKey") + ); + + var group = await _resourcePermissionManager.GetAllGroupAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1); + + group.ShouldNotContain(g => g.ProviderName == "TestUnavailable"); + } + + [Fact] + public async Task DeleteAsync_Should_Throw_When_Provider_Is_Unavailable() + { + var exception = await Assert.ThrowsAsync(async () => + { + await _resourcePermissionManager.DeleteAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "TestUnavailable", + "someKey"); + }); + exception.Message.ShouldBe("The resource permission management provider 'TestUnavailable' is not available in the current context."); + } + + [Fact] + public async Task DeleteAsyncByName_Should_Throw_When_Provider_Is_Unavailable() + { + var exception = await Assert.ThrowsAsync(async () => + { + await _resourcePermissionManager.DeleteAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "TestUnavailable", + "someKey"); + }); + exception.Message.ShouldBe("The resource permission management provider 'TestUnavailable' is not available in the current context."); + } }