diff --git a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs index 4019cd9031..ca8228b9b6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs @@ -100,7 +100,7 @@ public class IdentityUserIntegrationService : IdentityAppServiceBase, IIdentityU { using (RoleRepository.DisableTracking()) { - var roles = await RoleRepository.GetListAsync(input.Filter); + var roles = await RoleRepository.GetListAsync(sorting: input.Sorting, maxResultCount: input.MaxResultCount, skipCount: input.SkipCount, filter: input.Filter); return new ListResultDto(roles.Select(r => new RoleData(r.Id, r.Name, r.IsDefault, r.IsStatic, r.IsPublic, r.TenantId, r.ExtraProperties)).ToList()); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/ResourcePermissionManagementModal.razor.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/ResourcePermissionManagementModal.razor.cs index a69eacea3c..964fc6ed63 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/ResourcePermissionManagementModal.razor.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/ResourcePermissionManagementModal.razor.cs @@ -129,6 +129,12 @@ public partial class ResourcePermissionManagementModal ProviderKey = value; ProviderDisplayName = ProviderKeys.FirstOrDefault(p => p.ProviderKey == value)?.ProviderDisplayName; + if (value.IsNullOrWhiteSpace()) + { + await InvokeAsync(StateHasChanged); + return; + } + var permissionGrants = await PermissionAppService.GetResourceByProviderAsync(ResourceName, ResourceKey, CurrentLookupService, ProviderKey); foreach (var permission in CreateEntity.Permissions) { @@ -140,16 +146,23 @@ public partial class ResourcePermissionManagementModal private async Task SearchProviderKeyAsync(AutocompleteReadDataEventArgs autocompleteReadDataEventArgs) { - if ( !autocompleteReadDataEventArgs.CancellationToken.IsCancellationRequested ) + if (autocompleteReadDataEventArgs.CancellationToken.IsCancellationRequested) { - if (autocompleteReadDataEventArgs.SearchValue.IsNullOrWhiteSpace()) - { - ProviderKeys = new List(); - return; - } + return; + } - ProviderKeys = (await PermissionAppService.SearchResourceProviderKeyAsync(ResourceName, CurrentLookupService, autocompleteReadDataEventArgs.SearchValue, 1)).Keys; + if (autocompleteReadDataEventArgs.SearchValue.IsNullOrWhiteSpace()) + { + ProviderKeys = new List(); + return; + } + var lookupService = CurrentLookupService; + var results = (await PermissionAppService.SearchResourceProviderKeyAsync(ResourceName, lookupService, autocompleteReadDataEventArgs.SearchValue, 1)).Keys; + + if (!autocompleteReadDataEventArgs.CancellationToken.IsCancellationRequested) + { + ProviderKeys = results; await InvokeAsync(StateHasChanged); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreInMemoryCache.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreInMemoryCache.cs index 15a98c84dd..902b0431d2 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreInMemoryCache.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreInMemoryCache.cs @@ -48,15 +48,19 @@ public class DynamicPermissionDefinitionStoreInMemoryCache : var context = new PermissionDefinitionContext(null); - var resourcePermissions = permissionRecords.Where(x => !x.ResourceName.IsNullOrWhiteSpace()); - foreach (var resourcePermission in resourcePermissions) + var resourcePermissionRecords = permissionRecords.Where(x => !x.ResourceName.IsNullOrWhiteSpace()); + foreach (var resourcePermissionRecord in resourcePermissionRecords) { - context.AddResourcePermission(resourcePermission.Name, - resourcePermission.ResourceName, - resourcePermission.ManagementPermissionName, - resourcePermission.DisplayName != null ? LocalizableStringSerializer.Deserialize(resourcePermission.DisplayName) : null, - resourcePermission.MultiTenancySide, - resourcePermission.IsEnabled); + var resourcePermission = context.AddResourcePermission(resourcePermissionRecord.Name, + resourcePermissionRecord.ResourceName, + resourcePermissionRecord.ManagementPermissionName, + resourcePermissionRecord.DisplayName != null ? LocalizableStringSerializer.Deserialize(resourcePermissionRecord.DisplayName) : null, + resourcePermissionRecord.MultiTenancySide, + resourcePermissionRecord.IsEnabled); + + ApplyPermissionProperties(resourcePermission, resourcePermissionRecord); + + ResourcePermissionDefinitions.Add(resourcePermission); } var permissions = permissionRecords.Where(x => x.ResourceName.IsNullOrWhiteSpace()).ToList(); @@ -124,6 +128,16 @@ public class DynamicPermissionDefinitionStoreInMemoryCache : PermissionDefinitions[permission.Name] = permission; + ApplyPermissionProperties(permission, permissionRecord); + + foreach (var subPermission in allPermissionRecords.Where(p => p.ParentName == permissionRecord.Name)) + { + AddPermissionRecursively(permission, subPermission, allPermissionRecords); + } + } + + private void ApplyPermissionProperties(PermissionDefinition permission, PermissionDefinitionRecord permissionRecord) + { if (!permissionRecord.Providers.IsNullOrWhiteSpace()) { permission.Providers.AddRange(permissionRecord.Providers.Split(',')); @@ -143,10 +157,5 @@ public class DynamicPermissionDefinitionStoreInMemoryCache : { permission[property.Key] = property.Value; } - - foreach (var subPermission in allPermissionRecords.Where(p => p.ParentName == permissionRecord.Name)) - { - AddPermissionRecursively(permission, subPermission, allPermissionRecords); - } } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs index c672207f4f..492f987f1a 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs @@ -281,7 +281,7 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc if (changedRecords.Any()) { - newOrChangedPermissions.AddRange(newRecords.Select(x => x.Name)); + newOrChangedPermissions.AddRange(changedRecords.Select(x => x.Name)); await PermissionRepository.UpdateManyAsync(changedRecords); } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/AbpPermissionManagementWebModule.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/AbpPermissionManagementWebModule.cs index e20e38c53a..1f8d1753a5 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/AbpPermissionManagementWebModule.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/AbpPermissionManagementWebModule.cs @@ -1,7 +1,9 @@ -using Microsoft.Extensions.DependencyInjection; +using Localization.Resources.AbpUi; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; using Volo.Abp.Http.ProxyScripting.Generators.JQuery; +using Volo.Abp.Localization; using Volo.Abp.Mapperly; using Volo.Abp.Modularity; using Volo.Abp.PermissionManagement.Localization; @@ -33,6 +35,13 @@ public class AbpPermissionManagementWebModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpUiResource)); + }); + Configure(options => { options.FileSets.AddEmbedded(); diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreInMemoryCache_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreInMemoryCache_Tests.cs new file mode 100644 index 0000000000..f603bbe30f --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStoreInMemoryCache_Tests.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.MultiTenancy; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public class DynamicPermissionDefinitionStoreInMemoryCache_Tests : PermissionTestBase +{ + private readonly IDynamicPermissionDefinitionStoreInMemoryCache _cache; + + public DynamicPermissionDefinitionStoreInMemoryCache_Tests() + { + _cache = GetRequiredService(); + } + + [Fact] + public async Task FillAsync_Should_Populate_ResourcePermissionDefinitions() + { + // Arrange + var permissionGroupRecords = new List(); + var permissionRecords = new List + { + new PermissionDefinitionRecord( + Guid.NewGuid(), + groupName: null, + name: "TestResourcePerm1", + resourceName: "TestResource", + managementPermissionName: "TestManagementPerm", + parentName: null, + displayName: "F:Test Resource Permission 1", + isEnabled: true, + multiTenancySide: MultiTenancySides.Both, + providers: "R,U", + stateCheckers: null + ) + }; + + // Act + await _cache.FillAsync(permissionGroupRecords, permissionRecords); + + // Assert + var resourcePermissions = _cache.GetResourcePermissions(); + resourcePermissions.Count.ShouldBe(1); + + var resourcePermission = _cache.GetResourcePermissionOrNull("TestResource", "TestResourcePerm1"); + resourcePermission.ShouldNotBeNull(); + resourcePermission.Name.ShouldBe("TestResourcePerm1"); + resourcePermission.ResourceName.ShouldBe("TestResource"); + resourcePermission.ManagementPermissionName.ShouldBe("TestManagementPerm"); + resourcePermission.IsEnabled.ShouldBeTrue(); + resourcePermission.MultiTenancySide.ShouldBe(MultiTenancySides.Both); + resourcePermission.Providers.Count.ShouldBe(2); + resourcePermission.Providers.ShouldContain("R"); + resourcePermission.Providers.ShouldContain("U"); + } + + [Fact] + public async Task FillAsync_Should_Populate_ResourcePermission_With_ExtraProperties() + { + // Arrange + var permissionGroupRecords = new List(); + var record = new PermissionDefinitionRecord( + Guid.NewGuid(), + groupName: null, + name: "TestResourcePerm2", + resourceName: "TestResource", + managementPermissionName: "TestManagementPerm", + parentName: null, + displayName: "F:Test Resource Permission 2" + ); + record.ExtraProperties["CustomProp1"] = "CustomValue1"; + + var permissionRecords = new List { record }; + + // Act + await _cache.FillAsync(permissionGroupRecords, permissionRecords); + + // Assert + var resourcePermission = _cache.GetResourcePermissionOrNull("TestResource", "TestResourcePerm2"); + resourcePermission.ShouldNotBeNull(); + resourcePermission["CustomProp1"].ShouldBe("CustomValue1"); + } + + [Fact] + public async Task FillAsync_Should_Not_Mix_Resource_And_Regular_Permissions() + { + // Arrange + var permissionGroupRecords = new List + { + new PermissionGroupDefinitionRecord( + Guid.NewGuid(), + name: "TestGroup", + displayName: "F:Test Group" + ) + }; + + var permissionRecords = new List + { + // Regular permission + new PermissionDefinitionRecord( + Guid.NewGuid(), + groupName: "TestGroup", + name: "RegularPerm1", + resourceName: null, + managementPermissionName: null, + parentName: null, + displayName: "F:Regular Permission 1" + ), + // Resource permission + new PermissionDefinitionRecord( + Guid.NewGuid(), + groupName: null, + name: "ResourcePerm1", + resourceName: "TestResource", + managementPermissionName: "ManagementPerm", + parentName: null, + displayName: "F:Resource Permission 1" + ) + }; + + // Act + await _cache.FillAsync(permissionGroupRecords, permissionRecords); + + // Assert + var regularPermissions = _cache.GetPermissions(); + regularPermissions.Count.ShouldBe(1); + regularPermissions.First().Name.ShouldBe("RegularPerm1"); + + var resourcePermissions = _cache.GetResourcePermissions(); + resourcePermissions.Count.ShouldBe(1); + resourcePermissions.First().Name.ShouldBe("ResourcePerm1"); + + _cache.GetPermissionOrNull("RegularPerm1").ShouldNotBeNull(); + _cache.GetPermissionOrNull("ResourcePerm1").ShouldBeNull(); + + _cache.GetResourcePermissionOrNull("TestResource", "ResourcePerm1").ShouldNotBeNull(); + _cache.GetResourcePermissionOrNull("TestResource", "RegularPerm1").ShouldBeNull(); + } + + [Fact] + public async Task FillAsync_Should_Populate_ResourcePermission_With_StateCheckers() + { + // Arrange + var permissionGroupRecords = new List(); + var permissionRecords = new List + { + new PermissionDefinitionRecord( + Guid.NewGuid(), + groupName: null, + name: "TestResourcePerm3", + resourceName: "TestResource", + managementPermissionName: "TestManagementPerm", + parentName: null, + displayName: "F:Test Resource Permission 3", + stateCheckers: "[{\"T\":\"A\"}]" + ) + }; + + // Act + await _cache.FillAsync(permissionGroupRecords, permissionRecords); + + // Assert + var resourcePermission = _cache.GetResourcePermissionOrNull("TestResource", "TestResourcePerm3"); + resourcePermission.ShouldNotBeNull(); + resourcePermission.StateCheckers.Count.ShouldBe(1); + } + + [Fact] + public async Task FillAsync_Should_Clear_Previous_ResourcePermissions() + { + // Arrange - first fill + var permissionRecords1 = new List + { + new PermissionDefinitionRecord( + Guid.NewGuid(), + groupName: null, + name: "OldResourcePerm", + resourceName: "TestResource", + managementPermissionName: "ManagementPerm", + parentName: null, + displayName: "F:Old Resource Permission" + ) + }; + await _cache.FillAsync(new List(), permissionRecords1); + _cache.GetResourcePermissions().Count.ShouldBe(1); + + // Arrange - second fill with different data + var permissionRecords2 = new List + { + new PermissionDefinitionRecord( + Guid.NewGuid(), + groupName: null, + name: "NewResourcePerm", + resourceName: "TestResource", + managementPermissionName: "ManagementPerm", + parentName: null, + displayName: "F:New Resource Permission" + ) + }; + + // Act + await _cache.FillAsync(new List(), permissionRecords2); + + // Assert + var resourcePermissions = _cache.GetResourcePermissions(); + resourcePermissions.Count.ShouldBe(1); + resourcePermissions.First().Name.ShouldBe("NewResourcePerm"); + _cache.GetResourcePermissionOrNull("TestResource", "OldResourcePerm").ShouldBeNull(); + } +}