From 470cfdacdeab5b95e07259705035c9eeafce7898 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 21 Nov 2025 14:50:46 +0800 Subject: [PATCH] Support resource permissions in permission serialization --- .../IPermissionDefinitionSerializer.cs | 5 +- .../PermissionDefinitionRecord.cs | 6 +- .../PermissionDefinitionSerializer.cs | 17 ++++- .../StaticPermissionSaver.cs | 6 ++ ...nagementDbContextModelBuilderExtensions.cs | 3 +- ...missionDefinitionRecordRepository_Tests.cs | 15 +++++ .../PermissionDefinitionSerializer_Tests.cs | 64 +++++++++++++++---- ...rmissionGrantCacheItemInvalidator_Tests.cs | 2 +- ...missionDefinitionRecordRepository_Tests.cs | 2 +- ...estResourcePermissionDefinitionProvider.cs | 2 +- 10 files changed, 100 insertions(+), 22 deletions(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionDefinitionSerializer.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionDefinitionSerializer.cs index 8ed09a4380..3c5f4a8783 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionDefinitionSerializer.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionDefinitionSerializer.cs @@ -10,10 +10,13 @@ public interface IPermissionDefinitionSerializer Task<(PermissionGroupDefinitionRecord[], PermissionDefinitionRecord[])> SerializeAsync(IEnumerable permissionGroups); + Task SerializeAsync( + IEnumerable permissions); + Task SerializeAsync( PermissionGroupDefinition permissionGroup); Task SerializeAsync( PermissionDefinition permission, [CanBeNull] PermissionGroupDefinition permissionGroup); -} \ No newline at end of file +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionRecord.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionRecord.cs index a513beafe9..0ef2032452 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionRecord.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionRecord.cs @@ -53,7 +53,11 @@ public class PermissionDefinitionRecord : BasicAggregateRoot, IHasExtraPro string stateCheckers = null) : base(id) { - GroupName = Check.NotNullOrWhiteSpace(groupName, nameof(groupName), PermissionGroupDefinitionRecordConsts.MaxNameLength); + GroupName = groupName; + if (resourceName == null) + { + GroupName = Check.NotNullOrWhiteSpace(groupName, nameof(groupName), PermissionGroupDefinitionRecordConsts.MaxNameLength); + } Name = Check.NotNullOrWhiteSpace(name, nameof(name), PermissionDefinitionRecordConsts.MaxNameLength); ResourceName = resourceName; ParentName = Check.Length(parentName, nameof(parentName), PermissionDefinitionRecordConsts.MaxNameLength); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer.cs index 5d07e81a94..e5df5201cd 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer.cs @@ -27,7 +27,7 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I GuidGenerator = guidGenerator; } - public async Task<(PermissionGroupDefinitionRecord[], PermissionDefinitionRecord[])> + public virtual async Task<(PermissionGroupDefinitionRecord[], PermissionDefinitionRecord[])> SerializeAsync(IEnumerable permissionGroups) { var permissionGroupRecords = new List(); @@ -46,7 +46,18 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I return (permissionGroupRecords.ToArray(), permissionRecords.ToArray()); } - public Task SerializeAsync(PermissionGroupDefinition permissionGroup) + public virtual async Task SerializeAsync(IEnumerable permissions) + { + var permissionRecords = new List(); + foreach (var permission in permissions) + { + permissionRecords.Add(await SerializeAsync(permission, null)); + } + + return permissionRecords.ToArray(); + } + + public virtual Task SerializeAsync(PermissionGroupDefinition permissionGroup) { using (CultureHelper.Use(CultureInfo.InvariantCulture)) { @@ -65,7 +76,7 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I } } - public Task SerializeAsync( + public virtual Task SerializeAsync( PermissionDefinition permission, PermissionGroupDefinition permissionGroup) { 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 d1dff35f35..c672207f4f 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 @@ -85,6 +85,12 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc await StaticStore.GetGroupsAsync() ); + var resourcePermissions = await PermissionSerializer.SerializeAsync( + await StaticStore.GetResourcePermissionsAsync() + ); + + permissionRecords = permissionRecords.Union(resourcePermissions).ToArray(); + var currentHash = CalculateHash( permissionGroupRecords, permissionRecords, diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementDbContextModelBuilderExtensions.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementDbContextModelBuilderExtensions.cs index e1e569cd06..fa9fa6de12 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementDbContextModelBuilderExtensions.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementDbContextModelBuilderExtensions.cs @@ -69,8 +69,7 @@ public static class AbpPermissionManagementDbContextModelBuilderExtensions b.ConfigureByConvention(); - b.Property(x => x.GroupName).HasMaxLength(PermissionGroupDefinitionRecordConsts.MaxNameLength) - .IsRequired(); + b.Property(x => x.GroupName).HasMaxLength(PermissionGroupDefinitionRecordConsts.MaxNameLength); b.Property(x => x.Name).HasMaxLength(PermissionDefinitionRecordConsts.MaxNameLength).IsRequired(); b.Property(x => x.ResourceName).HasMaxLength(PermissionDefinitionRecordConsts.MaxResourceNameLength); b.Property(x => x.ParentName).HasMaxLength(PermissionDefinitionRecordConsts.MaxNameLength); diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionRecordRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionRecordRepository_Tests.cs index d7ca406624..62369869c4 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionRecordRepository_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionRecordRepository_Tests.cs @@ -26,4 +26,19 @@ public abstract class PermissionDefinitionRecordRepository_Tests permission.ShouldNotBeNull(); permission.Name.ShouldBe("MyPermission2"); } + + [Fact] + public async Task FindByResourceNameAsync() + { + var qq = await PermissionDefinitionRecordRepository.GetListAsync(); + var permission = await PermissionDefinitionRecordRepository.FindByNameAsync("MyResourcePermission1"); + permission.ShouldNotBeNull(); + permission.ResourceName.ShouldBe(TestEntityResource.ResourceName); + permission.Name.ShouldBe("MyResourcePermission1"); + + permission = await PermissionDefinitionRecordRepository.FindByNameAsync("MyResourcePermission2"); + permission.ShouldNotBeNull(); + permission.ResourceName.ShouldBe(TestEntityResource.ResourceName); + permission.Name.ShouldBe("MyResourcePermission2"); + } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer_Tests.cs index 1e7c04580c..231626de72 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer_Tests.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.PermissionManagement; public class PermissionDefinitionSerializer_Tests : PermissionTestBase { private readonly IPermissionDefinitionSerializer _serializer; - + public PermissionDefinitionSerializer_Tests() { _serializer = GetRequiredService(); @@ -26,26 +26,26 @@ public class PermissionDefinitionSerializer_Tests : PermissionTestBase public async Task Serialize_Permission_Group_Definition() { // Arrange - + var context = new PermissionDefinitionContext(null); var group1 = CreatePermissionGroup1(context); - + // Act var permissionGroupRecord = await _serializer.SerializeAsync(group1); - + //Assert permissionGroupRecord.Name.ShouldBe("Group1"); permissionGroupRecord.DisplayName.ShouldBe("F:Group one"); permissionGroupRecord.GetProperty("CustomProperty1").ShouldBe("CustomValue1"); } - + [Fact] public async Task Serialize_Complex_Permission_Definition() { // Arrange - + var context = new PermissionDefinitionContext(null); var group1 = CreatePermissionGroup1(context); var permission1 = group1.AddPermission( @@ -61,14 +61,14 @@ public class PermissionDefinitionSerializer_Tests : PermissionTestBase .RequirePermissions(requiresAll: false, batchCheck: false,"Permission2", "Permission3"); // Act - + var permissionRecord = await _serializer.SerializeAsync( permission1, group1 ); - + //Assert - + permissionRecord.Name.ShouldBe("Permission1"); permissionRecord.GroupName.ShouldBe("Group1"); permissionRecord.DisplayName.ShouldBe("L:AbpPermissionManagement,Permission1"); @@ -78,6 +78,46 @@ public class PermissionDefinitionSerializer_Tests : PermissionTestBase permissionRecord.StateCheckers.ShouldBe("[{\"T\":\"A\"},{\"T\":\"G\",\"A\":true,\"N\":[\"GlobalFeature1\",\"GlobalFeature2\"]},{\"T\":\"F\",\"A\":true,\"N\":[\"Feature1\",\"Feature2\"]},{\"T\":\"P\",\"A\":false,\"N\":[\"Permission2\",\"Permission3\"]}]"); } + + [Fact] + public async Task Serialize_Complex_Resource_Permission_Definition() + { + // Arrange + + var context = new PermissionDefinitionContext(null); + var resourcePermission1 = context.AddResourcePermission( + "ResourcePermission1", + TestEntityResource.ResourceName, + new LocalizableString(typeof(AbpPermissionManagementResource), "ResourcePermission1"), + MultiTenancySides.Tenant + ) + .WithProviders("ProviderA", "ProviderB") + .WithProperty("CustomProperty2", "CustomValue2") + .RequireAuthenticated() //For for testing, not so meaningful + .RequireGlobalFeatures("GlobalFeature1", "GlobalFeature2") + .RequireFeatures("Feature1", "Feature2") + .RequirePermissions(requiresAll: false, batchCheck: false,"Permission2", "Permission3"); + + // Act + + var permissionRecord = await _serializer.SerializeAsync( + resourcePermission1, + null + ); + + //Assert + + permissionRecord.Name.ShouldBe("ResourcePermission1"); + permissionRecord.GroupName.ShouldBe(null); + permissionRecord.ResourceName.ShouldBe(TestEntityResource.ResourceName); + permissionRecord.DisplayName.ShouldBe("L:AbpPermissionManagement,ResourcePermission1"); + permissionRecord.GetProperty("CustomProperty2").ShouldBe("CustomValue2"); + permissionRecord.Providers.ShouldBe("ProviderA,ProviderB"); + permissionRecord.MultiTenancySide.ShouldBe(MultiTenancySides.Tenant); + permissionRecord.StateCheckers.ShouldBe("[{\"T\":\"A\"},{\"T\":\"G\",\"A\":true,\"N\":[\"GlobalFeature1\",\"GlobalFeature2\"]},{\"T\":\"F\",\"A\":true,\"N\":[\"Feature1\",\"Feature2\"]},{\"T\":\"P\",\"A\":false,\"N\":[\"Permission2\",\"Permission3\"]}]"); + } + + private static PermissionGroupDefinition CreatePermissionGroup1( IPermissionDefinitionContext context) { @@ -85,9 +125,9 @@ public class PermissionDefinitionSerializer_Tests : PermissionTestBase "Group1", displayName: new FixedLocalizableString("Group one") ); - + group["CustomProperty1"] = "CustomValue1"; - + return group; } -} \ No newline at end of file +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItemInvalidator_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItemInvalidator_Tests.cs index 356290029e..3bdc4ee69e 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItemInvalidator_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItemInvalidator_Tests.cs @@ -58,7 +58,7 @@ public class ResourcePermissionGrantCacheItemInvalidator_Tests : PermissionTestB UserPermissionValueProvider.ProviderName, PermissionTestDataBuilder.User1Id.ToString()); resourcePermissionGrant.ShouldNotBeNull(); - await _resourcePermissionGrantRepository.DeleteAsync(permissionGrant); + await _resourcePermissionGrantRepository.DeleteAsync(resourcePermissionGrant); (await _cache.GetAsync(ResourcePermissionGrantCacheItem.CalculateCacheKey("MyResourcePermission1", TestEntityResource.ResourceName, diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoDbPermissionDefinitionRecordRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoDbPermissionDefinitionRecordRepository_Tests.cs index d43634cdb9..30f09c5720 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoDbPermissionDefinitionRecordRepository_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoDbPermissionDefinitionRecordRepository_Tests.cs @@ -3,7 +3,7 @@ namespace Volo.Abp.PermissionManagement.MongoDB; [Collection(MongoTestCollection.Name)] -public class MongoDbPermissionDefinitionRecordRepository_Tests : PermissionGrantRepository_Tests +public class MongoDbPermissionDefinitionRecordRepository_Tests : PermissionDefinitionRecordRepository_Tests { } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionDefinitionProvider.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionDefinitionProvider.cs index 9e52d02eab..e255419313 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionDefinitionProvider.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionDefinitionProvider.cs @@ -3,7 +3,7 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.PermissionManagement; -public class TestResourcePermissionDefinitionProvider: PermissionDefinitionProvider +public class TestResourcePermissionDefinitionProvider : PermissionDefinitionProvider { public override void Define(IPermissionDefinitionContext context) {