diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IHasResourcePermissions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IHasResourcePermissions.cs index 128c3065fd..903f6bd2d6 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IHasResourcePermissions.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IHasResourcePermissions.cs @@ -2,9 +2,7 @@ using System.Collections.Generic; namespace Volo.Abp.Authorization.Permissions.Resources; -public interface IHasResourcePermissions +public interface IHasResourcePermissions : IKeyedObject { - public Dictionary ResourcePermissions { get; } - - string GetResourceKey(); + Dictionary ResourcePermissions { get; } } 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 700f9104cf..e3684263a0 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 @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -42,13 +43,20 @@ public class ResourcePermissionPopulator : ITransientDependency foreach (var resource in resources) { - var results = await ResourcePermissionChecker.IsGrantedAsync(resopurcePermissionNames, resourceName, resource.GetResourceKey()); + var resourceKey = resource.GetObjectKey(); + if (resourceKey.IsNullOrEmpty()) + { + throw new AbpException("Resource key can not be null or empty."); + } + + var results = await ResourcePermissionChecker.IsGrantedAsync(resopurcePermissionNames, resourceName, resourceKey); foreach (var resopurcePermission in resopurcePermissionNames) { - if(resource.ResourcePermissions == null) + 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; } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IKeyedObject.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IKeyedObject.cs new file mode 100644 index 0000000000..d0cbb47790 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IKeyedObject.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp; + +public interface IKeyedObject +{ + string? GetObjectKey(); +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/KeyedObjectHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/KeyedObjectHelper.cs new file mode 100644 index 0000000000..9757e67ecc --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/KeyedObjectHelper.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Volo.Abp; + +public static class KeyedObjectHelper +{ + public static string EncodeCompositeKey(params object?[] keys) + { + var raw = keys.JoinAsString("||"); + var bytes = Encoding.UTF8.GetBytes(raw); + var base64 = Convert.ToBase64String(bytes); + var base64Url = base64 + .Replace("+", "-") + .Replace("/", "_") + .TrimEnd('='); + + return base64Url; + } + + public static string DecodeCompositeKey(string encoded) + { + var base64 = encoded + .Replace("-", "+") + .Replace("_", "/"); + + switch (encoded.Length % 4) + { + case 2: base64 += "=="; break; + case 3: base64 += "="; break; + } + + var bytes = Convert.FromBase64String(base64); + var raw = Encoding.UTF8.GetString(bytes); + + return raw; + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs index 656e63b0d5..16c81c2f92 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs @@ -23,4 +23,9 @@ public abstract class EntityDto : EntityDto, IEntityDto { return $"[DTO: {GetType().Name}] Id = {Id}"; } + + public virtual string? GetObjectKey() + { + return Id?.ToString(); + } } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs index 9687af0cf7..16379f865c 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs @@ -27,6 +27,11 @@ public abstract class ExtensibleEntityDto : ExtensibleObject, IEntityDto : IEntityDto +public interface IEntityDto : IEntityDto, IKeyedObject { TKey Id { get; set; } } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs index 9e52d1abfd..93c5555a39 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs @@ -18,6 +18,17 @@ public abstract class Entity : IEntity return $"[ENTITY: {GetType().Name}] Keys = {GetKeys().JoinAsString(", ")}"; } + public virtual string? GetObjectKey() + { + var keys = GetKeys(); + return keys.Length switch + { + 0 => null, + 1 when keys[0] != null => keys[0]?.ToString(), + _ => KeyedObjectHelper.EncodeCompositeKey(keys) + }; + } + public abstract object?[] GetKeys(); public bool EntityEquals(IEntity other) @@ -45,7 +56,7 @@ public abstract class Entity : Entity, IEntity public override object?[] GetKeys() { - return new object?[] { Id }; + return [Id]; } /// diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs index 1df1b75696..db4a144539 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs @@ -4,7 +4,7 @@ /// Defines an entity. It's primary key may not be "Id" or it may have a composite primary key. /// Use where possible for better integration to repositories and other structures in the framework. /// -public interface IEntity +public interface IEntity : IKeyedObject { /// /// Returns an array of ordered keys for this entity.