diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs index 4bdd7c0bb8..c240e1ac07 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Volo.Abp.Authorization.Permissions.Resources; using Volo.Abp.Collections; namespace Volo.Abp.Authorization.Permissions; @@ -9,6 +10,8 @@ public class AbpPermissionOptions public ITypeList ValueProviders { get; } + public ITypeList ResourceValueProviders { get; } + public HashSet DeletedPermissions { get; } public HashSet DeletedPermissionGroups { get; } @@ -17,6 +20,7 @@ public class AbpPermissionOptions { DefinitionProviders = new TypeList(); ValueProviders = new TypeList(); + ResourceValueProviders = new TypeList(); DeletedPermissions = new HashSet(); DeletedPermissionGroups = new HashSet(); diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/ICanAddChildPermission.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/ICanAddChildPermission.cs index 828e4cbd01..2bcf9ba10d 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/ICanAddChildPermission.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/ICanAddChildPermission.cs @@ -11,4 +11,4 @@ public interface ICanAddChildPermission ILocalizableString? displayName = null, MultiTenancySides multiTenancySide = MultiTenancySides.Both, bool isEnabled = true); -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs index 7ff890bac7..5a1bef8e1d 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs @@ -1,5 +1,7 @@ using System; +using JetBrains.Annotations; using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; @@ -46,4 +48,16 @@ public interface IPermissionDefinitionContext /// Name of the permission /// PermissionDefinition? GetPermissionOrNull(string name); + + PermissionDefinition AddResourcePermission( + string name, + string resourceName, + string managementPermissionName, + ILocalizableString? displayName = null, + MultiTenancySides multiTenancySide = MultiTenancySides.Both, + bool isEnabled = true); + + PermissionDefinition? GetResourcePermissionOrNull([NotNull] string resourceName, [NotNull] string name); + + void RemoveResourcePermission([NotNull] string resourceName, [NotNull] string name); } diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs index ca04b110f7..d9411d54fa 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionDefinitionManager.cs @@ -11,7 +11,14 @@ public interface IPermissionDefinitionManager Task GetOrNullAsync([NotNull] string name); + [ItemNotNull] + Task GetResourcePermissionAsync([NotNull]string resourceName, [NotNull] string name); + + Task GetResourcePermissionOrNullAsync([NotNull]string resourceName, [NotNull] string name); + Task> GetPermissionsAsync(); + Task> GetResourcePermissionsAsync(); + Task> GetGroupsAsync(); } diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs index ae9252632d..683f513cf4 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionValueProvider.cs @@ -6,7 +6,6 @@ public interface IPermissionValueProvider { string Name { get; } - //TODO: Rename to GetResult? (CheckAsync throws exception by naming convention) Task CheckAsync(PermissionValueCheckContext context); Task CheckAsync(PermissionValuesCheckContext context); diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs index 0f5d713e2b..c93992ed49 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs @@ -7,7 +7,7 @@ using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization.Permissions; -public class PermissionDefinition : +public class PermissionDefinition : IHasSimpleStateCheckers, ICanAddChildPermission { @@ -16,6 +16,16 @@ public class PermissionDefinition : /// public string Name { get; } + /// + /// Resource name of the permission. + /// + public string? ResourceName { get; set; } + + /// + /// Management permission of the resource permission. + /// + public string? ManagementPermissionName { get; set; } + /// /// Parent of this permission if one exists. /// If set, this permission can be granted only if parent is granted. @@ -76,6 +86,19 @@ public class PermissionDefinition : set => Properties[name] = value; } + protected internal PermissionDefinition( + [NotNull] string name, + string resourceName, + string managementPermissionName, + ILocalizableString? displayName = null, + MultiTenancySides multiTenancySide = MultiTenancySides.Both, + bool isEnabled = true) + : this(name, displayName, multiTenancySide, isEnabled) + { + ResourceName = Check.NotNull(resourceName, nameof(resourceName)); + ManagementPermissionName = Check.NotNull(managementPermissionName, nameof(managementPermissionName)); + } + protected internal PermissionDefinition( [NotNull] string name, ILocalizableString? displayName = null, @@ -99,6 +122,11 @@ public class PermissionDefinition : MultiTenancySides multiTenancySide = MultiTenancySides.Both, bool isEnabled = true) { + if (ResourceName != null) + { + throw new AbpException($"Resource permission cannot have child permissions. Resource: {ResourceName}"); + } + var child = new PermissionDefinition( name, displayName, @@ -109,12 +137,12 @@ public class PermissionDefinition : }; child[PermissionDefinitionContext.KnownPropertyNames.CurrentProviderName] = this[PermissionDefinitionContext.KnownPropertyNames.CurrentProviderName]; - + _children.Add(child); return child; } - + PermissionDefinition ICanAddChildPermission.AddPermission( string name, ILocalizableString? displayName = null, @@ -124,7 +152,6 @@ public class PermissionDefinition : return this.AddChild(name, displayName, multiTenancySide, isEnabled); } - /// /// Sets a property in the dictionary. /// This is a shortcut for nested calls on this object. diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs index 394cdb9d82..c13f53866a 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using JetBrains.Annotations; using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; @@ -11,17 +13,20 @@ public class PermissionDefinitionContext : IPermissionDefinitionContext public Dictionary Groups { get; } + public List ResourcePermissions { get; } + internal IPermissionDefinitionProvider? CurrentProvider { get; set; } public static class KnownPropertyNames { public const string CurrentProviderName = "_CurrentProviderName"; } - + public PermissionDefinitionContext(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; Groups = new Dictionary(); + ResourcePermissions = new List(); } public virtual PermissionGroupDefinition AddGroup( @@ -43,7 +48,7 @@ public class PermissionDefinitionContext : IPermissionDefinitionContext } Groups[name] = group; - + return group; } @@ -51,37 +56,23 @@ public class PermissionDefinitionContext : IPermissionDefinitionContext public virtual PermissionGroupDefinition GetGroup([NotNull] string name) { var group = GetGroupOrNull(name); - - if (group == null) - { - throw new AbpException($"Could not find a permission definition group with the given name: {name}"); - } - - return group; + return group ?? throw new AbpException($"Could not find a permission definition group with the given name: {name}"); } public virtual PermissionGroupDefinition? GetGroupOrNull([NotNull] string name) { Check.NotNull(name, nameof(name)); - - if (!Groups.ContainsKey(name)) - { - return null; - } - - return Groups[name]; + return Groups.GetOrDefault(name); } public virtual void RemoveGroup(string name) { Check.NotNull(name, nameof(name)); - if (!Groups.ContainsKey(name)) + if (!Groups.Remove(name)) { throw new AbpException($"Not found permission group with name: {name}"); } - - Groups.Remove(name); } public virtual PermissionDefinition? GetPermissionOrNull([NotNull] string name) @@ -100,4 +91,58 @@ public class PermissionDefinitionContext : IPermissionDefinitionContext return null; } + + public virtual PermissionDefinition AddResourcePermission( + string name, + string resourceName, + string managementPermissionName, + ILocalizableString? displayName = null, + MultiTenancySides multiTenancySide = MultiTenancySides.Both, + bool isEnabled = true) + { + Check.NotNull(name, nameof(name)); + Check.NotNull(resourceName, nameof(resourceName)); + Check.NotNull(managementPermissionName, nameof(managementPermissionName)); + + if (ResourcePermissions.Any(x => x.ResourceName == resourceName && x.Name == name)) + { + throw new AbpException($"There is already an existing resource permission with name: {name} for resource: {resourceName}"); + } + + var permission = new PermissionDefinition( + name, + resourceName, + managementPermissionName, + displayName, + multiTenancySide, + isEnabled) + { + [KnownPropertyNames.CurrentProviderName] = CurrentProvider?.GetType().FullName + }; + + ResourcePermissions.Add(permission); + + return permission; + } + + public virtual PermissionDefinition? GetResourcePermissionOrNull([NotNull] string resourceName, [NotNull] string name) + { + Check.NotNull(resourceName, nameof(resourceName)); + Check.NotNull(name, nameof(name)); + + return ResourcePermissions.FirstOrDefault(p => p.ResourceName == resourceName && p.Name == name); + } + + public virtual void RemoveResourcePermission([NotNull] string resourceName, [NotNull] string name) + { + Check.NotNull(resourceName, nameof(resourceName)); + Check.NotNull(name, nameof(name)); + + var resourcePermission = GetResourcePermissionOrNull(resourceName, name); + if (resourcePermission == null) + { + throw new AbpException($"Not found resource permission with name: {name} for resource: {resourceName}"); + } + ResourcePermissions.Remove(resourcePermission); + } } 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 new file mode 100644 index 0000000000..903f6bd2d6 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IHasResourcePermissions.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public interface IHasResourcePermissions : IKeyedObject +{ + Dictionary ResourcePermissions { get; } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionChecker.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionChecker.cs new file mode 100644 index 0000000000..0270d2c96b --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionChecker.cs @@ -0,0 +1,33 @@ +using System.Security.Claims; +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public interface IResourcePermissionChecker +{ + Task IsGrantedAsync( + string name, + string resourceName, + string resourceKey + ); + + Task IsGrantedAsync( + ClaimsPrincipal? claimsPrincipal, + string name, + string resourceName, + string resourceKey + ); + + Task IsGrantedAsync( + string[] names, + string resourceName, + string resourceKey + ); + + Task IsGrantedAsync( + ClaimsPrincipal? claimsPrincipal, + string[] names, + string resourceName, + string resourceKey + ); +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionStore.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionStore.cs new file mode 100644 index 0000000000..42f751b4c5 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionStore.cs @@ -0,0 +1,83 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public interface IResourcePermissionStore +{ + /// + /// Checks if the given permission is granted for the given resource. + /// + /// The name of the permission. + /// The name of the resource. + /// Resource key + /// The name of the provider. + /// The key of the provider. + /// + /// True if the permission is granted. + /// + Task IsGrantedAsync( + string name, + string resourceName, + string resourceKey, + string providerName, + string providerKey + ); + + /// + /// Checks if the given permissions are granted for the given resource. + /// + /// The name of the permissions. + /// The name of the resource. + /// Resource key + /// The name of the provider. + /// The key of the provider. + /// + /// A object containing the grant results for each permission. + /// + Task IsGrantedAsync( + string[] names, + string resourceName, + string resourceKey, + string providerName, + string providerKey + ); + + /// + /// Gets all permissions for the given resource. + /// + /// Resource name + /// Resource key + /// + /// A object containing the grant results for each permission. + /// + Task GetPermissionsAsync( + string resourceName, + string resourceKey + ); + + /// + /// Gets all granted permissions for the given resource. + /// + /// Resource name + /// Resource key + /// + /// An array of granted permission names. + /// + Task GetGrantedPermissionsAsync( + string resourceName, + string resourceKey + ); + + /// + /// Retrieves the keys of resources for which the specified permission is granted. + /// + /// The name of the resource. + /// The name of the permission. + /// + /// An array of resource keys where the specified permission is granted. + /// + Task GetGrantedResourceKeysAsync( + string resourceName, + string name + ); +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProvider.cs new file mode 100644 index 0000000000..288b878e5d --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProvider.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public interface IResourcePermissionValueProvider +{ + string Name { get; } + + Task CheckAsync(ResourcePermissionValueCheckContext context); + + Task CheckAsync(ResourcePermissionValuesCheckContext context); +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProviderManager.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProviderManager.cs new file mode 100644 index 0000000000..e07e63d06a --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/IResourcePermissionValueProviderManager.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public interface IResourcePermissionValueProviderManager +{ + IReadOnlyList ValueProviders { get; } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/NullResourcePermissionStore.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/NullResourcePermissionStore.cs new file mode 100644 index 0000000000..84bf38ef42 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/NullResourcePermissionStore.cs @@ -0,0 +1,43 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class NullResourcePermissionStore : IResourcePermissionStore, ISingletonDependency +{ + public ILogger Logger { get; set; } + + public NullResourcePermissionStore() + { + Logger = NullLogger.Instance; + } + + public Task IsGrantedAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + return TaskCache.FalseResult; + } + + public Task IsGrantedAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) + { + return Task.FromResult(new MultiplePermissionGrantResult(names, PermissionGrantResult.Prohibited)); + } + + public Task GetPermissionsAsync(string resourceName, string resourceKey) + { + return Task.FromResult(new MultiplePermissionGrantResult()); + } + + public Task GetGrantedPermissionsAsync(string resourceName, string resourceKey) + { + return Task.FromResult(Array.Empty()); + } + + public Task GetGrantedResourceKeysAsync(string resourceName, string name) + { + return Task.FromResult(Array.Empty()); + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionCheckerExtensions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionCheckerExtensions.cs new file mode 100644 index 0000000000..c1d153b246 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionCheckerExtensions.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public static class ResourcePermissionCheckerExtensions +{ + /// + /// Checks if a specific permission is granted for a resource with a given key. + /// + /// The type of the resource. + /// The resource permission checker instance. + /// The name of the permission to check. + /// The resource instance to check permission for. + /// The unique key identifying the resource instance. + /// A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the permission is granted. + public static Task IsGrantedAsync( + this IResourcePermissionChecker resourcePermissionChecker, + string permissionName, + TResource resource, + object resourceKey + ) + { + Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); + Check.NotNull(resource, nameof(resource)); + Check.NotNull(resourceKey, nameof(resourceKey)); + + return resourcePermissionChecker.IsGrantedAsync( + permissionName, + typeof(TResource).FullName!, + resourceKey.ToString()! + ); + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionGrantInfo.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionGrantInfo.cs new file mode 100644 index 0000000000..4eb9604454 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionGrantInfo.cs @@ -0,0 +1,21 @@ +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionGrantInfo : PermissionGrantInfo +{ + public string ResourceName { get; } + + public string ResourceKey { get; } + + public ResourcePermissionGrantInfo( + string name, + bool isGranted, + string resourceName, + string resourceKey, + string? providerName = null, + string? providerKey = null) + : base(name, isGranted, providerName, providerKey) + { + ResourceName = resourceName; + ResourceKey = resourceKey; + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionStoreExtensions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionStoreExtensions.cs new file mode 100644 index 0000000000..f5604a7683 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionStoreExtensions.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public static class ResourcePermissionStoreExtensions +{ + /// + /// Retrieves the list of granted permissions for a specific resource with a given key. + /// + /// The type of the resource. + /// The resource permission store instance. + /// The resource instance to retrieve permissions for. + /// The unique key identifying the resource instance. + /// A task that represents the asynchronous operation. The task result contains an array of strings representing the granted permissions. + public static async Task GetGrantedPermissionsAsync( + this IResourcePermissionStore resourcePermissionStore, + TResource resource, + object resourceKey + ) + { + return (await GetPermissionsAsync(resourcePermissionStore, resource, resourceKey)).Where(x => x.Value).Select(x => x.Key).ToArray(); + } + + /// + /// Retrieves a dictionary of permissions and their granted status for the specified entity. + /// + /// The type of the resource. + /// The resource permission store instance. + /// The resource for which the permissions are being retrieved. + /// The unique key identifying the resource instance. + /// A dictionary where the keys are permission names and the values are booleans indicating whether the permission is granted. + public static async Task> GetPermissionsAsync( + this IResourcePermissionStore resourcePermissionStore, + TResource resource, + object resourceKey + ) + { + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); + Check.NotNull(resource, nameof(resource)); + Check.NotNull(resourceKey, nameof(resourceKey)); + + var result = await resourcePermissionStore.GetPermissionsAsync( + typeof(TResource).FullName!, + resourceKey.ToString()! + ); + + return result.Result.ToDictionary(x => x.Key, x => x.Value == PermissionGrantResult.Granted); + } + + /// + /// Retrieves the keys of the resources granted a specific permission. + /// + /// The type of the resource. + /// The resource permission store instance. + /// The resource instance to check granted permissions for. + /// The name of the permission to check. + /// A task that represents the asynchronous operation. The task result contains an array of strings representing the granted resource keys. + public static Task GetGrantedResourceKeysAsync( + this IResourcePermissionStore resourcePermissionStore, + TResource resource, + string permissionName + ) + { + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); + Check.NotNull(resource, nameof(resource)); + Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); + + return resourcePermissionStore.GetGrantedResourceKeysAsync( + typeof(TResource).FullName!, + permissionName + ); + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueCheckContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueCheckContext.cs new file mode 100644 index 0000000000..dc8c78be64 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueCheckContext.cs @@ -0,0 +1,22 @@ +using System.Security.Claims; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionValueCheckContext : PermissionValueCheckContext +{ + public string ResourceName { get; } + + public string ResourceKey { get; } + + public ResourcePermissionValueCheckContext(PermissionDefinition permission, string resourceName, string resourceKey) + : this(permission, null, resourceName, resourceKey) + { + } + + public ResourcePermissionValueCheckContext(PermissionDefinition permission, ClaimsPrincipal? principal, string resourceName, string resourceKey) + : base(permission, principal) + { + ResourceName = resourceName; + ResourceKey = resourceKey; + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProvider.cs new file mode 100644 index 0000000000..ff53f274ad --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProvider.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public abstract class ResourcePermissionValueProvider : IResourcePermissionValueProvider, ITransientDependency +{ + public abstract string Name { get; } + + protected IResourcePermissionStore ResourcePermissionStore { get; } + + protected ResourcePermissionValueProvider(IResourcePermissionStore resourcePermissionStore) + { + ResourcePermissionStore = resourcePermissionStore; + } + + public abstract Task CheckAsync(ResourcePermissionValueCheckContext context); + + public abstract Task CheckAsync(ResourcePermissionValuesCheckContext context); +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValuesCheckContext.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValuesCheckContext.cs new file mode 100644 index 0000000000..239f74fc19 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValuesCheckContext.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Security.Claims; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionValuesCheckContext : PermissionValuesCheckContext +{ + public string ResourceName { get; } + + public string ResourceKey { get; } + + public ResourcePermissionValuesCheckContext(PermissionDefinition permission,string resourceName, string resourceKey) + : this([permission], null, resourceName, resourceKey) + { + + } + + + public ResourcePermissionValuesCheckContext(PermissionDefinition permission, ClaimsPrincipal? principal, string resourceName, string resourceKey) + : this([permission], principal, resourceName, resourceKey) + { + + } + + public ResourcePermissionValuesCheckContext(List permissions, string resourceName, string resourceKey) + : this(permissions, null, resourceName, resourceKey) + { + ResourceName = resourceName; + ResourceKey = resourceKey; + } + + public ResourcePermissionValuesCheckContext(List permissions, ClaimsPrincipal? principal, string resourceName, string resourceKey) + : base(permissions, principal) + { + ResourceName = resourceName; + ResourceKey = resourceKey; + } +} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/ResourcePermissionRequirement.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/ResourcePermissionRequirement.cs new file mode 100644 index 0000000000..03658f3e90 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/ResourcePermissionRequirement.cs @@ -0,0 +1,21 @@ +using JetBrains.Annotations; +using Microsoft.AspNetCore.Authorization; + +namespace Volo.Abp.Authorization; + +public class ResourcePermissionRequirement : IAuthorizationRequirement +{ + public string PermissionName { get; } + + public ResourcePermissionRequirement([NotNull] string permissionName) + { + Check.NotNull(permissionName, nameof(permissionName)); + + PermissionName = permissionName; + } + + public override string ToString() + { + return $"ResourcePermissionRequirement: {PermissionName}"; + } +} diff --git a/framework/src/Volo.Abp.Authorization/Microsoft/Extensions/DependencyInjection/KeyedObjectResourcePermissionExtenstions.cs b/framework/src/Volo.Abp.Authorization/Microsoft/Extensions/DependencyInjection/KeyedObjectResourcePermissionExtenstions.cs new file mode 100644 index 0000000000..e65d5174de --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Microsoft/Extensions/DependencyInjection/KeyedObjectResourcePermissionExtenstions.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Authorization; +using Volo.Abp.Authorization.Permissions.Resources; + +namespace Microsoft.Extensions.DependencyInjection; + +public static class KeyedObjectResourcePermissionExtenstions +{ + public static IServiceCollection AddKeyedObjectResourcePermissionAuthorization(this IServiceCollection services) + { + services.AddSingleton(); + return services; + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs index d8226bdee5..65b7e1b390 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Authorization.Localization; using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; using Volo.Abp.Localization; using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; @@ -32,6 +33,7 @@ public class AbpAuthorizationModule : AbpModule { context.Services.AddAuthorizationCore(); + context.Services.AddKeyedObjectResourcePermissionAuthorization(); context.Services.AddSingleton(); context.Services.AddSingleton(); @@ -42,6 +44,9 @@ public class AbpAuthorizationModule : AbpModule options.ValueProviders.Add(); options.ValueProviders.Add(); options.ValueProviders.Add(); + + options.ResourceValueProviders.Add(); + options.ResourceValueProviders.Add(); }); Configure(options => diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs index 7958f2a979..a5bd19b539 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs @@ -40,6 +40,14 @@ public class AbpAuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider return policyBuilder.Build(); } + if ((await _permissionDefinitionManager.GetResourcePermissionsAsync()).Any(x => x.Name == policyName)) + { + //TODO: Optimize & Cache! + var policyBuilder = new AuthorizationPolicyBuilder(Array.Empty()); + policyBuilder.Requirements.Add(new ResourcePermissionRequirement(policyName)); + return policyBuilder.Build(); + } + return null; } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IDynamicPermissionDefinitionStore.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IDynamicPermissionDefinitionStore.cs index 366ae2e58a..597b274035 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IDynamicPermissionDefinitionStore.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IDynamicPermissionDefinitionStore.cs @@ -8,6 +8,10 @@ public interface IDynamicPermissionDefinitionStore Task GetOrNullAsync(string name); Task> GetPermissionsAsync(); - + + Task GetResourcePermissionOrNullAsync(string resourceName, string name); + + Task> GetResourcePermissionsAsync(); + Task> GetGroupsAsync(); -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IStaticPermissionDefinitionStore.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IStaticPermissionDefinitionStore.cs index 4da8423dd3..da4055d771 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IStaticPermissionDefinitionStore.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IStaticPermissionDefinitionStore.cs @@ -8,6 +8,10 @@ public interface IStaticPermissionDefinitionStore Task GetOrNullAsync(string name); Task> GetPermissionsAsync(); - + + Task GetResourcePermissionOrNullAsync(string resourceName, string name); + + Task> GetResourcePermissionsAsync(); + Task> GetGroupsAsync(); -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullDynamicPermissionDefinitionStore.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullDynamicPermissionDefinitionStore.cs index 5b13288153..cf3a9820b4 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullDynamicPermissionDefinitionStore.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/NullDynamicPermissionDefinitionStore.cs @@ -9,10 +9,15 @@ namespace Volo.Abp.Authorization.Permissions; public class NullDynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStore, ISingletonDependency { private readonly static Task CachedPermissionResult = Task.FromResult((PermissionDefinition?)null); - + private readonly static Task> CachedPermissionsResult = Task.FromResult((IReadOnlyList)Array.Empty().ToImmutableList()); + private readonly static Task CachedResourcePermissionResult = Task.FromResult((PermissionDefinition?)null); + + private readonly static Task> CachedResourcePermissionsResult = + Task.FromResult((IReadOnlyList)Array.Empty().ToImmutableList()); + private readonly static Task> CachedGroupsResult = Task.FromResult((IReadOnlyList)Array.Empty().ToImmutableList()); @@ -26,8 +31,18 @@ public class NullDynamicPermissionDefinitionStore : IDynamicPermissionDefinition return CachedPermissionsResult; } + public Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + return CachedResourcePermissionResult; + } + + public Task> GetResourcePermissionsAsync() + { + return CachedResourcePermissionsResult; + } + public Task> GetGroupsAsync() { return CachedGroupsResult; } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionManager.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionManager.cs index 23f9e7883e..3dbc22fb47 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionManager.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionManager.cs @@ -34,17 +34,36 @@ public class PermissionDefinitionManager : IPermissionDefinitionManager, ITransi { Check.NotNull(name, nameof(name)); - return await _staticStore.GetOrNullAsync(name) ?? + return await _staticStore.GetOrNullAsync(name) ?? await _dynamicStore.GetOrNullAsync(name); } + public virtual async Task GetResourcePermissionAsync(string resourceName, string name) + { + var permission = await GetResourcePermissionOrNullAsync(resourceName, name); + if (permission == null) + { + throw new AbpException($"Undefined resource permission: {name} for resource: {resourceName}"); + } + + return permission; + } + + public virtual async Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + return await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name) ?? + await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + } + public virtual async Task> GetPermissionsAsync() { var staticPermissions = await _staticStore.GetPermissionsAsync(); var staticPermissionNames = staticPermissions .Select(p => p.Name) .ToImmutableHashSet(); - + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); /* We prefer static permissions over dynamics */ @@ -53,13 +72,28 @@ public class PermissionDefinitionManager : IPermissionDefinitionManager, ITransi ).ToImmutableList(); } - public async Task> GetGroupsAsync() + public virtual async Task> GetResourcePermissionsAsync() + { + var staticResourcePermissions = await _staticStore.GetResourcePermissionsAsync(); + var staticResourcePermissionNames = staticResourcePermissions + .Select(p => p.Name) + .ToImmutableHashSet(); + + var dynamicResourcePermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + /* We prefer static permissions over dynamics */ + return staticResourcePermissions.Concat( + dynamicResourcePermissions.Where(d => !staticResourcePermissionNames.Contains(d.Name)) + ).ToImmutableList(); + } + + public virtual async Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); var staticGroupNames = staticGroups .Select(p => p.Name) .ToImmutableHashSet(); - + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); /* We prefer static groups over dynamics */ @@ -67,4 +101,4 @@ public class PermissionDefinitionManager : IPermissionDefinitionManager, ITransi dynamicGroups.Where(d => !staticGroupNames.Contains(d.Name)) ).ToImmutableList(); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionCheckerExtensions.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionCheckerExtensions.cs new file mode 100644 index 0000000000..e8b9e38218 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionCheckerExtensions.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public static class KeyedObjectResourcePermissionCheckerExtensions +{ + /// + /// Checks if the specified permission is granted for the given resource. + /// + /// The type of the object. + /// The resource permission checker instance. + /// The name of the permission to check. + /// The resource for which the permission is being checked. + /// A task that represents the asynchronous operation. The task result is a boolean indicating whether the permission is granted. + public static Task IsGrantedAsync(this IResourcePermissionChecker resourcePermissionChecker, string permissionName, TResource resource) + where TResource : class, IKeyedObject + { + Check.NotNull(resourcePermissionChecker, nameof(resourcePermissionChecker)); + Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName)); + Check.NotNull(resource, nameof(resource)); + + return resourcePermissionChecker.IsGrantedAsync( + permissionName, + resource, + resource.GetObjectKey() ?? throw new AbpException("The resource doesn't have a key.") + ); + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionRequirementHandler.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionRequirementHandler.cs new file mode 100644 index 0000000000..e43b6d07b5 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionRequirementHandler.cs @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class KeyedObjectResourcePermissionRequirementHandler : AuthorizationHandler +{ + protected readonly IResourcePermissionChecker PermissionChecker; + + public KeyedObjectResourcePermissionRequirementHandler(IResourcePermissionChecker permissionChecker) + { + PermissionChecker = permissionChecker; + } + + protected override async Task HandleRequirementAsync( + AuthorizationHandlerContext context, + ResourcePermissionRequirement requirement, + IKeyedObject? resource) + { + if (resource == null) + { + return; + } + + var resourceName = resource.GetType().FullName!; + var resourceKey = resource.GetObjectKey() ?? throw new AbpException("The resource doesn't have a key."); + + if (await PermissionChecker.IsGrantedAsync(context.User, requirement.PermissionName, resourceName, resourceKey)) + { + context.Succeed(requirement); + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionStoreExtensions.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionStoreExtensions.cs new file mode 100644 index 0000000000..3088950510 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/KeyedObjectResourcePermissionStoreExtensions.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public static class KeyedObjectResourcePermissionStoreExtensions +{ + /// + /// Retrieves an array of granted permissions for a specific entity. + /// + /// The type of the resource. + /// The resource permission store instance. + /// The resource for which the permissions are being checked. + /// An array of granted permission names as strings. + public static async Task GetGrantedPermissionsAsync( + this IResourcePermissionStore resourcePermissionStore, + TResource resource + ) + where TResource : class, IKeyedObject + { + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); + Check.NotNull(resource, nameof(resource)); + + return (await GetPermissionsAsync(resourcePermissionStore, resource)).Where(x => x.Value).Select(x => x.Key).ToArray(); + } + + /// + /// Retrieves a dictionary of permissions and their granted status for the specified entity. + /// + /// The type of the entity. + /// The resource permission store instance. + /// The entity for which the permissions are being retrieved. + /// A dictionary where the keys are permission names and the values are booleans indicating whether the permission is granted. + public static async Task> GetPermissionsAsync( + this IResourcePermissionStore resourcePermissionStore, + TEntity entity + ) + where TEntity : class, IKeyedObject + { + Check.NotNull(resourcePermissionStore, nameof(resourcePermissionStore)); + Check.NotNull(entity, nameof(entity)); + + return await resourcePermissionStore.GetPermissionsAsync( + entity, + entity.GetObjectKey() ?? throw new AbpException("The entity doesn't have a key.") + ); + } +} 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 new file mode 100644 index 0000000000..a920c2e464 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionChecker.cs @@ -0,0 +1,173 @@ +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Security.Principal; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionChecker : IResourcePermissionChecker, ITransientDependency +{ + protected IPermissionDefinitionManager PermissionDefinitionManager { get; } + protected ICurrentPrincipalAccessor PrincipalAccessor { get; } + 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, + 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) + { + return await IsGrantedAsync(PrincipalAccessor.Principal, name, resourceName, resourceKey); + } + + public virtual async Task IsGrantedAsync( + ClaimsPrincipal? claimsPrincipal, + string name, + string resourceName, + string resourceKey) + { + Check.NotNull(name, nameof(name)); + + var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(resourceName, name); + if (permission == null) + { + return false; + } + + if (!permission.IsEnabled) + { + return false; + } + + if (!await StateCheckerManager.IsEnabledAsync(permission)) + { + return false; + } + + var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() + ?? CurrentTenant.GetMultiTenancySide(); + + if (!permission.MultiTenancySide.HasFlag(multiTenancySide)) + { + return false; + } + + var isGranted = false; + var context = new ResourcePermissionValueCheckContext(permission, claimsPrincipal, resourceName, resourceKey); + foreach (var provider in PermissionValueProviderManager.ValueProviders) + { + if (context.Permission.Providers.Any() && + !context.Permission.Providers.Contains(provider.Name)) + { + continue; + } + + var result = await provider.CheckAsync(context); + + if (result == PermissionGrantResult.Granted) + { + isGranted = true; + } + else if (result == PermissionGrantResult.Prohibited) + { + return false; + } + } + + return isGranted; + } + + public async Task IsGrantedAsync(string[] names, string resourceName, string resourceKey) + { + return await IsGrantedAsync(PrincipalAccessor.Principal, names, resourceName, resourceKey); + } + + public async Task IsGrantedAsync(ClaimsPrincipal? claimsPrincipal, string[] names, string resourceName, string resourceKey) + { + Check.NotNull(names, nameof(names)); + + var result = new MultiplePermissionGrantResult(); + if (!names.Any()) + { + return result; + } + + var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() ?? + CurrentTenant.GetMultiTenancySide(); + + var permissionDefinitions = new List(); + foreach (var name in names) + { + var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(resourceName, name); + if (permission == null) + { + result.Result.Add(name, PermissionGrantResult.Prohibited); + continue; + } + + result.Result.Add(name, PermissionGrantResult.Undefined); + + if (permission.IsEnabled && + await StateCheckerManager.IsEnabledAsync(permission) && + permission.MultiTenancySide.HasFlag(multiTenancySide)) + { + permissionDefinitions.Add(permission); + } + } + + foreach (var provider in PermissionValueProviderManager.ValueProviders) + { + var permissions = permissionDefinitions + .Where(x => !x.Providers.Any() || x.Providers.Contains(provider.Name)) + .ToList(); + + if (permissions.IsNullOrEmpty()) + { + continue; + } + + var context = new ResourcePermissionValuesCheckContext( + permissions, + claimsPrincipal, + resourceName, + resourceKey); + + var multipleResult = await provider.CheckAsync(context); + foreach (var grantResult in multipleResult.Result.Where(grantResult => + result.Result.ContainsKey(grantResult.Key) && + result.Result[grantResult.Key] == PermissionGrantResult.Undefined && + grantResult.Value != PermissionGrantResult.Undefined)) + { + result.Result[grantResult.Key] = grantResult.Value; + permissionDefinitions.RemoveAll(x => x.Name == grantResult.Key); + } + + if (result.AllGranted || result.AllProhibited) + { + break; + } + } + + return result; + } +} 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 new file mode 100644 index 0000000000..91dfb509d4 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionPopulator.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +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, + IPermissionChecker permissionChecker) + { + PermissionDefinitionManager = permissionDefinitionManager; + ResourcePermissionChecker = resourcePermissionChecker; + ResourcePermissionStore = resourcePermissionStore; + PermissionChecker = permissionChecker; + } + + public virtual async Task PopulateAsync(TResource resource, string resourceName) + where TResource : IHasResourcePermissions + { + await PopulateAsync([resource], resourceName); + } + + public virtual async Task PopulateAsync(List resources, string resourceName) + where TResource : IHasResourcePermissions + { + Check.NotNull(resources, nameof(resources)); + Check.NotNullOrWhiteSpace(resourceName, nameof(resourceName)); + + var resopurcePermissions = (await PermissionDefinitionManager.GetResourcePermissionsAsync()) + .Where(x => x.ResourceName == resourceName) + .ToArray(); + + foreach (var resource in resources) + { + var resourceKey = resource.GetObjectKey(); + if (resourceKey.IsNullOrEmpty()) + { + throw new AbpException("Resource key can not be null or empty."); + } + + var results = await ResourcePermissionChecker.IsGrantedAsync(resopurcePermissions.Select(x => x.Name).ToArray(), resourceName, resourceKey); + foreach (var resopurcePermission in resopurcePermissions) + { + if (resource.ResourcePermissions == null) + { + ObjectHelper.TrySetProperty(resource, x => x.ResourcePermissions, () => new Dictionary()); + } + + var hasPermission = results.Result.TryGetValue(resopurcePermission.Name, out var granted) && granted == PermissionGrantResult.Granted; + resource.ResourcePermissions![resopurcePermission.Name] = hasPermission; + } + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProviderManager.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProviderManager.cs new file mode 100644 index 0000000000..bab3180fea --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/ResourcePermissionValueProviderManager.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class ResourcePermissionValueProviderManager : IResourcePermissionValueProviderManager, ISingletonDependency +{ + public IReadOnlyList ValueProviders => _lazyProviders.Value; + private readonly Lazy> _lazyProviders; + + protected AbpPermissionOptions Options { get; } + protected IServiceProvider ServiceProvider { get; } + + public ResourcePermissionValueProviderManager( + IServiceProvider serviceProvider, + IOptions options) + { + Options = options.Value; + ServiceProvider = serviceProvider; + + _lazyProviders = new Lazy>(GetProviders, true); + } + + protected virtual List GetProviders() + { + var providers = Options + .ResourceValueProviders + .Select(type => (ServiceProvider.GetRequiredService(type) as IResourcePermissionValueProvider)!) + .ToList(); + + var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1); + if(multipleProviders != null) + { + throw new AbpException($"Duplicate resource permission value provider name detected: {multipleProviders.Key}. Providers:{Environment.NewLine}{multipleProviders.Select(p => p.GetType().FullName!).JoinAsString(Environment.NewLine)}"); + } + + return providers; + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/RoleResourcePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/RoleResourcePermissionValueProvider.cs new file mode 100644 index 0000000000..fc8e91e794 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/RoleResourcePermissionValueProvider.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Security.Claims; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class RoleResourcePermissionValueProvider : ResourcePermissionValueProvider +{ + public const string ProviderName = "R"; + + public override string Name => ProviderName; + + public RoleResourcePermissionValueProvider(IResourcePermissionStore resourcePermissionStore) + : base(resourcePermissionStore) + { + + } + + public override async Task CheckAsync(ResourcePermissionValueCheckContext context) + { + var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray(); + + if (roles == null || !roles.Any()) + { + return PermissionGrantResult.Undefined; + } + + foreach (var role in roles.Distinct()) + { + if (await ResourcePermissionStore.IsGrantedAsync(context.Permission.Name, context.ResourceName, context.ResourceKey, Name, role)) + { + return PermissionGrantResult.Granted; + } + } + + return PermissionGrantResult.Undefined; + } + + public override async Task CheckAsync(ResourcePermissionValuesCheckContext context) + { + var permissionNames = context.Permissions.Select(x => x.Name).Distinct().ToList(); + Check.NotNullOrEmpty(permissionNames, nameof(permissionNames)); + + var result = new MultiplePermissionGrantResult(permissionNames.ToArray()); + + var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray(); + if (roles == null || !roles.Any()) + { + return result; + } + + foreach (var role in roles.Distinct()) + { + var multipleResult = await ResourcePermissionStore.IsGrantedAsync(permissionNames.ToArray(), context.ResourceName, context.ResourceKey, Name, role); + + foreach (var grantResult in multipleResult.Result.Where(grantResult => + result.Result.ContainsKey(grantResult.Key) && + result.Result[grantResult.Key] == PermissionGrantResult.Undefined && + grantResult.Value != PermissionGrantResult.Undefined)) + { + result.Result[grantResult.Key] = grantResult.Value; + permissionNames.RemoveAll(x => x == grantResult.Key); + } + + if (result.AllGranted || result.AllProhibited) + { + break; + } + + if (permissionNames.IsNullOrEmpty()) + { + break; + } + } + + return result; + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/UserResourcePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/UserResourcePermissionValueProvider.cs new file mode 100644 index 0000000000..8cfcb8ca6f --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/Resources/UserResourcePermissionValueProvider.cs @@ -0,0 +1,46 @@ +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Security.Claims; + +namespace Volo.Abp.Authorization.Permissions.Resources; + +public class UserResourcePermissionValueProvider : ResourcePermissionValueProvider +{ + public const string ProviderName = "U"; + + public override string Name => ProviderName; + + public UserResourcePermissionValueProvider(IResourcePermissionStore resourcePermissionStore) + : base(resourcePermissionStore) + { + + } + + public override async Task CheckAsync(ResourcePermissionValueCheckContext context) + { + var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value; + + if (userId == null) + { + return PermissionGrantResult.Undefined; + } + + return await ResourcePermissionStore.IsGrantedAsync(context.Permission.Name, context.ResourceName, context.ResourceKey, Name, userId) + ? PermissionGrantResult.Granted + : PermissionGrantResult.Undefined; + } + + public override async Task CheckAsync(ResourcePermissionValuesCheckContext context) + { + var permissionNames = context.Permissions.Select(x => x.Name).Distinct().ToArray(); + Check.NotNullOrEmpty(permissionNames, nameof(permissionNames)); + + var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value; + if (userId == null) + { + return new MultiplePermissionGrantResult(permissionNames); + } + + return await ResourcePermissionStore.IsGrantedAsync(permissionNames, context.ResourceName, context.ResourceKey, Name, userId); + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/StaticPermissionDefinitionStore.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/StaticPermissionDefinitionStore.cs index 4e6ff0d11c..5ac2257060 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/StaticPermissionDefinitionStore.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/StaticPermissionDefinitionStore.cs @@ -11,12 +11,14 @@ namespace Volo.Abp.Authorization.Permissions; public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, ISingletonDependency { - protected IDictionary PermissionGroupDefinitions => _lazyPermissionGroupDefinitions.Value; - private readonly Lazy> _lazyPermissionGroupDefinitions; + protected IDictionary PermissionGroupDefinitions => _lazyPermissionGroupDefinitions.Value.Item1; + private readonly Lazy<(Dictionary, List)> _lazyPermissionGroupDefinitions; protected IDictionary PermissionDefinitions => _lazyPermissionDefinitions.Value; private readonly Lazy> _lazyPermissionDefinitions; + protected IList ResourcePermissionDefinitions => _lazyPermissionGroupDefinitions.Value.Item2; + protected AbpPermissionOptions Options { get; } private readonly IServiceProvider _serviceProvider; @@ -33,12 +35,12 @@ public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, isThreadSafe: true ); - _lazyPermissionGroupDefinitions = new Lazy>( + _lazyPermissionGroupDefinitions = new Lazy<(Dictionary, List)>( CreatePermissionGroupDefinitions, isThreadSafe: true ); } - + protected virtual Dictionary CreatePermissionDefinitions() { var permissions = new Dictionary(); @@ -71,7 +73,7 @@ public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, } } - protected virtual Dictionary CreatePermissionGroupDefinitions() + protected virtual (Dictionary, List) CreatePermissionGroupDefinitions() { using (var scope = _serviceProvider.CreateScope()) { @@ -99,10 +101,10 @@ public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, context.CurrentProvider = provider; provider.PostDefine(context); } - + context.CurrentProvider = null; - return context.Groups; + return (context.Groups, context.ResourcePermissions); } } @@ -110,7 +112,7 @@ public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, { return Task.FromResult(PermissionDefinitions.GetOrDefault(name)); } - + public virtual Task> GetPermissionsAsync() { return Task.FromResult>( @@ -118,10 +120,22 @@ public class StaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, ); } + public virtual Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + return Task.FromResult(ResourcePermissionDefinitions.FirstOrDefault(p => p.ResourceName == resourceName && p.Name == name)); + } + + public virtual Task> GetResourcePermissionsAsync() + { + return Task.FromResult>( + ResourcePermissionDefinitions.ToImmutableList() + ); + } + public Task> GetGroupsAsync() { return Task.FromResult>( PermissionGroupDefinitions.Values.ToImmutableList() ); } -} \ No newline at end of file +} 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. diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json index 93cf62ab84..eb32a44fa2 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json @@ -61,6 +61,7 @@ "ProfilePicture": "الصوره الشخصيه", "Theme": "سمة", "NotAssigned": "غيرمعتمد", - "EntityActionsDisabledTooltip": "ليس لديك إذن لتنفيذ أي إجراء." + "EntityActionsDisabledTooltip": "ليس لديك إذن لتنفيذ أي إجراء.", + "ResourcePermissions": "أذونات" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json index ff2d09fdf8..27a174cb49 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profilový obrázek", "Theme": "Téma", "NotAssigned": "Nepřiřazena", - "EntityActionsDisabledTooltip": "Nemáte oprávnění provést žádnou akci." + "EntityActionsDisabledTooltip": "Nemáte oprávnění provést žádnou akci.", + "ResourcePermissions": "Oprávnění" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json index 37c361c1e3..869d049be1 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profilbild", "Theme": "Thema", "NotAssigned": "Nicht zugeordnet", - "EntityActionsDisabledTooltip": "Sie haben keine Berechtigung, Aktionen auszuführen." + "EntityActionsDisabledTooltip": "Sie haben keine Berechtigung, Aktionen auszuführen.", + "ResourcePermissions": "Berechtigungen" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json index f7d837a361..8c2dc2be1d 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json @@ -55,6 +55,7 @@ "OthersGroup": "άλλος", "Today": "Σήμερα", "Apply": "Ισχύουν", - "EntityActionsDisabledTooltip": "Δεν έχετε δικαίωμα να εκτελέσετε καμία ενέργεια." + "EntityActionsDisabledTooltip": "Δεν έχετε δικαίωμα να εκτελέσετε καμία ενέργεια.", + "ResourcePermissions": "Δικαιώματα", } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json index c5aaa5957c..ce9d962d5e 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json @@ -56,6 +56,7 @@ "NotAssigned": "Not Assigned", "Today": "Today", "Apply": "Apply", - "EntityActionsDisabledTooltip": "You do not have permission to perform any action." + "EntityActionsDisabledTooltip": "You do not have permission to perform any action.", + "ResourcePermissions": "Permissions" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json index 7a5a806124..f328765a39 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profile picture", "Theme": "Theme", "NotAssigned": "Not Assigned", - "EntityActionsDisabledTooltip": "You do not have permission to perform any action." + "EntityActionsDisabledTooltip": "You do not have permission to perform any action.", + "ResourcePermissions": "Permissions" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json index 132243a740..9d341cb88f 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json @@ -61,6 +61,7 @@ "ProfilePicture": "Foto de perfil", "Theme": "Tema", "NotAssigned": "No asignado", - "EntityActionsDisabledTooltip": "No tienes permisos para realizar ninguna acción." + "EntityActionsDisabledTooltip": "No tienes permisos para realizar ninguna acción.", + "ResourcePermissions": "Permisos" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json index f1738957c9..5862eab90e 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json @@ -55,6 +55,7 @@ "OthersGroup": "دیگر", "Today": "امروز", "Apply": "درخواست دادن", - "EntityActionsDisabledTooltip": "شما دسترسی به انجام هر گونه عملیات ندارید." + "EntityActionsDisabledTooltip": "شما دسترسی به انجام هر گونه عملیات ندارید.", + "ResourcePermissions": "مجوزها" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json index 1af59eb720..51e356559b 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profiilikuva", "Theme": "Teema", "NotAssigned": "Ei määritetty", - "EntityActionsDisabledTooltip": "Sinulla ei ole oikeutta suorittaa mitään toimintoa." + "EntityActionsDisabledTooltip": "Sinulla ei ole oikeutta suorittaa mitään toimintoa.", + "ResourcePermissions": "Käyttöoikeudet" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json index 8af5661d1a..79a40c57f9 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json @@ -61,6 +61,7 @@ "ProfilePicture": "Image de profil", "Theme": "Thème", "NotAssigned": "Non attribué", - "EntityActionsDisabledTooltip": "Vous n'avez pas les permissions pour effectuer une action." + "EntityActionsDisabledTooltip": "Vous n'avez pas les permissions pour effectuer une action.", + "ResourcePermissions": "Autorisations" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json index ba873b7685..10c1e426c1 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json @@ -61,6 +61,7 @@ "ProfilePicture": "प्रोफ़ाइल फोटो", "Theme": "विषय", "NotAssigned": "सौंपा नहीं गया है", - "EntityActionsDisabledTooltip": "आपके पास कोई कार्रवाई नहीं है जो करने के लिए है।" + "EntityActionsDisabledTooltip": "आपके पास कोई कार्रवाई नहीं है जो करने के लिए है।", + "ResourcePermissions": "अनुमतियाँ" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json index 5b16c84963..c36751828c 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profilna slika", "Theme": "Tema", "NotAssigned": "Nije dodijeljeno", - "EntityActionsDisabledTooltip": "Nemate dozvolu za izvođenje bilo kakve akcije." + "EntityActionsDisabledTooltip": "Nemate dozvolu za izvođenje bilo kakve akcije.", + "ResourcePermissions": "Dozvole" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json index 0539276498..e162a2c6c8 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profil kép", "Theme": "Téma", "NotAssigned": "Nem kijelölt", - "EntityActionsDisabledTooltip": "Nincs jogosultsága bármely művelethez." + "EntityActionsDisabledTooltip": "Nincs jogosultsága bármely művelethez.", + "ResourcePermissions": "Engedélyek" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json index 8a1eda9e4e..3d88d70d97 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json @@ -61,6 +61,7 @@ "ProfilePicture": "Forsíðumynd", "Theme": "Þema", "NotAssigned": "Ekki skráður", - "EntityActionsDisabledTooltip": "Þú hefur ekki aðgang að þessum aðgerðum." + "EntityActionsDisabledTooltip": "Þú hefur ekki aðgang að þessum aðgerðum.", + "ResourcePermissions": "Aðgangsheimildir" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json index 77d4742680..9bfffe181e 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json @@ -61,6 +61,7 @@ "ProfilePicture": "Immagine del profilo", "Theme": "Tema", "NotAssigned": "Non assegnato", - "EntityActionsDisabledTooltip": "Non hai i permessi per eseguire alcuna azione." + "EntityActionsDisabledTooltip": "Non hai i permessi per eseguire alcuna azione.", + "ResourcePermissions": "Autorizzazioni" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json index 38182ec9e6..51ab0bcd31 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profielfoto", "Theme": "Thema", "NotAssigned": "Niet toegekend", - "EntityActionsDisabledTooltip": "U hebt geen toegang tot deze acties." + "EntityActionsDisabledTooltip": "U hebt geen toegang tot deze acties.", + "ResourcePermissions": "Machtigingen" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json index d7f321f3d6..20b4daf7f0 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json @@ -61,6 +61,7 @@ "ProfilePicture": "Zdjęcie profilowe", "Theme": "Temat", "NotAssigned": "Nie przypisano", - "EntityActionsDisabledTooltip": "Nie masz uprawnień do wykonania żadnej akcji." + "EntityActionsDisabledTooltip": "Nie masz uprawnień do wykonania żadnej akcji.", + "ResourcePermissions": "Uprawnienia" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json index 13c8380fa3..9764d99fe6 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json @@ -61,6 +61,7 @@ "ProfilePicture": "Foto do perfil", "Theme": "Tema", "NotAssigned": "Não atribuído", - "EntityActionsDisabledTooltip": "Você não tem permissão para executar qualquer ação." + "EntityActionsDisabledTooltip": "Você não tem permissão para executar qualquer ação.", + "ResourcePermissions": "Permissões" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json index e03fd91f50..6b7367994c 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json @@ -61,6 +61,7 @@ "ProfilePicture": "Poză de profil", "Theme": "Temă", "NotAssigned": "Nealocat", - "EntityActionsDisabledTooltip": "Nu aveți permisiune să efectuați nicio acțiune." + "EntityActionsDisabledTooltip": "Nu aveți permisiune să efectuați nicio acțiune.", + "ResourcePermissions": "Permisiuni" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json index 57f3079cb4..d4f4acf5d6 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json @@ -61,6 +61,7 @@ "ProfilePicture": "Изображение профиля", "Theme": "Тема", "NotAssigned": "Не назначен", - "EntityActionsDisabledTooltip": "У вас нет прав на выполнение каких-либо действий." + "EntityActionsDisabledTooltip": "У вас нет прав на выполнение каких-либо действий.", + "ResourcePermissions": "Разрешения" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json index eb0ba2958f..59d8aecef4 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profilový obrázok", "Theme": "Téma", "NotAssigned": "Nepridelené", - "EntityActionsDisabledTooltip": "Nemáte oprávnenie vykonávať žiadnu akciu." + "EntityActionsDisabledTooltip": "Nemáte oprávnenie vykonávať žiadnu akciu.", + "ResourcePermissions": "Oprávnenia" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json index bc3f795b34..89f2691a11 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profilna slika", "Theme": "Tema", "NotAssigned": "Ni dodeljena", - "EntityActionsDisabledTooltip": "Nimate pravic za izvajanje kakršne koli dejanje." + "EntityActionsDisabledTooltip": "Nimate pravic za izvajanje kakršne koli dejanje.", + "ResourcePermissions": "Dovoljenja" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sv.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sv.json index f0257637c1..fe4b692cdf 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sv.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sv.json @@ -60,6 +60,7 @@ "ProfilePicture": "Profilbild", "Theme": "Tema", "NotAssigned": "Ej tilldelad", - "EntityActionsDisabledTooltip": "Du har inte tillgång till dessa åtgärder." + "EntityActionsDisabledTooltip": "Du har inte tillgång till dessa åtgärder.", + "ResourcePermissions": "Behörigheter" } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json index b21adf632a..73a4bb5cb4 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json @@ -61,6 +61,7 @@ "ProfilePicture": "Profil resmi", "Theme": "Tema", "NotAssigned": "Atanmadı", - "EntityActionsDisabledTooltip": "Bu işlemi gerçekleştirmek için yeterli yetkiniz yok." + "EntityActionsDisabledTooltip": "Bu işlemi gerçekleştirmek için yeterli yetkiniz yok.", + "ResourcePermissions": "İzinler" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json index 700798895f..015ed883d3 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json @@ -61,6 +61,7 @@ "ProfilePicture": "Ảnh đại diện", "Theme": "chủ đề", "NotAssigned": "Không được chỉ định", - "EntityActionsDisabledTooltip": "Bạn không có quyền thực hiện bất kỳ hành động nào." + "EntityActionsDisabledTooltip": "Bạn không có quyền thực hiện bất kỳ hành động nào.", + "ResourcePermissions": "Quyền" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json index 60f70e1545..b0759d7da9 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json @@ -61,6 +61,7 @@ "ProfilePicture": "个人资料图片", "Theme": "主题", "NotAssigned": "未分配", - "EntityActionsDisabledTooltip": "您没有权限执行任何操作。" + "EntityActionsDisabledTooltip": "您没有权限执行任何操作。", + "ResourcePermissions": "权限" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json index 0f8fdeb254..e35bae3610 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json @@ -61,6 +61,7 @@ "ProfilePicture": "個人資料圖片", "Theme": "主題", "NotAssigned": "未分配", - "EntityActionsDisabledTooltip": "您沒有權限執行任何操作。" + "EntityActionsDisabledTooltip": "您沒有權限執行任何操作。", + "ResourcePermissions": "權限" } } diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs index fca3d209b0..15ec4e0641 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.TestServices; +using Volo.Abp.Authorization.TestServices.Resources; using Volo.Abp.Autofac; using Volo.Abp.DynamicProxy; using Volo.Abp.ExceptionHandling; @@ -33,6 +34,9 @@ public class AbpAuthorizationTestModule : AbpModule options.ValueProviders.Add(); options.ValueProviders.Add(); options.ValueProviders.Add(); + + options.ResourceValueProviders.Add(); + options.ResourceValueProviders.Add(); }); } } diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs index 4144df2e1e..43736f0dce 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs @@ -2,12 +2,11 @@ using System; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Shouldly; -using Volo.Abp.Authorization; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.TestServices; using Xunit; -namespace Volo.Abp; +namespace Volo.Abp.Authorization; public class PermissionValueProviderManager_Tests: AuthorizationTestBase { @@ -17,7 +16,7 @@ public class PermissionValueProviderManager_Tests: AuthorizationTestBase { _permissionValueProviderManager = GetRequiredService(); } - + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) { options.Services.Configure(permissionOptions => @@ -25,7 +24,7 @@ public class PermissionValueProviderManager_Tests: AuthorizationTestBase permissionOptions.ValueProviders.Add(); }); } - + [Fact] public void Should_Throw_Exception_If_Duplicate_Provider_Name_Detected() { @@ -33,7 +32,7 @@ public class PermissionValueProviderManager_Tests: AuthorizationTestBase { var providers = _permissionValueProviderManager.ValueProviders; }); - + exception.Message.ShouldBe($"Duplicate permission value provider name detected: TestPermissionValueProvider1. Providers:{Environment.NewLine}{typeof(TestDuplicatePermissionValueProvider).FullName}{Environment.NewLine}{typeof(TestPermissionValueProvider1).FullName}"); } } @@ -55,4 +54,4 @@ public class TestDuplicatePermissionValueProvider : PermissionValueProvider { throw new NotImplementedException(); } -} \ No newline at end of file +} 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 new file mode 100644 index 0000000000..739968b603 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionChecker_Tests.cs @@ -0,0 +1,62 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Authorization.TestServices.Resources; +using Xunit; + +namespace Volo.Abp.Authorization; + +public class ResourcePermissionChecker_Tests: AuthorizationTestBase +{ + private readonly IResourcePermissionChecker _resourcePermissionChecker; + + public ResourcePermissionChecker_Tests() + { + _resourcePermissionChecker = GetRequiredService(); + } + + [Fact] + public async Task IsGrantedAsync() + { + (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] + public async Task IsGranted_Multiple_Result_Async() + { + var result = await _resourcePermissionChecker.IsGrantedAsync(new [] + { + "MyResourcePermission1", + "MyResourcePermission2", + "UndefinedPermission", + "MyResourcePermission3", + "MyResourcePermission4", + "MyResourcePermission5", + "MyResourcePermission8" + }, TestEntityResource.ResourceName, TestEntityResource.ResourceKey5); + + result.Result["MyResourcePermission1"].ShouldBe(PermissionGrantResult.Undefined); + result.Result["MyResourcePermission2"].ShouldBe(PermissionGrantResult.Prohibited); + result.Result["UndefinedPermission"].ShouldBe(PermissionGrantResult.Prohibited); + 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 [] + { + "MyResourcePermission7", + }, TestEntityResource.ResourceName, TestEntityResource.ResourceKey7); + result.Result["MyResourcePermission7"].ShouldBe(PermissionGrantResult.Granted); + } +} 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..2cc000c30a --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionPopulator_Test.cs @@ -0,0 +1,60 @@ +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(8); + 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.ResourcePermissions["MyResourcePermission8"].ShouldBe(false); + + testResourceObject = new TestEntityResource(TestEntityResource.ResourceKey6); + testResourceObject.ResourcePermissions.IsNullOrEmpty().ShouldBeTrue(); + + await _resourcePermissionPopulator.PopulateAsync( + testResourceObject, + TestEntityResource.ResourceName + ); + + testResourceObject.ResourcePermissions.ShouldNotBeNull(); + testResourceObject.ResourcePermissions.Count.ShouldBe(8); + 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); + testResourceObject.ResourcePermissions["MyResourcePermission8"].ShouldBe(false); + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionValueProviderManager_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionValueProviderManager_Tests.cs new file mode 100644 index 0000000000..ceebc1ebac --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/ResourcePermissionValueProviderManager_Tests.cs @@ -0,0 +1,58 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Authorization.TestServices.Resources; +using Xunit; + +namespace Volo.Abp.Authorization; + +public class ResourcePermissionValueProviderManager_Tests: AuthorizationTestBase +{ + private readonly IResourcePermissionValueProviderManager _resourcePermissionValueProviderManager; + + public ResourcePermissionValueProviderManager_Tests() + { + _resourcePermissionValueProviderManager = GetRequiredService(); + } + + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.Services.Configure(permissionOptions => + { + permissionOptions.ResourceValueProviders.Add(); + }); + } + + [Fact] + public void Should_Throw_Exception_If_Duplicate_Provider_Name_Detected() + { + var exception = Assert.Throws(() => + { + var providers = _resourcePermissionValueProviderManager.ValueProviders; + }); + + exception.Message.ShouldBe($"Duplicate resource permission value provider name detected: TestResourcePermissionValueProvider1. Providers:{Environment.NewLine}{typeof(TestDuplicateResourcePermissionValueProvider).FullName}{Environment.NewLine}{typeof(TestResourcePermissionValueProvider1).FullName}"); + } +} + +public class TestDuplicateResourcePermissionValueProvider : ResourcePermissionValueProvider +{ + public TestDuplicateResourcePermissionValueProvider(IResourcePermissionStore permissionStore) : base(permissionStore) + { + } + + public override string Name => "TestResourcePermissionValueProvider1"; + + public override Task CheckAsync(ResourcePermissionValueCheckContext context) + { + throw new NotImplementedException(); + } + + public override Task CheckAsync(ResourcePermissionValuesCheckContext context) + { + throw new NotImplementedException(); + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/StaticPermissionDefinitionStore_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/StaticPermissionDefinitionStore_Tests.cs index d3a484c32f..0afaa34f10 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/StaticPermissionDefinitionStore_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/StaticPermissionDefinitionStore_Tests.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Shouldly; using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.TestServices.Resources; using Xunit; namespace Volo.Abp.Authorization; @@ -44,4 +45,29 @@ public class StaticPermissionDefinitionStore_Tests : AuthorizationTestBase var groups = await _store.GetGroupsAsync(); groups.ShouldNotContain(x => x.Name == "TestGetGroup"); } + + [Fact] + public async Task GetResourcePermissionOrNullAsync() + { + var permission = await _store.GetResourcePermissionOrNullAsync(TestEntityResource.ResourceName, "MyResourcePermission1"); + permission.ShouldNotBeNull(); + permission.Name.ShouldBe("MyResourcePermission1"); + permission.StateCheckers.ShouldContain(x => x.GetType() == typeof(TestRequireEditionPermissionSimpleStateChecker)); + + permission = await _store.GetResourcePermissionOrNullAsync(TestEntityResource.ResourceName, "NotExists"); + permission.ShouldBeNull(); + } + + [Fact] + public async Task GetResourcePermissionsAsync() + { + var permissions = await _store.GetResourcePermissionsAsync(); + permissions.ShouldContain(x => x.Name == "MyResourcePermission1"); + permissions.ShouldContain(x => x.Name == "MyResourcePermission2"); + permissions.ShouldContain(x => x.Name == "MyResourcePermission3"); + permissions.ShouldContain(x => x.Name == "MyResourcePermission4"); + permissions.ShouldContain(x => x.Name == "MyResourcePermission5"); + permissions.ShouldContain(x => x.Name == "MyResourcePermission6"); + permissions.ShouldContain(x => x.Name == "MyResourcePermission7"); + } } diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/FakePermissionStore.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/FakePermissionStore.cs index 4582417d3b..608cf94428 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/FakePermissionStore.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/FakePermissionStore.cs @@ -8,7 +8,7 @@ public class FakePermissionStore : IPermissionStore, ITransientDependency { public Task IsGrantedAsync(string name, string providerName, string providerKey) { - return Task.FromResult(name == "MyPermission3" || name == "MyPermission5"); + return Task.FromResult(name == "MyPermission3" || name == "MyPermission5" || name == "TestEntityManagementPermission"); } public Task IsGrantedAsync(string[] names, string providerName, string providerKey) @@ -16,7 +16,7 @@ public class FakePermissionStore : IPermissionStore, ITransientDependency var result = new MultiplePermissionGrantResult(); foreach (var name in names) { - result.Result.Add(name, name == "MyPermission3" || name == "MyPermission5" + result.Result.Add(name, name == "MyPermission3" || name == "MyPermission5" || name == "TestEntityManagementPermission" ? PermissionGrantResult.Granted : PermissionGrantResult.Prohibited); } 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 new file mode 100644 index 0000000000..29a597c9b3 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/AuthorizationTestResourcePermissionDefinitionProvider.cs @@ -0,0 +1,48 @@ +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Xunit; + +namespace Volo.Abp.Authorization.TestServices.Resources; + +public class AuthorizationTestResourcePermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + var getGroup = context.GetGroupOrNull("TestGroup"); + if (getGroup == null) + { + getGroup = context.AddGroup("TestGroup"); + } + getGroup.AddPermission("TestEntityManagementPermission"); + getGroup.AddPermission("TestEntityManagementPermission2"); + + var permission1 = context.AddResourcePermission("MyResourcePermission1", resourceName: TestEntityResource.ResourceName, "TestEntityManagementPermission"); + Assert.Throws(() => + { + permission1.AddChild("MyResourcePermission1.ChildPermission1"); + }).Message.ShouldBe($"Resource permission cannot have child permissions. Resource: {TestEntityResource.ResourceName}"); + permission1.StateCheckers.Add(new TestRequireEditionPermissionSimpleStateChecker());; + permission1[PermissionDefinitionContext.KnownPropertyNames.CurrentProviderName].ShouldBe(typeof(AuthorizationTestResourcePermissionDefinitionProvider).FullName); + + context.AddResourcePermission("MyResourcePermission2", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); + context.AddResourcePermission("MyResourcePermission3", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); + context.AddResourcePermission("MyResourcePermission4", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); + 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(() => + { + context.AddResourcePermission("MyResourcePermission7", resourceName: typeof(TestEntityResource).FullName!, "TestEntityManagementPermission"); + }).Message.ShouldBe($"There is already an existing resource permission with name: MyResourcePermission7 for resource: {typeof(TestEntityResource).FullName}"); + + context.AddResourcePermission("MyResourcePermission7", resourceName: typeof(TestEntityResource2).FullName!, "TestEntityManagementPermission").WithProviders(nameof(TestResourcePermissionValueProvider2)); + + context.GetResourcePermissionOrNull(TestEntityResource.ResourceName, "MyResourcePermission1").ShouldNotBeNull(); + context.GetResourcePermissionOrNull(TestEntityResource.ResourceName, "MyResourcePermission7").ShouldNotBeNull(); + context.GetResourcePermissionOrNull(TestEntityResource2.ResourceName, "MyResourcePermission7").ShouldNotBeNull(); + context.GetResourcePermissionOrNull(TestEntityResource.ResourceName, "MyResourcePermission9").ShouldBeNull(); + context.GetResourcePermissionOrNull(TestEntityResource2.ResourceName, "MyResourcePermission6").ShouldBeNull(); + } +} 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 new file mode 100644 index 0000000000..40cd542ac7 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/FakeResourcePermissionStore.cs @@ -0,0 +1,46 @@ +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Authorization.TestServices.Resources; + +public class FakeResourcePermissionStore : IResourcePermissionStore, ITransientDependency +{ + public Task IsGrantedAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + return Task.FromResult((name == "MyResourcePermission3" || name == "MyResourcePermission5") && + resourceName == TestEntityResource.ResourceName && + (resourceKey == TestEntityResource.ResourceKey3 || resourceKey == TestEntityResource.ResourceKey5)); + } + + public Task IsGrantedAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in names) + { + result.Result.Add(name, ((name == "MyResourcePermission3" || name == "MyResourcePermission5") && + resourceName == TestEntityResource.ResourceName && + (resourceKey == TestEntityResource.ResourceKey3 || resourceKey == TestEntityResource.ResourceKey5) + ? PermissionGrantResult.Granted + : PermissionGrantResult.Prohibited)); + } + + return Task.FromResult(result); + } + + public Task GetPermissionsAsync(string resourceName, string resourceKey) + { + throw new System.NotImplementedException(); + } + + public Task GetGrantedPermissionsAsync(string resourceName, string resourceKey) + { + throw new System.NotImplementedException(); + } + + public Task GetGrantedResourceKeysAsync(string resourceName, string name) + { + throw new System.NotImplementedException(); + } +} 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 new file mode 100644 index 0000000000..f703007633 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestEntityResource.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Authorization.Permissions.Resources; + +namespace Volo.Abp.Authorization.TestServices.Resources; + +public class TestEntityResource : IHasResourcePermissions +{ + public static readonly string ResourceName = typeof(TestEntityResource).FullName; + + public static readonly string ResourceKey1 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey2 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey3 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey4 = Guid.NewGuid().ToString(); + 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 +{ + public static readonly string ResourceName = typeof(TestEntityResource2).FullName; +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestResourcePermissionValueProvider1.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestResourcePermissionValueProvider1.cs new file mode 100644 index 0000000000..3c7dc49a83 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestResourcePermissionValueProvider1.cs @@ -0,0 +1,43 @@ +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; + +namespace Volo.Abp.Authorization.TestServices.Resources; + +public class TestResourcePermissionValueProvider1 : ResourcePermissionValueProvider +{ + public TestResourcePermissionValueProvider1(IResourcePermissionStore permissionStore) : base(permissionStore) + { + } + + public override string Name => "TestResourcePermissionValueProvider1"; + + public override Task CheckAsync(ResourcePermissionValueCheckContext context) + { + var result = PermissionGrantResult.Undefined; + if (context.Permission.Name == "MyResourcePermission6" && + context.ResourceName == TestEntityResource.ResourceName && + context.ResourceKey == TestEntityResource.ResourceKey6) + { + result = PermissionGrantResult.Granted; + } + + return Task.FromResult(result); + } + + public override Task CheckAsync(ResourcePermissionValuesCheckContext context) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in context.Permissions.Select(x => x.Name)) + { + result.Result.Add(name, name == "MyResourcePermission6" && + context.ResourceName == TestEntityResource.ResourceName && + context.ResourceKey == TestEntityResource.ResourceKey6 + ? PermissionGrantResult.Granted + : PermissionGrantResult.Undefined); + } + + return Task.FromResult(result); + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestResourcePermissionValueProvider2.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestResourcePermissionValueProvider2.cs new file mode 100644 index 0000000000..c4ac61cb2c --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/Resources/TestResourcePermissionValueProvider2.cs @@ -0,0 +1,43 @@ +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; + +namespace Volo.Abp.Authorization.TestServices.Resources; + +public class TestResourcePermissionValueProvider2 : ResourcePermissionValueProvider +{ + public TestResourcePermissionValueProvider2(IResourcePermissionStore permissionStore) : base(permissionStore) + { + } + + public override string Name => "TestResourcePermissionValueProvider2"; + + public override Task CheckAsync(ResourcePermissionValueCheckContext context) + { + var result = PermissionGrantResult.Undefined; + if (context.Permission.Name == "MyResourcePermission7" && + context.ResourceName == TestEntityResource.ResourceName && + context.ResourceKey == TestEntityResource.ResourceKey7) + { + result = PermissionGrantResult.Granted; + } + + return Task.FromResult(result); + } + + public override Task CheckAsync(ResourcePermissionValuesCheckContext context) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in context.Permissions.Select(x => x.Name)) + { + result.Result.Add(name, name == "MyResourcePermission7" && + context.ResourceName == TestEntityResource.ResourceName && + context.ResourceKey == TestEntityResource.ResourceKey7 + ? PermissionGrantResult.Granted + : PermissionGrantResult.Undefined); + } + + return Task.FromResult(result); + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/ObjectWithKeyHelper_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/ObjectWithKeyHelper_Tests.cs new file mode 100644 index 0000000000..d5f0186b3c --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/ObjectWithKeyHelper_Tests.cs @@ -0,0 +1,31 @@ +using System; +using Shouldly; +using Xunit; + +namespace Volo.Abp; + +public class KeyedObjectHelper_Tests +{ + [Fact] + public void EncodeCompositeKey() + { + var encoded = KeyedObjectHelper.EncodeCompositeKey("Book", "123"); + encoded.ShouldBe("Qm9va3x8MTIz"); + } + + [Fact] + public void DecodeCompositeKey() + { + var decoded = KeyedObjectHelper.DecodeCompositeKey("Qm9va3x8MTIz"); + decoded.ShouldBe("Book||123"); + } + + [Fact] + public void Encode_Decode_CompositeKey() + { + var encoded = KeyedObjectHelper.EncodeCompositeKey("User", 42, Guid.Empty); + var decoded = KeyedObjectHelper.DecodeCompositeKey(encoded); + + decoded.ShouldBe($"User||42||{Guid.Empty}"); + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/EntityHelper_Tests.cs b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/EntityHelper_Tests.cs index 52ab34baee..adf82d74bd 100644 --- a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/EntityHelper_Tests.cs +++ b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/EntityHelper_Tests.cs @@ -55,6 +55,11 @@ public class EntityHelper_Tests { return new object[] { Id }; } + + public string GetObjectKey() + { + return Id.ToString(); + } } private class MyEntityDisablesIdGeneration : Entity diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs index 815c1c48c9..3a61407ddf 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs @@ -10,12 +10,20 @@ namespace Volo.Abp.Identity.Integration; public interface IIdentityUserIntegrationService : IApplicationService { Task GetRoleNamesAsync(Guid id); - + Task FindByIdAsync(Guid id); Task FindByUserNameAsync(string userName); Task> SearchAsync(UserLookupSearchInputDto input); + Task> SearchByIdsAsync(Guid[] ids); + Task GetCountAsync(UserLookupCountInputDto input); -} \ No newline at end of file + + Task> SearchRoleAsync(RoleLookupSearchInputDto input); + + Task> SearchRoleByNamesAsync(string[] ids); + + Task GetRoleCountAsync(RoleLookupCountInputDto input); +} diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupCountInputDto.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupCountInputDto.cs new file mode 100644 index 0000000000..875d350f1c --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupCountInputDto.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.Identity; + +public class RoleLookupCountInputDto +{ + public string Filter { get; set; } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupSearchInputDto.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupSearchInputDto.cs new file mode 100644 index 0000000000..ebc1707055 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupSearchInputDto.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Application.Dtos; + +namespace Volo.Abp.Identity; + +public class RoleLookupSearchInputDto : ExtensiblePagedAndSortedResultRequestDto +{ + public string Filter { get; set; } +} 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 37446ce1f3..4019cd9031 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 @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; +using Volo.Abp.Domain.Repositories; using Volo.Abp.Users; namespace Volo.Abp.Identity.Integration; @@ -10,13 +11,19 @@ public class IdentityUserIntegrationService : IdentityAppServiceBase, IIdentityU { protected IUserRoleFinder UserRoleFinder { get; } protected IdentityUserRepositoryExternalUserLookupServiceProvider UserLookupServiceProvider { get; } + protected IIdentityUserRepository UserRepository { get; } + protected IIdentityRoleRepository RoleRepository { get; } public IdentityUserIntegrationService( IUserRoleFinder userRoleFinder, - IdentityUserRepositoryExternalUserLookupServiceProvider userLookupServiceProvider) + IdentityUserRepositoryExternalUserLookupServiceProvider userLookupServiceProvider, + IIdentityUserRepository userRepository, + IIdentityRoleRepository roleRepository) { UserRoleFinder = userRoleFinder; UserLookupServiceProvider = userLookupServiceProvider; + UserRepository = userRepository; + RoleRepository = roleRepository; } public virtual async Task GetRoleNamesAsync(Guid id) @@ -62,8 +69,53 @@ public class IdentityUserIntegrationService : IdentityAppServiceBase, IIdentityU ); } + public virtual async Task> SearchByIdsAsync(Guid[] ids) + { + var users = await UserRepository.GetListByIdsAsync(ids); + + return new ListResultDto( + users + .Select(u => new UserData( + u.Id, + u.UserName, + u.Email, + u.Name, + u.Surname, + u.EmailConfirmed, + u.PhoneNumber, + u.PhoneNumberConfirmed, + u.TenantId, + u.IsActive, + u.ExtraProperties)) + .ToList() + ); + } + public virtual async Task GetCountAsync(UserLookupCountInputDto input) { return await UserLookupServiceProvider.GetCountAsync(input.Filter); } + + public virtual async Task> SearchRoleAsync(RoleLookupSearchInputDto input) + { + using (RoleRepository.DisableTracking()) + { + var roles = await RoleRepository.GetListAsync(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()); + } + } + + public virtual async Task> SearchRoleByNamesAsync(string[] names) + { + using (RoleRepository.DisableTracking()) + { + var roles = await RoleRepository.GetListAsync(names); + return new ListResultDto(roles.Select(r => new RoleData(r.Id, r.Name, r.IsDefault, r.IsStatic, r.IsPublic, r.TenantId, r.ExtraProperties)).ToList()); + } + } + + public virtual async Task GetRoleCountAsync(RoleLookupCountInputDto input) + { + return await RoleRepository.GetCountAsync(input.Filter); + } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs index 1835f38952..75261b2cc4 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace Volo.Abp.Identity; @@ -7,6 +9,14 @@ public interface IUserRoleFinder { [Obsolete("Use GetRoleNamesAsync instead.")] Task GetRolesAsync(Guid userId); - + Task GetRoleNamesAsync(Guid userId); + + Task> SearchUserAsync(string filter, int page = 1); + + Task> SearchRoleAsync(string filter, int page = 1); + + Task> SearchUserByIdsAsync(Guid[] ids); + + Task> SearchRoleByNamesAsync(string[] names); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json index 49b22071cd..71b858f834 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json @@ -135,6 +135,8 @@ "ModificationTime": "وقت التعديل", "PasswordUpdateTime": "وقت تحديث كلمة المرور", "LockoutEndTime": "وقت انتهاء القفل", - "FailedAccessCount": "فشل عدد الوصول" + "FailedAccessCount": "فشل عدد الوصول", + "UserResourcePermissionProviderKeyLookupService": "المستخدم", + "RoleResourcePermissionProviderKeyLookupService": "الدور" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json index 8f0456c601..e84320059e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json @@ -135,6 +135,8 @@ "ModificationTime": "Doba úpravy", "PasswordUpdateTime": "Čas aktualizace hesla", "LockoutEndTime": "Čas konce uzamčení", - "FailedAccessCount": "Počet neúspěšných přístupů" + "FailedAccessCount": "Počet neúspěšných přístupů", + "UserResourcePermissionProviderKeyLookupService": "Uživatel", + "RoleResourcePermissionProviderKeyLookupService": "Role" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json index 19daf4d440..4064866f00 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json @@ -135,6 +135,8 @@ "LockoutEndTime": "Endzeit der Sperrung", "FailedAccessCount": "Anzahl der fehlgeschlagenen Zugriffe", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "E-Mail-Verifizierung für die Registrierung erzwingen", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Benutzerkonten werden nicht erstellt, es sei denn, sie verifizieren ihre E-Mail-Adressen." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Benutzerkonten werden nicht erstellt, es sei denn, sie verifizieren ihre E-Mail-Adressen.", + "UserResourcePermissionProviderKeyLookupService": "Benutzer", + "RoleResourcePermissionProviderKeyLookupService": "Rolle" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json index 1e2c8a23ce..ba610a993a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json @@ -128,6 +128,8 @@ "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Εάν το email μπορεί να ενημερωθεί από τον χρήστη.", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Επιβολή επαλήθευσης email για εγγραφή", "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Οι λογαριασμοί χρηστών δεν θα δημιουργηθούν εκτός αν επαληθεύσουν τις διευθύνσεις email τους.", - "Details": "Λεπτομέρειες" + "Details": "Λεπτομέρειες", + "UserResourcePermissionProviderKeyLookupService": "Χρήστης", + "RoleResourcePermissionProviderKeyLookupService": "Ρόλος" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json index 45f25bc864..9f10e1f188 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json @@ -137,6 +137,8 @@ "Description:Abp.Identity.UsersCanChange": "Allow users to change their Two Factor.", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Enforce email verification to register", "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "User accounts will not be created unless they verify their email addresses.", - "Details": "Details" + "Details": "Details", + "UserResourcePermissionProviderKeyLookupService": "User", + "RoleResourcePermissionProviderKeyLookupService": "Role" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json index f2cc74cef0..0deb6a4b56 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json @@ -135,6 +135,8 @@ "ModificationTime": "Modification time", "PasswordUpdateTime": "Password update time", "LockoutEndTime": "Lockout end time", - "FailedAccessCount": "Failed access count" + "FailedAccessCount": "Failed access count", + "UserResourcePermissionProviderKeyLookupService": "User", + "RoleResourcePermissionProviderKeyLookupService": "Role" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json index ff4d4302f8..a2a9414214 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json @@ -135,6 +135,8 @@ "ModificationTime": "tiempo de modificación", "PasswordUpdateTime": "Hora de actualización de contraseña", "LockoutEndTime": "Hora de finalización del bloqueo", - "FailedAccessCount": "Recuento de acceso fallido" + "FailedAccessCount": "Recuento de acceso fallido", + "UserResourcePermissionProviderKeyLookupService": "Usuario", + "RoleResourcePermissionProviderKeyLookupService": "Rol" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json index 024b443fec..e9a1911b52 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json @@ -139,6 +139,8 @@ "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "کاربران می‌توانند حساب ایجاد کنند اما تا زمانی که آدرس ایمیل خود را تایید نکنند نمی‌توانند وارد شوند.", "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "کاربران می‌توانند حساب ایجاد کنند اما تا زمانی که شماره تلفن خود را تایید نکنند نمی‌توانند وارد شوند.", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "اجباری کردن تایید ایمیل برای ثبت‌نام", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "حساب‌های کاربری ایجاد نخواهند شد مگر اینکه آدرس ایمیل خود را تایید کنند." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "حساب‌های کاربری ایجاد نخواهند شد مگر اینکه آدرس ایمیل خود را تایید کنند.", + "UserResourcePermissionProviderKeyLookupService": "کاربر", + "RoleResourcePermissionProviderKeyLookupService": "نقش" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json index 71cfe15712..2a37974cbb 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json @@ -135,6 +135,8 @@ "ModificationTime": "Muutosaika", "PasswordUpdateTime": "Salasanan päivityksen aika", "LockoutEndTime": "Lukituksen päättymisaika", - "FailedAccessCount": "Epäonnistuneet käyttöoikeudet" + "FailedAccessCount": "Epäonnistuneet käyttöoikeudet", + "UserResourcePermissionProviderKeyLookupService": "Käyttäjä", + "RoleResourcePermissionProviderKeyLookupService": "Rooli" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json index 61bc1dea98..323bb5927a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json @@ -135,6 +135,8 @@ "LockoutEndTime": "Heure de fin du verrouillage", "FailedAccessCount": "Nombre d'accès ayant échoué", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Exiger la vérification de l'e-mail pour s'inscrire", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Les comptes d’utilisateurs ne seront pas créés à moins qu’ils ne vérifient leurs adresses e-mail." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Les comptes d’utilisateurs ne seront pas créés à moins qu’ils ne vérifient leurs adresses e-mail.", + "UserResourcePermissionProviderKeyLookupService": "Utilisateur", + "RoleResourcePermissionProviderKeyLookupService": "Rôle" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json index 464426cf34..0d5fca3dde 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json @@ -135,6 +135,8 @@ "ModificationTime": "संशोधन का समय", "PasswordUpdateTime": "पासवर्ड अद्यतन समय", "LockoutEndTime": "तालाबंदी समाप्ति समय", - "FailedAccessCount": "विफल पहुंच गणना" + "FailedAccessCount": "विफल पहुंच गणना", + "UserResourcePermissionProviderKeyLookupService": "उपयोगकर्ता", + "RoleResourcePermissionProviderKeyLookupService": "भूमिका" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json index e8af421629..0e73aa5f1e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json @@ -135,6 +135,8 @@ "ModificationTime": "Vrijeme izmjene", "PasswordUpdateTime": "Vrijeme ažuriranja lozinke", "LockoutEndTime": "Vrijeme završetka zaključavanja", - "FailedAccessCount": "Broj neuspjelih pristupa" + "FailedAccessCount": "Broj neuspjelih pristupa", + "UserResourcePermissionProviderKeyLookupService": "Korisnik", + "RoleResourcePermissionProviderKeyLookupService": "Uloga" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json index 935a59e2f5..730a831d23 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json @@ -135,6 +135,8 @@ "ModificationTime": "Módosítási idő", "PasswordUpdateTime": "A jelszó frissítési ideje", "LockoutEndTime": "A zárolás befejezési ideje", - "FailedAccessCount": "Sikertelen hozzáférések száma" + "FailedAccessCount": "Sikertelen hozzáférések száma", + "UserResourcePermissionProviderKeyLookupService": "Felhasználó", + "RoleResourcePermissionProviderKeyLookupService": "Szerep" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json index ebf43ceab3..da53a10657 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json @@ -135,6 +135,8 @@ "ModificationTime": "Breytingartími", "PasswordUpdateTime": "Uppfærslutími lykilorðs", "LockoutEndTime": "Lokatími lokunar", - "FailedAccessCount": "Misheppnuð fjöldi aðgangs" + "FailedAccessCount": "Misheppnuð fjöldi aðgangs", + "UserResourcePermissionProviderKeyLookupService": "Notandi", + "RoleResourcePermissionProviderKeyLookupService": "Hlutverk" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json index 1d1d9771fd..163ff98754 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json @@ -135,6 +135,8 @@ "LockoutEndTime": "Ora di fine del blocco", "FailedAccessCount": "Conteggio accessi non riusciti", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Richiedi verifica email per la registrazione", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Gli account utente non verranno creati a meno che non verifichino i loro indirizzi email." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Gli account utente non verranno creati a meno che non verifichino i loro indirizzi email.", + "UserResourcePermissionProviderKeyLookupService": "Utente", + "RoleResourcePermissionProviderKeyLookupService": "Ruolo" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json index 2b405697ae..9836137c80 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json @@ -135,6 +135,8 @@ "LockoutEndTime": "Eindtijd uitsluiting", "FailedAccessCount": "Aantal mislukte toegangen", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "E-mailverificatie vereisen voor registratie", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Gebruikersaccounts worden niet aangemaakt tenzij ze hun e-mailadressen verifiëren." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Gebruikersaccounts worden niet aangemaakt tenzij ze hun e-mailadressen verifiëren.", + "UserResourcePermissionProviderKeyLookupService": "Gebruiker", + "RoleResourcePermissionProviderKeyLookupService": "Rol" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json index c3c8053556..18f33d89c1 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json @@ -135,6 +135,8 @@ "LockoutEndTime": "Czas zakończenia blokady", "FailedAccessCount": "Liczba nieudanych dostępów", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Wymagaj weryfikacji e-mail do rejestracji", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Konta użytkowników nie zostaną utworzone, dopóki nie zweryfikują swoich adresów e-mail." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Konta użytkowników nie zostaną utworzone, dopóki nie zweryfikują swoich adresów e-mail.", + "UserResourcePermissionProviderKeyLookupService": "Użytkownik", + "RoleResourcePermissionProviderKeyLookupService": "Rola" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json index 40ef80556f..cd796edbde 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json @@ -135,6 +135,8 @@ "ModificationTime": "Hora da modificação", "PasswordUpdateTime": "Hora de atualização da senha", "LockoutEndTime": "Hora de término do bloqueio", - "FailedAccessCount": "Contagem de acessos com falha" + "FailedAccessCount": "Contagem de acessos com falha", + "UserResourcePermissionProviderKeyLookupService": "Usuário", + "RoleResourcePermissionProviderKeyLookupService": "Perfil" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json index efe0c53541..3ebc98d179 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json @@ -135,6 +135,8 @@ "ModificationTime": "Timp de modificare", "PasswordUpdateTime": "Ora actualizării parolei", "LockoutEndTime": "Ora de încheiere a blocării", - "FailedAccessCount": "Număr de acces eșuat" + "FailedAccessCount": "Număr de acces eșuat", + "UserResourcePermissionProviderKeyLookupService": "Utilizator", + "RoleResourcePermissionProviderKeyLookupService": "Rol" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json index 6afaf14b1a..f9ddb814d4 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json @@ -135,6 +135,8 @@ "LockoutEndTime": "Время окончания блокировки", "FailedAccessCount": "Количество неудачных попыток доступа", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Требовать подтверждение электронной почты для регистрации", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Учетные записи пользователей не будут созданы, пока они не подтвердят свои адреса электронной почты." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Учетные записи пользователей не будут созданы, пока они не подтвердят свои адреса электронной почты.", + "UserResourcePermissionProviderKeyLookupService": "Пользователь", + "RoleResourcePermissionProviderKeyLookupService": "Роль" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json index e529910a5e..26486aa6ab 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json @@ -135,6 +135,8 @@ "ModificationTime": "Čas úpravy", "PasswordUpdateTime": "Čas aktualizácie hesla", "LockoutEndTime": "Čas ukončenia uzamknutia", - "FailedAccessCount": "Počet neúspešných prístupov" + "FailedAccessCount": "Počet neúspešných prístupov", + "UserResourcePermissionProviderKeyLookupService": "Používateľ", + "RoleResourcePermissionProviderKeyLookupService": "Rola" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json index c02577c385..8ae2a2f81b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json @@ -135,6 +135,8 @@ "ModificationTime": "Čas spreminjanja", "PasswordUpdateTime": "Čas posodobitve gesla", "LockoutEndTime": "Končni čas zaklepanja", - "FailedAccessCount": "Število neuspešnih dostopov" + "FailedAccessCount": "Število neuspešnih dostopov", + "UserResourcePermissionProviderKeyLookupService": "Uporabnik", + "RoleResourcePermissionProviderKeyLookupService": "Vloga" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sv.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sv.json index 166f32a10a..aef65e2b11 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sv.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sv.json @@ -135,6 +135,8 @@ "ModificationTime": "Tid för modifiering", "PasswordUpdateTime": "Uppdateringstid för lösenord", "LockoutEndTime": "Sluttid för låsning", - "FailedAccessCount": "Antal misslyckade åtkomster" + "FailedAccessCount": "Antal misslyckade åtkomster", + "UserResourcePermissionProviderKeyLookupService": "Användare", + "RoleResourcePermissionProviderKeyLookupService": "Roll" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json index 2da62b0355..0a6e4d393c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json @@ -135,6 +135,8 @@ "LockoutEndTime": "Kilitlenme bitiş zamanı", "FailedAccessCount": "Başarısız giriş denemesi sayısı", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Kayıt için e-posta doğrulaması zorunlu kıl", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Kullanıcı hesapları, e-posta adreslerini doğrulamadıkça oluşturulmayacaktır." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Kullanıcı hesapları, e-posta adreslerini doğrulamadıkça oluşturulmayacaktır.", + "UserResourcePermissionProviderKeyLookupService": "Kullanıcı", + "RoleResourcePermissionProviderKeyLookupService": "Rol" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json index a98baf6566..32c1dfe008 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json @@ -135,6 +135,8 @@ "LockoutEndTime": "Thời gian kết thúc khóa", "FailedAccessCount": "Số lượt truy cập không thành công", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Yêu cầu xác minh email để đăng ký", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Tài khoản người dùng sẽ không được tạo ra trừ khi họ xác minh địa chỉ email của mình." + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Tài khoản người dùng sẽ không được tạo ra trừ khi họ xác minh địa chỉ email của mình.", + "UserResourcePermissionProviderKeyLookupService": "Người dùng", + "RoleResourcePermissionProviderKeyLookupService": "Vai trò" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json index 0cfc117cf6..3a1239ddc7 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json @@ -135,6 +135,8 @@ "ModificationTime": "修改时间", "PasswordUpdateTime": "密码更新时间", "LockoutEndTime": "锁定结束时间", - "FailedAccessCount": "访问失败次数" + "FailedAccessCount": "访问失败次数", + "UserResourcePermissionProviderKeyLookupService": "用户", + "RoleResourcePermissionProviderKeyLookupService": "角色" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json index 39f6fe5267..a28cc6c7d4 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json @@ -135,6 +135,8 @@ "LockoutEndTime": "鎖定結束時間", "FailedAccessCount": "訪問失敗次數", "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "強制要求驗證電子郵件才能註冊", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "除非驗證他們的電子郵件地址,否則不會創建用戶帳戶。" + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "除非驗證他們的電子郵件地址,否則不會創建用戶帳戶。", + "UserResourcePermissionProviderKeyLookupService": "使用者", + "RoleResourcePermissionProviderKeyLookupService": "角色" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/RoleFinderResult.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/RoleFinderResult.cs new file mode 100644 index 0000000000..8fe118f13d --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/RoleFinderResult.cs @@ -0,0 +1,10 @@ +using System; + +namespace Volo.Abp.Identity; + +public class RoleFinderResult +{ + public Guid Id { get; set; } + + public string RoleName { get; set; } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/UserFinderResult.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/UserFinderResult.cs new file mode 100644 index 0000000000..48ba5ace7a --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/UserFinderResult.cs @@ -0,0 +1,10 @@ +using System; + +namespace Volo.Abp.Identity; + +public class UserFinderResult +{ + public Guid Id { get; set; } + + public string UserName { get; set; } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs index a9eefe019e..26bd8624b9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs @@ -31,11 +31,17 @@ public interface IIdentityRoleRepository : IBasicRepository bool includeDetails = false, CancellationToken cancellationToken = default ); + Task> GetListAsync( IEnumerable ids, CancellationToken cancellationToken = default ); + Task> GetListAsync( + IEnumerable names, + CancellationToken cancellationToken = default + ); + Task> GetDefaultOnesAsync( bool includeDetails = false, CancellationToken cancellationToken = default diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs index 3ec1b2fbb1..48d8b01a73 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs @@ -1,16 +1,21 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; namespace Volo.Abp.Identity; public class UserRoleFinder : IUserRoleFinder, ITransientDependency { protected IIdentityUserRepository IdentityUserRepository { get; } + protected IIdentityRoleRepository IdentityRoleRepository { get; } - public UserRoleFinder(IIdentityUserRepository identityUserRepository) + public UserRoleFinder(IIdentityUserRepository identityUserRepository, IIdentityRoleRepository identityRoleRepository) { IdentityUserRepository = identityUserRepository; + IdentityRoleRepository = identityRoleRepository; } [Obsolete("Use GetRoleNamesAsync instead.")] @@ -19,8 +24,62 @@ public class UserRoleFinder : IUserRoleFinder, ITransientDependency return (await IdentityUserRepository.GetRoleNamesAsync(userId)).ToArray(); } - public async Task GetRoleNamesAsync(Guid userId) + public virtual async Task GetRoleNamesAsync(Guid userId) { return (await IdentityUserRepository.GetRoleNamesAsync(userId)).ToArray(); } + + public virtual async Task> SearchUserAsync(string filter, int page = 1) + { + using (IdentityUserRepository.DisableTracking()) + { + page = page < 1 ? 1 : page; + var users = await IdentityUserRepository.GetListAsync(filter: filter, skipCount: (page - 1) * 10, maxResultCount: 10); + return users.Select(user => new UserFinderResult + { + Id = user.Id, + UserName = user.UserName + }).ToList(); + } + } + + public virtual async Task> SearchRoleAsync(string filter, int page = 1) + { + using (IdentityUserRepository.DisableTracking()) + { + page = page < 1 ? 1 : page; + var roles = await IdentityRoleRepository.GetListAsync(filter: filter, skipCount: (page - 1) * 10, maxResultCount: 10); + return roles.Select(user => new RoleFinderResult + { + Id = user.Id, + RoleName = user.Name + }).ToList(); + } + } + + public virtual async Task> SearchUserByIdsAsync(Guid[] ids) + { + using (IdentityUserRepository.DisableTracking()) + { + var users = await IdentityUserRepository.GetListByIdsAsync(ids); + return users.Select(user => new UserFinderResult + { + Id = user.Id, + UserName = user.UserName + }).ToList(); + } + } + + public virtual async Task> SearchRoleByNamesAsync(string[] names) + { + using (IdentityUserRepository.DisableTracking()) + { + var roles = await IdentityRoleRepository.GetListAsync(names); + return roles.Select(user => new RoleFinderResult + { + Id = user.Id, + RoleName = user.Name + }).ToList(); + } + } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs index ca6dc42d6f..1da7758f19 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs @@ -72,6 +72,13 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository> GetListAsync(IEnumerable names, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(t => names.Contains(t.Name)) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + public virtual async Task> GetDefaultOnesAsync( bool includeDetails = false, CancellationToken cancellationToken = default) { diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs index 1c2f1b61cb..ddbb2cfc55 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs @@ -52,6 +52,14 @@ public partial class IdentityUserIntegrationClientProxy : ClientProxyBase> SearchByIdsAsync(Guid[] ids) + { + return await RequestAsync>(nameof(SearchByIdsAsync), new ClientProxyRequestTypeValue + { + { typeof(Guid[]), ids } + }); + } + public virtual async Task GetCountAsync(UserLookupCountInputDto input) { return await RequestAsync(nameof(GetCountAsync), new ClientProxyRequestTypeValue @@ -59,4 +67,28 @@ public partial class IdentityUserIntegrationClientProxy : ClientProxyBase> SearchRoleAsync(RoleLookupSearchInputDto input) + { + return await RequestAsync>(nameof(SearchRoleAsync), new ClientProxyRequestTypeValue + { + { typeof(RoleLookupSearchInputDto), input } + }); + } + + public virtual async Task> SearchRoleByNamesAsync(String[] names) + { + return await RequestAsync>(nameof(SearchRoleByNamesAsync), new ClientProxyRequestTypeValue + { + { typeof(String[]), names } + }); + } + + public virtual async Task GetRoleCountAsync(RoleLookupCountInputDto input) + { + return await RequestAsync(nameof(GetRoleCountAsync), new ClientProxyRequestTypeValue + { + { typeof(RoleLookupCountInputDto), input } + }); + } } diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json index 33efd0a6e7..3937d99aa9 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json @@ -200,6 +200,18 @@ "constraintTypes": null, "bindingSourceId": "ModelBinding", "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ExtraProperties", + "jsonName": null, + "type": "Volo.Abp.Data.ExtraPropertyDictionary", + "typeSimple": "{string:object}", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" } ], "returnValue": { @@ -673,6 +685,18 @@ "constraintTypes": null, "bindingSourceId": "ModelBinding", "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ExtraProperties", + "jsonName": null, + "type": "Volo.Abp.Data.ExtraPropertyDictionary", + "typeSimple": "{string:object}", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" } ], "returnValue": { @@ -1220,6 +1244,18 @@ "constraintTypes": null, "bindingSourceId": "ModelBinding", "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ExtraProperties", + "jsonName": null, + "type": "Volo.Abp.Data.ExtraPropertyDictionary", + "typeSimple": "{string:object}", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" } ], "returnValue": { @@ -1348,6 +1384,23 @@ "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" } }, + { + "name": "SearchByIdsAsync", + "parametersOnMethod": [ + { + "name": "ids", + "typeAsString": "System.Guid[], System.Private.CoreLib", + "type": "System.Guid[]", + "typeSimple": "[string]", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, { "name": "GetCountAsync", "parametersOnMethod": [ @@ -1364,6 +1417,57 @@ "type": "System.Int64", "typeSimple": "number" } + }, + { + "name": "SearchRoleAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.RoleLookupSearchInputDto, Volo.Abp.Identity.Application.Contracts", + "type": "Volo.Abp.Identity.RoleLookupSearchInputDto", + "typeSimple": "Volo.Abp.Identity.RoleLookupSearchInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + { + "name": "SearchRoleByNamesAsync", + "parametersOnMethod": [ + { + "name": "ids", + "typeAsString": "System.String[], System.Private.CoreLib", + "type": "System.String[]", + "typeSimple": "[string]", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + { + "name": "GetRoleCountAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.RoleLookupCountInputDto, Volo.Abp.Identity.Application.Contracts", + "type": "Volo.Abp.Identity.RoleLookupCountInputDto", + "typeSimple": "Volo.Abp.Identity.RoleLookupCountInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Int64", + "typeSimple": "number" + } } ] } @@ -1544,6 +1648,55 @@ "constraintTypes": null, "bindingSourceId": "ModelBinding", "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ExtraProperties", + "jsonName": null, + "type": "Volo.Abp.Data.ExtraPropertyDictionary", + "typeSimple": "{string:object}", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService" + }, + "SearchByIdsAsyncByIds": { + "uniqueName": "SearchByIdsAsyncByIds", + "name": "SearchByIdsAsync", + "httpMethod": "GET", + "url": "integration-api/identity/users/search/by-ids", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "ids", + "typeAsString": "System.Guid[], System.Private.CoreLib", + "type": "System.Guid[]", + "typeSimple": "[string]", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "ids", + "name": "ids", + "jsonName": null, + "type": "System.Guid[]", + "typeSimple": "[string]", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" } ], "returnValue": { @@ -1589,6 +1742,165 @@ }, "allowAnonymous": null, "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService" + }, + "SearchRoleAsyncByInput": { + "uniqueName": "SearchRoleAsyncByInput", + "name": "SearchRoleAsync", + "httpMethod": "GET", + "url": "integration-api/identity/users/search/roles", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.RoleLookupSearchInputDto, Volo.Abp.Identity.Application.Contracts", + "type": "Volo.Abp.Identity.RoleLookupSearchInputDto", + "typeSimple": "Volo.Abp.Identity.RoleLookupSearchInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "jsonName": null, + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "jsonName": null, + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ExtraProperties", + "jsonName": null, + "type": "Volo.Abp.Data.ExtraPropertyDictionary", + "typeSimple": "{string:object}", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService" + }, + "SearchRoleByNamesAsyncByNames": { + "uniqueName": "SearchRoleByNamesAsyncByNames", + "name": "SearchRoleByNamesAsync", + "httpMethod": "GET", + "url": "integration-api/identity/users/search/roles/by-names", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "names", + "typeAsString": "System.String[], System.Private.CoreLib", + "type": "System.String[]", + "typeSimple": "[string]", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "names", + "name": "names", + "jsonName": null, + "type": "System.String[]", + "typeSimple": "[string]", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService" + }, + "GetRoleCountAsyncByInput": { + "uniqueName": "GetRoleCountAsyncByInput", + "name": "GetRoleCountAsync", + "httpMethod": "GET", + "url": "integration-api/identity/users/count/roles", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.RoleLookupCountInputDto, Volo.Abp.Identity.Application.Contracts", + "type": "Volo.Abp.Identity.RoleLookupCountInputDto", + "typeSimple": "Volo.Abp.Identity.RoleLookupCountInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "System.Int64", + "typeSimple": "number" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService" } } } diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs index 201c9f3eb0..ed7f0f5382 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -25,8 +26,59 @@ public class HttpClientUserRoleFinder : IUserRoleFinder, ITransientDependency return output.Items.Select(r => r.Name).ToArray(); } - public async Task GetRoleNamesAsync(Guid userId) + public virtual async Task GetRoleNamesAsync(Guid userId) { return await _userIntegrationService.GetRoleNamesAsync(userId); } + + public virtual async Task> SearchUserAsync(string filter, int page = 1) + { + page = page < 1 ? 1 : page; + var users = await _userIntegrationService.SearchAsync(new UserLookupSearchInputDto() + { + Filter = filter, + SkipCount = (page - 1) * 10 + }); + return users.Items.Select(u => new UserFinderResult + { + Id = u.Id, + UserName = u.UserName + }).ToList(); + } + + public virtual async Task> SearchRoleAsync(string filter, int page = 1) + { + page = page < 1 ? 1 : page; + var roles = await _userIntegrationService.SearchRoleAsync(new RoleLookupSearchInputDto() + { + Filter = filter, + SkipCount = (page - 1) * 10 + }); + + return roles.Items.Select(r => new RoleFinderResult + { + Id = r.Id, + RoleName = r.Name + }).ToList(); + } + + public virtual async Task> SearchUserByIdsAsync(Guid[] ids) + { + var users = await _userIntegrationService.SearchByIdsAsync(ids); + return users.Items.Select(u => new UserFinderResult + { + Id = u.Id, + UserName = u.UserName + }).ToList(); + } + + public virtual async Task> SearchRoleByNamesAsync(string[] names) + { + var roles = await _userIntegrationService.SearchRoleByNamesAsync(names); + return roles.Items.Select(r => new RoleFinderResult + { + Id = r.Id, + RoleName = r.Name + }).ToList(); + } } diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs index 2a84385e48..a30b73d5cd 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs @@ -20,7 +20,7 @@ public class IdentityUserIntegrationController : AbpControllerBase, IIdentityUse { UserIntegrationService = userIntegrationService; } - + [HttpGet] [Route("{id}/role-names")] public virtual Task GetRoleNamesAsync(Guid id) @@ -49,10 +49,38 @@ public class IdentityUserIntegrationController : AbpControllerBase, IIdentityUse return UserIntegrationService.SearchAsync(input); } + [HttpGet] + [Route("search/by-ids")] + public virtual Task> SearchByIdsAsync(Guid[] ids) + { + return UserIntegrationService.SearchByIdsAsync(ids); + } + [HttpGet] [Route("count")] public Task GetCountAsync(UserLookupCountInputDto input) { return UserIntegrationService.GetCountAsync(input); } -} \ No newline at end of file + + [HttpGet] + [Route("search/roles")] + public virtual Task> SearchRoleAsync(RoleLookupSearchInputDto input) + { + return UserIntegrationService.SearchRoleAsync(input); + } + + [HttpGet] + [Route("search/roles/by-names")] + public virtual Task> SearchRoleByNamesAsync(string[] names) + { + return UserIntegrationService.SearchRoleByNamesAsync(names); + } + + [HttpGet] + [Route("count/roles")] + public virtual Task GetRoleCountAsync(RoleLookupCountInputDto input) + { + return UserIntegrationService.GetRoleCountAsync(input); + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs index 7deee94160..f613a3ee88 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs @@ -78,6 +78,13 @@ public class MongoIdentityRoleRepository : MongoDbRepository> GetListAsync(IEnumerable names, CancellationToken cancellationToken = default) + { + return await (await GetQueryableAsync(cancellationToken)) + .Where(x => names.Contains(x.Name)) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + public virtual async Task> GetDefaultOnesAsync( bool includeDetails = false, CancellationToken cancellationToken = default) diff --git a/modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js b/modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js index 250abbc47b..6de3aeb8d5 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js +++ b/modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js @@ -20,7 +20,7 @@ volo.abp.identity.identityRole.getList = function(input, ajaxParams) { return abp.ajax($.extend(true, { - url: abp.appPath + 'api/identity/roles' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '', + url: abp.appPath + 'api/identity/roles' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '', type: 'GET' }, ajaxParams)); }; @@ -73,7 +73,7 @@ volo.abp.identity.identityUser.getList = function(input, ajaxParams) { return abp.ajax($.extend(true, { - url: abp.appPath + 'api/identity/users' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '', + url: abp.appPath + 'api/identity/users' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '', type: 'GET' }, ajaxParams)); }; @@ -163,7 +163,7 @@ volo.abp.identity.identityUserLookup.search = function(input, ajaxParams) { return abp.ajax($.extend(true, { - url: abp.appPath + 'api/identity/users/lookup/search' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '', + url: abp.appPath + 'api/identity/users/lookup/search' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '', type: 'GET' }, ajaxParams)); }; diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/AbpPermissionManagementDomainIdentityModule.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/AbpPermissionManagementDomainIdentityModule.cs index 973577ccff..43399a134d 100644 --- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/AbpPermissionManagementDomainIdentityModule.cs +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/AbpPermissionManagementDomainIdentityModule.cs @@ -1,4 +1,5 @@ using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; using Volo.Abp.Identity; using Volo.Abp.Modularity; using Volo.Abp.Users; @@ -22,6 +23,12 @@ public class AbpPermissionManagementDomainIdentityModule : AbpModule //TODO: Can we prevent duplication of permission names without breaking the design and making the system complicated options.ProviderPolicies[UserPermissionValueProvider.ProviderName] = "AbpIdentity.Users.ManagePermissions"; options.ProviderPolicies[RolePermissionValueProvider.ProviderName] = "AbpIdentity.Roles.ManagePermissions"; + + options.ResourceManagementProviders.Add(); + options.ResourceManagementProviders.Add(); + + options.ResourcePermissionProviderKeyLookupServices.Add(); + options.ResourcePermissionProviderKeyLookupServices.Add(); }); } } diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs index cb63b2681a..82200f763f 100644 --- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus; @@ -14,15 +15,18 @@ public class RoleDeletedEventHandler : ITransientDependency { protected IPermissionManager PermissionManager { get; } + protected IResourcePermissionManager ResourcePermissionManager { get; } - public RoleDeletedEventHandler(IPermissionManager permissionManager) + public RoleDeletedEventHandler(IPermissionManager permissionManager, IResourcePermissionManager resourcePermissionManager) { PermissionManager = permissionManager; + ResourcePermissionManager = resourcePermissionManager; } [UnitOfWork] public virtual async Task HandleEventAsync(EntityDeletedEto eventData) { await PermissionManager.DeleteAsync(RolePermissionValueProvider.ProviderName, eventData.Entity.Name); + await ResourcePermissionManager.DeleteAsync(RoleResourcePermissionValueProvider.ProviderName, eventData.Entity.Name); } } diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs index e97d524cd7..5cd2dda193 100644 --- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs @@ -49,9 +49,8 @@ public class RolePermissionManagementProvider : PermissionManagementProvider } - if (providerName == UserPermissionValueProvider.ProviderName) + if (providerName == UserPermissionValueProvider.ProviderName && Guid.TryParse(providerKey, out var userId)) { - var userId = Guid.Parse(providerKey); var roleNames = await UserRoleFinder.GetRoleNamesAsync(userId); foreach (var roleName in roleNames) diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionManagementProvider.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionManagementProvider.cs new file mode 100644 index 0000000000..bce070130c --- /dev/null +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionManagementProvider.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Guids; +using Volo.Abp.Identity; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.PermissionManagement.Identity; + +public class RoleResourcePermissionManagementProvider : ResourcePermissionManagementProvider +{ + public override string Name => RoleResourcePermissionValueProvider.ProviderName; + + protected IUserRoleFinder UserRoleFinder { get; } + + public RoleResourcePermissionManagementProvider( + IResourcePermissionGrantRepository resourcepPrmissionGrantRepository, + IGuidGenerator guidGenerator, + ICurrentTenant currentTenant, + IUserRoleFinder userRoleFinder) + : base( + resourcepPrmissionGrantRepository, + guidGenerator, + currentTenant) + { + UserRoleFinder = userRoleFinder; + } + + public override async Task CheckAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + var multipleGrantInfo = await CheckAsync(new[] { name }, resourceName, resourceKey, providerName, providerKey); + + return multipleGrantInfo.Result.Values.First(); + } + + public override async Task CheckAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) + { + using (ResourcePermissionGrantRepository.DisableTracking()) + { + var multiplePermissionValueProviderGrantInfo = new MultipleResourcePermissionValueProviderGrantInfo(names); + var resourcePermissionGrants = new List(); + + if (providerName == Name) + { + resourcePermissionGrants.AddRange(await ResourcePermissionGrantRepository.GetListAsync(names, resourceName, resourceKey, providerName, providerKey)); + } + + if (providerName == UserResourcePermissionValueProvider.ProviderName && Guid.TryParse(providerKey, out var userId)) + { + var roleNames = await UserRoleFinder.GetRoleNamesAsync(userId); + + foreach (var roleName in roleNames) + { + resourcePermissionGrants.AddRange(await ResourcePermissionGrantRepository.GetListAsync(names, resourceName, resourceKey, Name, roleName)); + } + } + + resourcePermissionGrants = resourcePermissionGrants.Distinct().ToList(); + if (!resourcePermissionGrants.Any()) + { + return multiplePermissionValueProviderGrantInfo; + } + + foreach (var permissionName in names) + { + var resourcePermissionGrant = resourcePermissionGrants.FirstOrDefault(x => x.Name == permissionName); + if (resourcePermissionGrant != null) + { + multiplePermissionValueProviderGrantInfo.Result[permissionName] = new ResourcePermissionValueProviderGrantInfo(true, resourcePermissionGrant.ProviderKey); + } + } + + return multiplePermissionValueProviderGrantInfo; + } + } +} diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionProviderKeyLookupService.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionProviderKeyLookupService.cs new file mode 100644 index 0000000000..fa9fc31f79 --- /dev/null +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionProviderKeyLookupService.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.Identity.Localization; +using Volo.Abp.Localization; + +namespace Volo.Abp.PermissionManagement.Identity; + +public class RoleResourcePermissionProviderKeyLookupService : IResourcePermissionProviderKeyLookupService, ITransientDependency +{ + public string Name => RoleResourcePermissionValueProvider.ProviderName; + + public ILocalizableString DisplayName { get; } + + protected IUserRoleFinder UserRoleFinder { get; } + + public RoleResourcePermissionProviderKeyLookupService(IUserRoleFinder userRoleFinder) + { + UserRoleFinder = userRoleFinder; + DisplayName = LocalizableString.Create(nameof(RoleResourcePermissionProviderKeyLookupService)); + } + + public virtual async Task> SearchAsync(string filter = null, int page = 1, CancellationToken cancellationToken = default) + { + var roles = await UserRoleFinder.SearchRoleAsync(filter, page); + return roles.Select(r => new ResourcePermissionProviderKeyInfo(r.RoleName, r.RoleName)).ToList(); + } + + public virtual async Task> SearchAsync(string[] keys, CancellationToken cancellationToken = default) + { + var roles = await UserRoleFinder.SearchRoleByNamesAsync(keys.Distinct().ToArray()); + return roles.Select(r => new ResourcePermissionProviderKeyInfo(r.RoleName, r.RoleName)).ToList(); + } +} diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleUpdateEventHandler.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleUpdateEventHandler.cs index ca865063e0..bf9a86c06d 100644 --- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleUpdateEventHandler.cs +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleUpdateEventHandler.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Identity; @@ -12,13 +13,19 @@ public class RoleUpdateEventHandler : { protected IPermissionManager PermissionManager { get; } protected IPermissionGrantRepository PermissionGrantRepository { get; } + protected IResourcePermissionManager ResourcePermissionManager { get; } + protected IResourcePermissionGrantRepository ResourcePermissionGrantRepository { get; } public RoleUpdateEventHandler( IPermissionManager permissionManager, - IPermissionGrantRepository permissionGrantRepository) + IPermissionGrantRepository permissionGrantRepository, + IResourcePermissionManager resourcePermissionManager, + IResourcePermissionGrantRepository resourcePermissionGrantRepository) { PermissionManager = permissionManager; PermissionGrantRepository = permissionGrantRepository; + ResourcePermissionManager = resourcePermissionManager; + ResourcePermissionGrantRepository = resourcePermissionGrantRepository; } public async Task HandleEventAsync(IdentityRoleNameChangedEto eventData) @@ -28,5 +35,11 @@ public class RoleUpdateEventHandler : { await PermissionManager.UpdateProviderKeyAsync(permissionGrant, eventData.Name); } + + var resourcePermissionGrantsInRole = await ResourcePermissionGrantRepository.GetListAsync(RoleResourcePermissionValueProvider.ProviderName, eventData.OldName); + foreach (var resourcePermissionGrant in resourcePermissionGrantsInRole) + { + await ResourcePermissionManager.UpdateProviderKeyAsync(resourcePermissionGrant, eventData.Name); + } } } diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserDeletedEventHandler.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserDeletedEventHandler.cs index 35aaba29ae..b10cef8fe4 100644 --- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserDeletedEventHandler.cs +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserDeletedEventHandler.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus.Distributed; @@ -13,15 +14,18 @@ public class UserDeletedEventHandler : ITransientDependency { protected IPermissionManager PermissionManager { get; } + protected IResourcePermissionManager ResourcePermissionManager { get; } - public UserDeletedEventHandler(IPermissionManager permissionManager) + public UserDeletedEventHandler(IPermissionManager permissionManager, IResourcePermissionManager resourcePermissionManager) { PermissionManager = permissionManager; + ResourcePermissionManager = resourcePermissionManager; } [UnitOfWork] public virtual async Task HandleEventAsync(EntityDeletedEto eventData) { await PermissionManager.DeleteAsync(UserPermissionValueProvider.ProviderName, eventData.Entity.Id.ToString()); + await ResourcePermissionManager.DeleteAsync(UserResourcePermissionValueProvider.ProviderName, eventData.Entity.Id.ToString()); } } diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserResourcePermissionManagementProvider.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserResourcePermissionManagementProvider.cs new file mode 100644 index 0000000000..ef165d422d --- /dev/null +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserResourcePermissionManagementProvider.cs @@ -0,0 +1,22 @@ +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.PermissionManagement.Identity; + +public class UserResourcePermissionManagementProvider : ResourcePermissionManagementProvider +{ + public override string Name => UserResourcePermissionValueProvider.ProviderName; + + public UserResourcePermissionManagementProvider( + IResourcePermissionGrantRepository resourcePermissionGrantRepository, + IGuidGenerator guidGenerator, + ICurrentTenant currentTenant) + : base( + resourcePermissionGrantRepository, + guidGenerator, + currentTenant) + { + + } +} diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserResourcePermissionProviderKeyLookupService.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserResourcePermissionProviderKeyLookupService.cs new file mode 100644 index 0000000000..83f0e79099 --- /dev/null +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserResourcePermissionProviderKeyLookupService.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.Identity.Localization; +using Volo.Abp.Localization; + +namespace Volo.Abp.PermissionManagement.Identity; + +public class UserResourcePermissionProviderKeyLookupService : IResourcePermissionProviderKeyLookupService, ITransientDependency +{ + public string Name => UserResourcePermissionValueProvider.ProviderName; + + public ILocalizableString DisplayName { get; } + + protected IUserRoleFinder UserRoleFinder { get; } + + public UserResourcePermissionProviderKeyLookupService(IUserRoleFinder userRoleFinder) + { + UserRoleFinder = userRoleFinder; + DisplayName = LocalizableString.Create(nameof(UserResourcePermissionProviderKeyLookupService)); + } + + public virtual async Task> SearchAsync(string filter = null, int page = 1, CancellationToken cancellationToken = default) + { + var users = await UserRoleFinder.SearchUserAsync(filter, page); + return users.Select(u => new ResourcePermissionProviderKeyInfo(u.Id.ToString(), u.UserName)).ToList(); + } + + public virtual async Task> SearchAsync(string[] keys, CancellationToken cancellationToken = default) + { + var ids = keys + .Select(key => Guid.TryParse(key, out var id) ? (Guid?)id : null) + .Where(id => id.HasValue) + .Select(id => id.Value) + .Distinct() + .ToArray(); + var users = await UserRoleFinder.SearchUserByIdsAsync(ids.ToArray()); + return users.Select(u => new ResourcePermissionProviderKeyInfo(u.Id.ToString(), u.UserName)).ToList(); + } +} diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/RoleResourcePermissionManagerExtensions.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/RoleResourcePermissionManagerExtensions.cs new file mode 100644 index 0000000000..53ff327f7b --- /dev/null +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/RoleResourcePermissionManagerExtensions.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Authorization.Permissions; + +namespace Volo.Abp.PermissionManagement; + +public static class RoleResourceresourcePermissionManagerExtensions +{ + public static Task GetForRoleAsync([NotNull] this IResourcePermissionManager resourcePermissionManager, string roleName, string permissionName, [NotNull] string resourceName, [NotNull] string resourceKey) + { + Check.NotNull(resourcePermissionManager, nameof(resourcePermissionManager)); + + return resourcePermissionManager.GetAsync(permissionName, resourceName, resourceKey, RolePermissionValueProvider.ProviderName, roleName); + } + + public static Task> GetAllForRoleAsync([NotNull] this IResourcePermissionManager resourcePermissionManager, string roleName, [NotNull] string resourceName, [NotNull] string resourceKey) + { + Check.NotNull(resourcePermissionManager, nameof(resourcePermissionManager)); + + return resourcePermissionManager.GetAllAsync(resourceName, resourceKey, RolePermissionValueProvider.ProviderName, roleName); + } + + public static Task SetForRoleAsync([NotNull] this IResourcePermissionManager resourcePermissionManager, string roleName, [NotNull] string permissionName, [NotNull] string resourceName, [NotNull] string resourceKey, bool isGranted) + { + Check.NotNull(resourcePermissionManager, nameof(resourcePermissionManager)); + + return resourcePermissionManager.SetAsync(permissionName, resourceName, resourceKey, RolePermissionValueProvider.ProviderName, roleName, isGranted); + } +} diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/UserResourcePermissionManagerExtensions.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/UserResourcePermissionManagerExtensions.cs new file mode 100644 index 0000000000..c0fe2eb845 --- /dev/null +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/UserResourcePermissionManagerExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Authorization.Permissions.Resources; + +namespace Volo.Abp.PermissionManagement; + +public static class UserResourcePermissionManagerExtensions +{ + public static Task> GetAllForUserAsync([NotNull] this IResourcePermissionManager resourcePermissionManager, Guid userId, [NotNull] string resourceName, [NotNull] string resourceKey) + { + Check.NotNull(resourcePermissionManager, nameof(resourcePermissionManager)); + + return resourcePermissionManager.GetAllAsync(resourceName, resourceKey, UserResourcePermissionValueProvider.ProviderName, userId.ToString()); + } + + public static Task SetForUserAsync([NotNull] this IResourcePermissionManager resourcePermissionManager, Guid userId, [NotNull] string name, [NotNull] string resourceName, [NotNull] string resourceKey, bool isGranted) + { + Check.NotNull(resourcePermissionManager, nameof(resourcePermissionManager)); + + return resourcePermissionManager.SetAsync(name, resourceName, resourceKey, UserResourcePermissionValueProvider.ProviderName, userId.ToString(), isGranted); + } +} diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/UserRoleFinder_Tests.cs b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/UserRoleFinder_Tests.cs index 524c7c25f3..56f9049b92 100644 --- a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/UserRoleFinder_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/UserRoleFinder_Tests.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; using Shouldly; using Xunit; @@ -19,11 +16,47 @@ public class UserRoleFinder_Tests : AbpIdentityDomainTestBase } [Fact] - public async Task GetRolesAsync() + public async Task GetRoleNamesAsync() { - var roleNames = await _userRoleFinder.GetRolesAsync(_testData.UserJohnId); + var roleNames = await _userRoleFinder.GetRoleNamesAsync(_testData.UserJohnId); roleNames.ShouldNotBeEmpty(); roleNames.ShouldContain(x => x == "moderator"); roleNames.ShouldContain(x => x == "supporter"); } + + [Fact] + public async Task SearchUserAsync() + { + var userResults = await _userRoleFinder.SearchUserAsync("john"); + userResults.ShouldNotBeEmpty(); + userResults.ShouldContain(x => x.Id == _testData.UserJohnId); + } + + [Fact] + public async Task SearchRoleAsync() + { + var roleResults = await _userRoleFinder.SearchRoleAsync("moderator"); + roleResults.ShouldNotBeEmpty(); + roleResults.ShouldContain(x => x.RoleName == "moderator"); + } + + [Fact] + public async Task SearchUserByIdsAsync() + { + var userResults = await _userRoleFinder.SearchUserByIdsAsync(new[] { _testData.UserJohnId, _testData.UserBobId }); + userResults.ShouldNotBeEmpty(); + userResults.Count.ShouldBe(2); + userResults.ShouldContain(x => x.Id == _testData.UserJohnId && x.UserName == "john.nash"); + userResults.ShouldContain(x => x.Id == _testData.UserBobId && x.UserName == "bob"); + } + + [Fact] + public async Task SearchRoleByNamesAsync() + { + var roleResults = await _userRoleFinder.SearchRoleByNamesAsync(new[] { "moderator", "manager" }); + roleResults.ShouldNotBeEmpty(); + roleResults.Count.ShouldBe(2); + roleResults.ShouldContain(x => x.RoleName == "moderator"); + roleResults.ShouldContain(x => x.RoleName == "manager"); + } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionDefinitionListResultDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionDefinitionListResultDto.cs new file mode 100644 index 0000000000..ea1ce882df --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionDefinitionListResultDto.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class GetResourcePermissionDefinitionListResultDto +{ + public List Permissions { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionListResultDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionListResultDto.cs new file mode 100644 index 0000000000..b9c4db2190 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionListResultDto.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class GetResourcePermissionListResultDto +{ + public List Permissions { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionWithProviderListResultDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionWithProviderListResultDto.cs new file mode 100644 index 0000000000..dcf4556d04 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourcePermissionWithProviderListResultDto.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class GetResourcePermissionWithProviderListResultDto +{ + public List Permissions { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourceProviderListResultDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourceProviderListResultDto.cs new file mode 100644 index 0000000000..ede31a6ca5 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GetResourceProviderListResultDto.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class GetResourceProviderListResultDto +{ + public List Providers { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GrantedResourcePermissionDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GrantedResourcePermissionDto.cs new file mode 100644 index 0000000000..bbb1de112a --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/GrantedResourcePermissionDto.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.PermissionManagement; + +public class GrantedResourcePermissionDto +{ + public string Name { get; set; } + + public string DisplayName { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/IPermissionAppService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/IPermissionAppService.cs index 819d643a21..dd24d436be 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/IPermissionAppService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/IPermissionAppService.cs @@ -11,4 +11,18 @@ public interface IPermissionAppService : IApplicationService Task GetByGroupAsync([NotNull] string groupName, [NotNull] string providerName, [NotNull] string providerKey); Task UpdateAsync([NotNull] string providerName, [NotNull] string providerKey, UpdatePermissionsDto input); + + Task GetResourceProviderKeyLookupServicesAsync(string resourceName); + + Task SearchResourceProviderKeyAsync(string resourceName, string serviceName, string filter, int page); + + Task GetResourceDefinitionsAsync([NotNull] string resourceName); + + Task GetResourceAsync([NotNull] string resourceName, [NotNull] string resourceKey); + + Task GetResourceByProviderAsync([NotNull] string resourceName, [NotNull] string resourceKey, [NotNull] string providerName, [NotNull] string providerKey); + + Task UpdateResourceAsync([NotNull] string resourceName, [NotNull] string resourceKey, UpdateResourcePermissionsDto input); + + Task DeleteResourceAsync([NotNull] string resourceName, [NotNull] string resourceKey, [NotNull] string providerName, [NotNull] string providerKey); } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionDefinitionDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionDefinitionDto.cs new file mode 100644 index 0000000000..b8218b562c --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionDefinitionDto.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionDefinitionDto +{ + public string Name { get; set; } + + public string DisplayName { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionGrantInfoDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionGrantInfoDto.cs new file mode 100644 index 0000000000..cf286815a5 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionGrantInfoDto.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionGrantInfoDto +{ + public string ProviderName { get; set; } + + public string ProviderKey { get; set; } + + public string ProviderDisplayName { get; set; } + + public string ProviderNameDisplayName { get; set; } + + public List Permissions { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionWithProdiverGrantInfoDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionWithProdiverGrantInfoDto.cs new file mode 100644 index 0000000000..d56e217cd6 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionWithProdiverGrantInfoDto.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionWithProdiverGrantInfoDto +{ + public string Name { get; set; } + + public string DisplayName { get; set; } + + public List Providers { get; set; } + + public bool IsGranted { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourceProviderDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourceProviderDto.cs new file mode 100644 index 0000000000..98ee22c6b7 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourceProviderDto.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.PermissionManagement; + +public class ResourceProviderDto +{ + public string Name { get; set; } + + public string DisplayName { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/SearchProviderKeyInfo.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/SearchProviderKeyInfo.cs new file mode 100644 index 0000000000..efc6ae2b18 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/SearchProviderKeyInfo.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.PermissionManagement; + +public class SearchProviderKeyInfo +{ + public string ProviderKey { get; set; } + + public string ProviderDisplayName { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/SearchProviderKeyListResultDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/SearchProviderKeyListResultDto.cs new file mode 100644 index 0000000000..7fe4edd6e7 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/SearchProviderKeyListResultDto.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class SearchProviderKeyListResultDto +{ + public List Keys { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/UpdateResourcePermissionsDto.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/UpdateResourcePermissionsDto.cs new file mode 100644 index 0000000000..f82c27ff02 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/UpdateResourcePermissionsDto.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class UpdateResourcePermissionsDto +{ + public string ProviderName { get; set; } + + public string ProviderKey { get; set; } + + public List Permissions { get; set; } +} 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 e628c39644..c27a0b4469 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 @@ -18,12 +18,18 @@ public class PermissionAppService : ApplicationService, IPermissionAppService { protected PermissionManagementOptions Options { get; } protected IPermissionManager PermissionManager { get; } + protected IPermissionChecker PermissionChecker { get; } + protected IResourcePermissionManager ResourcePermissionManager { get; } + protected IResourcePermissionGrantRepository ResourcePermissionGrantRepository { get; } protected IPermissionDefinitionManager PermissionDefinitionManager { get; } protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } public PermissionAppService( IPermissionManager permissionManager, + IPermissionChecker permissionChecker, IPermissionDefinitionManager permissionDefinitionManager, + IResourcePermissionManager resourcePermissionManager, + IResourcePermissionGrantRepository resourcePermissionGrantRepository, IOptions options, ISimpleStateCheckerManager simpleStateCheckerManager) { @@ -32,6 +38,9 @@ public class PermissionAppService : ApplicationService, IPermissionAppService Options = options.Value; PermissionManager = permissionManager; + PermissionChecker = permissionChecker; + ResourcePermissionManager = resourcePermissionManager; + ResourcePermissionGrantRepository = resourcePermissionGrantRepository; PermissionDefinitionManager = permissionDefinitionManager; SimpleStateCheckerManager = simpleStateCheckerManager; } @@ -160,6 +169,203 @@ public class PermissionAppService : ApplicationService, IPermissionAppService } } + public virtual async Task GetResourceProviderKeyLookupServicesAsync(string resourceName) + { + var resourcePermissions = await ResourcePermissionManager.GetAvailablePermissionsAsync(resourceName); + if (!resourcePermissions.Any() || + !await AuthorizationService.IsGrantedAnyAsync(resourcePermissions.Select(p => p.ManagementPermissionName!).ToArray())) + { + return new GetResourceProviderListResultDto(); + } + + var lookupServices = await ResourcePermissionManager.GetProviderKeyLookupServicesAsync(); + return new GetResourceProviderListResultDto + { + Providers = lookupServices.Select(s => new ResourceProviderDto + { + Name = s.Name, + DisplayName = s.DisplayName.Localize(StringLocalizerFactory), + }).ToList() + }; + } + + public virtual async Task SearchResourceProviderKeyAsync(string resourceName, string serviceName, string filter, int page) + { + var resourcePermissions = await ResourcePermissionManager.GetAvailablePermissionsAsync(resourceName); + if (resourcePermissions.IsNullOrEmpty() || + !await AuthorizationService.IsGrantedAnyAsync(resourcePermissions.Select(p => p.ManagementPermissionName!).ToArray())) + { + return new SearchProviderKeyListResultDto(); + } + + var lookupService = await ResourcePermissionManager.GetProviderKeyLookupServiceAsync(serviceName); + var keys = await lookupService.SearchAsync(filter, page); + return new SearchProviderKeyListResultDto + { + Keys = keys.Select(x => new SearchProviderKeyInfo + { + ProviderKey = x.ProviderKey, + ProviderDisplayName = x.ProviderDisplayName, + }).ToList() + }; + } + + public virtual async Task GetResourceDefinitionsAsync(string resourceName) + { + var result = new GetResourcePermissionDefinitionListResultDto + { + Permissions = new List() + }; + + var resourcePermissions = await ResourcePermissionManager.GetAvailablePermissionsAsync(resourceName); + var permissionGrants = (await PermissionChecker.IsGrantedAsync(resourcePermissions + .Select(rp => rp.ManagementPermissionName!) + .Distinct().ToArray())).Result.Where(x => x.Value == PermissionGrantResult.Granted).Select(x => x.Key) + .ToHashSet(); + foreach (var resourcePermission in resourcePermissions) + { + if (!permissionGrants.Contains(resourcePermission.ManagementPermissionName)) + { + continue; + } + + result.Permissions.Add(new ResourcePermissionDefinitionDto + { + Name = resourcePermission.Name, + DisplayName = resourcePermission.DisplayName?.Localize(StringLocalizerFactory), + }); + } + + return result; + } + + public virtual async Task GetResourceAsync(string resourceName, string resourceKey) + { + var result = new GetResourcePermissionListResultDto + { + Permissions = new List() + }; + + var resourcePermissions = await ResourcePermissionManager.GetAvailablePermissionsAsync(resourceName); + var resourcePermissionGrants = await ResourcePermissionManager.GetAllGroupAsync(resourceName, resourceKey); + var permissionGrants = (await PermissionChecker.IsGrantedAsync(resourcePermissions + .Select(rp => rp.ManagementPermissionName!) + .Distinct().ToArray())).Result.Where(x => x.Value == PermissionGrantResult.Granted).Select(x => x.Key) + .ToHashSet(); + foreach (var resourcePermissionGrant in resourcePermissionGrants) + { + var resourcePermissionGrantInfoDto = new ResourcePermissionGrantInfoDto + { + ProviderName = resourcePermissionGrant.ProviderName, + ProviderKey = resourcePermissionGrant.ProviderKey, + ProviderDisplayName = resourcePermissionGrant.ProviderDisplayName, + ProviderNameDisplayName = resourcePermissionGrant.ProviderNameDisplayName?.Localize(StringLocalizerFactory), + Permissions = new List() + }; + foreach (var permission in resourcePermissionGrant.Permissions) + { + var resourcePermission = resourcePermissions.FirstOrDefault(x => x.Name == permission); + if (resourcePermission == null) + { + continue; + } + + if (!permissionGrants.Contains(resourcePermission.ManagementPermissionName)) + { + continue; + } + + resourcePermissionGrantInfoDto.Permissions.Add(new GrantedResourcePermissionDto() + { + Name = permission, + DisplayName = resourcePermission?.DisplayName.Localize(StringLocalizerFactory), + }); + } + + if(resourcePermissionGrantInfoDto.Permissions.Any()) + { + result.Permissions.Add(resourcePermissionGrantInfoDto); + } + } + + return result; + } + + public virtual async Task GetResourceByProviderAsync(string resourceName, string resourceKey, string providerName, string providerKey) + { + var result = new GetResourcePermissionWithProviderListResultDto + { + Permissions = new List() + }; + + var resourcePermissions = await ResourcePermissionManager.GetAvailablePermissionsAsync(resourceName); + var resourcePermissionGrants = await ResourcePermissionManager.GetAllAsync(resourceName, resourceKey, providerName, providerKey); + var permissionGrants = (await PermissionChecker.IsGrantedAsync(resourcePermissions + .Select(rp => rp.ManagementPermissionName!) + .Distinct().ToArray())).Result.Where(x => x.Value == PermissionGrantResult.Granted).Select(x => x.Key) + .ToHashSet(); + foreach (var resourcePermissionGrant in resourcePermissionGrants) + { + var resourcePermission = resourcePermissions.FirstOrDefault(x => x.Name == resourcePermissionGrant.Name); + if (resourcePermission == null) + { + continue; + } + + if (!permissionGrants.Contains(resourcePermission.ManagementPermissionName)) + { + continue; + } + + result.Permissions.Add(new ResourcePermissionWithProdiverGrantInfoDto + { + Name = resourcePermissionGrant.Name, + DisplayName = resourcePermission?.DisplayName.Localize(StringLocalizerFactory), + Providers = resourcePermissionGrant.Providers.Select(x => x.Name).ToList(), + IsGranted = resourcePermissionGrant.IsGranted + }); + } + + return result; + } + + public virtual async Task UpdateResourceAsync(string resourceName, string resourceKey, UpdateResourcePermissionsDto input) + { + var resourcePermissions = await ResourcePermissionManager.GetAvailablePermissionsAsync(resourceName); + var permissionGrants = (await PermissionChecker.IsGrantedAsync(resourcePermissions + .Select(rp => rp.ManagementPermissionName!) + .Distinct().ToArray())).Result.Where(x => x.Value == PermissionGrantResult.Granted).Select(x => x.Key) + .ToHashSet(); + foreach (var resourcePermission in resourcePermissions) + { + if (!permissionGrants.Contains(resourcePermission.ManagementPermissionName)) + { + continue; + } + + var isGranted = !input.Permissions.IsNullOrEmpty() && input.Permissions.Any(p => p == resourcePermission.Name); + await ResourcePermissionManager.SetAsync(resourcePermission.Name, resourceName, resourceKey, input.ProviderName, input.ProviderKey, isGranted); + } + } + + public virtual async Task DeleteResourceAsync(string resourceName, string resourceKey, string providerName, string providerKey) + { + var resourcePermissions = await ResourcePermissionManager.GetAvailablePermissionsAsync(resourceName); + var permissionGrants = (await PermissionChecker.IsGrantedAsync(resourcePermissions + .Select(rp => rp.ManagementPermissionName!) + .Distinct().ToArray())).Result.Where(x => x.Value == PermissionGrantResult.Granted).Select(x => x.Key) + .ToHashSet(); + foreach (var resourcePermission in resourcePermissions) + { + if (!permissionGrants.Contains(resourcePermission.ManagementPermissionName)) + { + continue; + } + + await ResourcePermissionManager.DeleteAsync(resourcePermission.Name, resourceName, resourceKey, providerName, providerKey); + } + } + protected virtual async Task CheckProviderPolicy(string providerName) { var policyName = Options.ProviderPolicies.GetOrDefault(providerName); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ar.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ar.json index 30f4b647e8..79dbec3a3e 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ar.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ar.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "تحديد الكل", "SaveWithoutAnyPermissionsWarningMessage": "هل أنت متأكد أنك تريد الحفظ بدون أي أذونات؟", "PermissionGroup": "مجموعة الأذونات", - "Filter": "تصفية" + "Filter": "تصفية", + "ResourcePermissions": "الأذونات", + "ResourcePermissionTarget": "الهدف", + "ResourcePermissionPermissions": "الأذونات", + "AddResourcePermission": "إضافة إذن", + "ResourcePermissionDeletionConfirmationMessage": "هل أنت متأكد أنك تريد حذف جميع الأذونات؟", + "AddResourcePermissions": "إضافة الأذونات", + "UpdateResourcePermissions": "تحديث الأذونات", + "GrantAllResourcePermissions": "منح الكل", + "NoResourceProviderKeyLookupServiceFound": "لم يتم العثور على خدمة البحث عن مفتاح المزود", + "NoResourcePermissionFound": "لا توجد أي أذونات محددة." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/cs.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/cs.json index 814b8e423c..eef2ab75fa 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/cs.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/cs.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Vybrat vše", "SaveWithoutAnyPermissionsWarningMessage": "Opravdu chcete ukládat bez jakýchkoli oprávnění?", "PermissionGroup": "Skupina oprávnění", - "Filter": "Filtr" + "Filter": "Filtr", + "ResourcePermissions": "Oprávnění", + "ResourcePermissionTarget": "Cíl", + "ResourcePermissionPermissions": "Oprávnění", + "AddResourcePermission": "Přidat oprávnění", + "ResourcePermissionDeletionConfirmationMessage": "Opravdu chcete smazat všechna oprávnění?", + "AddResourcePermissions": "Přidat oprávnění", + "UpdateResourcePermissions": "Aktualizovat oprávnění", + "GrantAllResourcePermissions": "Udělit vše", + "NoResourceProviderKeyLookupServiceFound": "Nebyla nalezena služba pro vyhledávání klíče poskytovatele zdrojů", + "NoResourcePermissionFound": "Pro aktuální prostředek není definováno žádné oprávnění." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/de.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/de.json index 7a40c5d4d4..d08b78e925 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/de.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/de.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Alle auswählen", "SaveWithoutAnyPermissionsWarningMessage": "Sind Sie sicher, dass Sie ohne Berechtigungen speichern möchten?", "PermissionGroup": "Berechtigungsgruppe", - "Filter": "Filtern" + "Filter": "Filtern", + "ResourcePermissions": "Berechtigungen", + "ResourcePermissionTarget": "Ziel", + "ResourcePermissionPermissions": "Berechtigungen", + "AddResourcePermission": "Berechtigung hinzufügen", + "ResourcePermissionDeletionConfirmationMessage": "Sind Sie sicher, dass Sie alle Berechtigungen löschen möchten?", + "AddResourcePermissions": "Berechtigungen hinzufügen", + "UpdateResourcePermissions": "Berechtigungen aktualisieren", + "GrantAllResourcePermissions": "Alle gewähren", + "NoResourceProviderKeyLookupServiceFound": "Es wurde kein Dienst zum Nachschlagen des Anbieterschlüssels gefunden", + "NoResourcePermissionFound": "Es ist keine Berechtigung definiert." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/el.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/el.json index 3449b7fab6..63eb0668c1 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/el.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/el.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Επιλογή όλων", "SaveWithoutAnyPermissionsWarningMessage": "Είστε βέβαιοι ότι θέλετε να αποθηκεύσετε χωρίς δικαιώματα;", "PermissionGroup": "Ομάδα δικαιωμάτων", - "Filter": "Φίλτρο" + "Filter": "Φίλτρο", + "ResourcePermissions": "Δικαιώματα", + "ResourcePermissionTarget": "Στόχος", + "ResourcePermissionPermissions": "Δικαιώματα", + "AddResourcePermission": "Προσθήκη δικαιώματος", + "ResourcePermissionDeletionConfirmationMessage": "Είστε βέβαιοι ότι θέλετε να διαγράψετε όλα τα δικαιώματα;", + "AddResourcePermissions": "Προσθήκη δικαιωμάτων", + "UpdateResourcePermissions": "Ενημέρωση δικαιωμάτων", + "GrantAllResourcePermissions": "Παραχώρηση όλων", + "NoResourceProviderKeyLookupServiceFound": "Δεν βρέθηκε υπηρεσία αναζήτησης κλειδιού παρόχου", + "NoResourcePermissionFound": "Δεν έχει οριστεί καμία άδεια." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en-GB.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en-GB.json index be6cbcd1f5..eebae2dc62 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en-GB.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en-GB.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Select all", "SaveWithoutAnyPermissionsWarningMessage": "Are you sure you want to save without any permissions?", "PermissionGroup": "Permission Group", - "Filter": "Filter" + "Filter": "Filter", + "ResourcePermissions": "Permissions", + "ResourcePermissionTarget": "Target", + "ResourcePermissionPermissions": "Permissions", + "AddResourcePermission": "Add permission", + "ResourcePermissionDeletionConfirmationMessage": "Are you sure you want to delete all permissions?", + "AddResourcePermissions": "Add permissions", + "UpdateResourcePermissions": "Update permissions", + "GrantAllResourcePermissions": "Grant all", + "NoResourceProviderKeyLookupServiceFound": "There is no provider key lookup service was found", + "NoResourcePermissionFound": "There is no permission defined." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en.json index b8299d4e5b..b1ea4b37fd 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Select all", "SaveWithoutAnyPermissionsWarningMessage": "Are you sure you want to save without any permissions?", "PermissionGroup": "Permission Group", - "Filter": "Filter" + "Filter": "Filter", + "ResourcePermissions": "Permissions", + "ResourcePermissionTarget": "Target", + "ResourcePermissionPermissions": "Permissions", + "AddResourcePermission": "Add permission", + "ResourcePermissionDeletionConfirmationMessage": "Are you sure you want to delete all permissions?", + "AddResourcePermissions": "Add permissions", + "UpdateResourcePermissions": "Update permissions", + "GrantAllResourcePermissions": "Grant all", + "NoResourceProviderKeyLookupServiceFound": "There is no provider key lookup service was found", + "NoResourcePermissionFound": "There is no permission defined." } -} \ No newline at end of file +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/es.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/es.json index 622883b259..f62d7fdba0 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/es.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/es.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Seleccionar todo", "SaveWithoutAnyPermissionsWarningMessage": "¿Estás seguro de que quieres guardar sin ningún permiso?", "PermissionGroup": "Grupo de permisos", - "Filter": "Filtrar" + "Filter": "Filtrar", + "ResourcePermissions": "Permisos", + "ResourcePermissionTarget": "Objetivo", + "ResourcePermissionPermissions": "Permisos", + "AddResourcePermission": "Agregar permiso", + "ResourcePermissionDeletionConfirmationMessage": "¿Está seguro de que desea eliminar todos los permisos?", + "AddResourcePermissions": "Agregar permisos", + "UpdateResourcePermissions": "Actualizar permisos", + "GrantAllResourcePermissions": "Conceder todos", + "NoResourceProviderKeyLookupServiceFound": "No se encontró ningún servicio de búsqueda de clave de proveedor", + "NoResourcePermissionFound": "No hay ningún permiso definido." } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fa.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fa.json index 7ea9a6c4f3..d025e2403d 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fa.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fa.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "انتخاب همه", "SaveWithoutAnyPermissionsWarningMessage": "آیا مطمئن هستید که می خواهید بدون هیچ دسترسی ذخیره کنید؟", "PermissionGroup": "گروه دسترسی", - "Filter": "فیلتر" + "Filter": "فیلتر", + "ResourcePermissions": "دسترسی‌ها", + "ResourcePermissionTarget": "هدف", + "ResourcePermissionPermissions": "دسترسی‌ها", + "AddResourcePermission": "افزودن مجوز", + "ResourcePermissionDeletionConfirmationMessage": "آیا مطمئن هستید که می‌خواهید همه مجوزها را حذف کنید؟", + "AddResourcePermissions": "افزودن مجوزها", + "UpdateResourcePermissions": "به‌روزرسانی مجوزها", + "GrantAllResourcePermissions": "اعطای همه", + "NoResourceProviderKeyLookupServiceFound": "هیچ سرویس جستجوی کلید ارائه‌دهنده یافت نشد", + "NoResourcePermissionFound": "هیچ مجوزی تعریف نشده است." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fi.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fi.json index f9b828ade4..60c6f682d4 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fi.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fi.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Valitse kaikki", "SaveWithoutAnyPermissionsWarningMessage": "Haluatko varmasti tallentaa ilman käyttöoikeuksia?", "PermissionGroup": "Käyttöoikeus", - "Filter": "Suodatus" + "Filter": "Suodatus", + "ResourcePermissions": "Käyttöoikeudet", + "ResourcePermissionTarget": "Kohde", + "ResourcePermissionPermissions": "Käyttöoikeudet", + "AddResourcePermission": "Lisää käyttöoikeus", + "ResourcePermissionDeletionConfirmationMessage": "Haluatko varmasti poistaa kaikki käyttöoikeudet?", + "AddResourcePermissions": "Lisää käyttöoikeudet", + "UpdateResourcePermissions": "Päivitä käyttöoikeudet", + "GrantAllResourcePermissions": "Myönnä kaikki", + "NoResourceProviderKeyLookupServiceFound": "Palveluntarjoajan avaimen hakupalvelua ei löytynyt", + "NoResourcePermissionFound": "Ei käyttöoikeuksia määritetty." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fr.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fr.json index 79f4e68377..30bf227119 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fr.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/fr.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Sélectionner tous les", "SaveWithoutAnyPermissionsWarningMessage": "Êtes-vous sûr de vouloir enregistrer sans aucune autorisation ?", "PermissionGroup": "Groupe d'autorisations", - "Filter": "Filtrer" + "Filter": "Filtrer", + "ResourcePermissions": "Autorisations", + "ResourcePermissionTarget": "Cible", + "ResourcePermissionPermissions": "Autorisations", + "AddResourcePermission": "Ajouter une autorisation", + "ResourcePermissionDeletionConfirmationMessage": "Êtes-vous sûr de vouloir supprimer toutes les autorisations ?", + "AddResourcePermissions": "Ajouter des autorisations", + "UpdateResourcePermissions": "Mettre à jour les autorisations", + "GrantAllResourcePermissions": "Accorder tout", + "NoResourceProviderKeyLookupServiceFound": "Aucun service de recherche de clé de fournisseur n'a été trouvé", + "NoResourcePermissionFound": "Aucune autorisation n'est définie." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hi.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hi.json index cdc030e8ef..4523cce321 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hi.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hi.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "सभी का चयन करे", "SaveWithoutAnyPermissionsWarningMessage": "क्या आप वाकई बिना किसी अनुमति के सहेजना चाहते हैं?", "PermissionGroup": "अनुमति समूह", - "Filter": "फ़िल्टर" + "Filter": "फ़िल्टर", + "ResourcePermissions": "अनुमतियाँ", + "ResourcePermissionTarget": "लक्ष्य", + "ResourcePermissionPermissions": "अनुमतियाँ", + "AddResourcePermission": "अनुमति जोड़ें", + "ResourcePermissionDeletionConfirmationMessage": "क्या आप वाकई सभी अनुमतियां हटाना चाहते हैं?", + "AddResourcePermissions": "अनुमतियां जोड़ें", + "UpdateResourcePermissions": "अनुमतियां अपडेट करें", + "GrantAllResourcePermissions": "सभी प्रदान करें", + "NoResourceProviderKeyLookupServiceFound": "कोई प्रदाता कुंजी खोज सेवा नहीं मिली", + "NoResourcePermissionFound": "कोई अनुमति परिभाषित नहीं है।" } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hr.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hr.json index 531d0a35d2..ff1f097592 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hr.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hr.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Odaberi sve", "SaveWithoutAnyPermissionsWarningMessage": "Jeste li sigurni da želite spremiti bez ikakvih dopuštenja?", "PermissionGroup": "Grupa dozvola", - "Filter": "Filtriraj" + "Filter": "Filtriraj", + "ResourcePermissions": "Dozvole", + "ResourcePermissionTarget": "Cilj", + "ResourcePermissionPermissions": "Dozvole", + "AddResourcePermission": "Dodaj dozvolu", + "ResourcePermissionDeletionConfirmationMessage": "Jeste li sigurni da želite izbrisati sve dozvole?", + "AddResourcePermissions": "Dodaj dozvole", + "UpdateResourcePermissions": "Ažuriraj dozvole", + "GrantAllResourcePermissions": "Dodijeli sve", + "NoResourceProviderKeyLookupServiceFound": "Nije pronađena usluga za pronalaženje ključa pružatelja", + "NoResourcePermissionFound": "Nijedna dozvola nije definirana." } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hu.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hu.json index 3177ef8fa7..48ef87202d 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hu.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hu.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Mindet kiválaszt", "SaveWithoutAnyPermissionsWarningMessage": "Biztos, hogy engedélyek nélkül akar menteni?", "PermissionGroup": "Engedélycsoport", - "Filter": "Szűrő" + "Filter": "Szűrő", + "ResourcePermissions": "Engedélyek", + "ResourcePermissionTarget": "Cél", + "ResourcePermissionPermissions": "Engedélyek", + "AddResourcePermission": "Engedély hozzáadása", + "ResourcePermissionDeletionConfirmationMessage": "Biztosan törölni szeretné az összes engedélyt?", + "AddResourcePermissions": "Engedélyek hozzáadása", + "UpdateResourcePermissions": "Engedélyek frissítése", + "GrantAllResourcePermissions": "Összes engedély megadása", + "NoResourceProviderKeyLookupServiceFound": "Nem található szolgáltató kulcs kereső szolgáltatás", + "NoResourcePermissionFound": "Nincs meghatározva engedély." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/is.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/is.json index 7db32eb99e..fd4b43fde5 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/is.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/is.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Velja allt", "SaveWithoutAnyPermissionsWarningMessage": "Ertu viss um að þú viljir vista án nokkurra heimilda?", "PermissionGroup": "Heimildahópur", - "Filter": "Sía" + "Filter": "Sía", + "ResourcePermissions": "Heimildir", + "ResourcePermissionTarget": "Markmið", + "ResourcePermissionPermissions": "Heimildir", + "AddResourcePermission": "Bæta við heimild", + "ResourcePermissionDeletionConfirmationMessage": "Ertu viss um að þú viljir eyða öllum heimildum?", + "AddResourcePermissions": "Bæta við heimildum", + "UpdateResourcePermissions": "Uppfæra heimildir", + "GrantAllResourcePermissions": "Veita allt", + "NoResourceProviderKeyLookupServiceFound": "Engin þjónusta fannst til að leita að lykli veitanda", + "NoResourcePermissionFound": "Engin heimild er skilgreind." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/it.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/it.json index e473c7b310..39893a8dbc 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/it.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/it.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Seleziona tutto", "SaveWithoutAnyPermissionsWarningMessage": "Sei sicuro di voler salvare senza alcuna autorizzazione?", "PermissionGroup": "Gruppo di autorizzazioni", - "Filter": "Filtro" + "Filter": "Filtro", + "ResourcePermissions": "Autorizzazioni", + "ResourcePermissionTarget": "Obiettivo", + "ResourcePermissionPermissions": "Autorizzazioni", + "AddResourcePermission": "Aggiungi autorizzazione", + "ResourcePermissionDeletionConfirmationMessage": "Sei sicuro di voler eliminare tutte le autorizzazioni?", + "AddResourcePermissions": "Aggiungi autorizzazioni", + "UpdateResourcePermissions": "Aggiorna autorizzazioni", + "GrantAllResourcePermissions": "Concedi tutto", + "NoResourceProviderKeyLookupServiceFound": "Non è stato trovato alcun servizio di ricerca chiave del provider", + "NoResourcePermissionFound": "Non è definita alcuna autorizzazione." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/nl.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/nl.json index 4b928c4d03..c3eeb2bc60 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/nl.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/nl.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Selecteer alles", "SaveWithoutAnyPermissionsWarningMessage": "Weet u zeker dat u zonder rechten wilt opslaan?", "PermissionGroup": "Rechtengroep", - "Filter": "Filter" + "Filter": "Filter", + "ResourcePermissions": "Rechten", + "ResourcePermissionTarget": "Doel", + "ResourcePermissionPermissions": "Rechten", + "AddResourcePermission": "Recht toevoegen", + "ResourcePermissionDeletionConfirmationMessage": "Weet u zeker dat u alle rechten wilt verwijderen?", + "AddResourcePermissions": "Rechten toevoegen", + "UpdateResourcePermissions": "Rechten bijwerken", + "GrantAllResourcePermissions": "Alles toekennen", + "NoResourceProviderKeyLookupServiceFound": "Er is geen service gevonden voor het opzoeken van de sleutel van de provider", + "NoResourcePermissionFound": "Er is geen machtiging gedefinieerd." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/pl-PL.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/pl-PL.json index ee483651eb..de16903dd0 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/pl-PL.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/pl-PL.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Zaznacz wszystkie", "SaveWithoutAnyPermissionsWarningMessage": "Czy na pewno chcesz zapisać bez żadnych uprawnień?", "PermissionGroup": "Grupa uprawnień", - "Filter": "Filtr" + "Filter": "Filtr", + "ResourcePermissions": "Uprawnienia", + "ResourcePermissionTarget": "Cel", + "ResourcePermissionPermissions": "Uprawnienia", + "AddResourcePermission": "Dodaj uprawnienie", + "ResourcePermissionDeletionConfirmationMessage": "Czy na pewno chcesz usunąć wszystkie uprawnienia?", + "AddResourcePermissions": "Dodaj uprawnienia", + "UpdateResourcePermissions": "Zaktualizuj uprawnienia", + "GrantAllResourcePermissions": "Przyznaj wszystko", + "NoResourceProviderKeyLookupServiceFound": "Nie znaleziono usługi wyszukiwania klucza dostawcy", + "NoResourcePermissionFound": "Nie zdefiniowano żadnych uprawnień." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/pt-BR.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/pt-BR.json index 28231b227f..fbb2351f54 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/pt-BR.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/pt-BR.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Selecionar todos", "SaveWithoutAnyPermissionsWarningMessage": "Tem certeza que deseja salvar sem nenhuma permissão?", "PermissionGroup": "Grupo de permissão", - "Filter": "Filtrar" + "Filter": "Filtrar", + "ResourcePermissions": "Permissões", + "ResourcePermissionTarget": "Alvo", + "ResourcePermissionPermissions": "Permissões", + "AddResourcePermission": "Adicionar permissão", + "ResourcePermissionDeletionConfirmationMessage": "Tem certeza de que deseja excluir todas as permissões?", + "AddResourcePermissions": "Adicionar permissões", + "UpdateResourcePermissions": "Atualizar permissões", + "GrantAllResourcePermissions": "Conceder tudo", + "NoResourceProviderKeyLookupServiceFound": "Nenhum serviço de pesquisa de chave do provedor foi encontrado", + "NoResourcePermissionFound": "Nenhuma permissão foi definida." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ro-RO.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ro-RO.json index af7db26acb..87a764d599 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ro-RO.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ro-RO.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Selectează toate", "SaveWithoutAnyPermissionsWarningMessage": "Sigur doriți să salvați fără nicio permisiune?", "PermissionGroup": "Grup de permisiuni", - "Filter": "Filtru" + "Filter": "Filtru", + "ResourcePermissions": "Permisiuni", + "ResourcePermissionTarget": "Țintă", + "ResourcePermissionPermissions": "Permisiuni", + "AddResourcePermission": "Adăugați permisiune", + "ResourcePermissionDeletionConfirmationMessage": "Sigur doriți să ștergeți toate permisiunile?", + "AddResourcePermissions": "Adăugați permisiuni", + "UpdateResourcePermissions": "Actualizați permisiunile", + "GrantAllResourcePermissions": "Acordați toate", + "NoResourceProviderKeyLookupServiceFound": "Nu a fost găsit niciun serviciu de căutare a cheii furnizorului", + "NoResourcePermissionFound": "Nu există nicio permisiune definită." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json index 6041357b0e..dcbfeaaf08 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Выбрать все", "SaveWithoutAnyPermissionsWarningMessage": "Вы уверены, что хотите сохранить без каких-либо разрешений?", "PermissionGroup": "Группа разрешений", - "Filter": "Фильтр" + "Filter": "Фильтр", + "ResourcePermissions": "Разрешения", + "ResourcePermissionTarget": "Цель", + "ResourcePermissionPermissions": "Разрешения", + "AddResourcePermission": "Добавить разрешение", + "ResourcePermissionDeletionConfirmationMessage": "Вы уверены, что хотите удалить все разрешения?", + "AddResourcePermissions": "Добавить разрешения", + "UpdateResourcePermissions": "Обновить разрешения", + "GrantAllResourcePermissions": "Предоставить все", + "NoResourceProviderKeyLookupServiceFound": "Служба поиска ключа поставщика не найдена", + "NoResourcePermissionFound": "Не определено ни одного разрешения." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sk.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sk.json index c079b8eba1..fb4425f148 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sk.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sk.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Vybrať všetky", "SaveWithoutAnyPermissionsWarningMessage": "Naozaj chcete ukladať bez akýchkoľvek povolení?", "PermissionGroup": "Skupina oprávnení", - "Filter": "Filtrovať" + "Filter": "Filtrovať", + "ResourcePermissions": "Oprávnenia", + "ResourcePermissionTarget": "Cieľ", + "ResourcePermissionPermissions": "Oprávnenia", + "AddResourcePermission": "Pridať oprávnenie", + "ResourcePermissionDeletionConfirmationMessage": "Naozaj chcete odstrániť všetky oprávnenia?", + "AddResourcePermissions": "Pridať oprávnenia", + "UpdateResourcePermissions": "Aktualizovať oprávnenia", + "GrantAllResourcePermissions": "Udeľ všetko", + "NoResourceProviderKeyLookupServiceFound": "Nebola nájdená služba na vyhľadávanie kľúča poskytovateľa", + "NoResourcePermissionFound": "Nie je definované žiadne povolenie." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sl.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sl.json index 9c906f7387..ca919b069b 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sl.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sl.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Izberi vse", "SaveWithoutAnyPermissionsWarningMessage": "Ali ste prepričani, da želite shraniti brez kakršnih koli dovoljenj?", "PermissionGroup": "Skupina dovoljenj", - "Filter": "Filtriraj" + "Filter": "Filtriraj", + "ResourcePermissions": "Dovoljenja", + "ResourcePermissionTarget": "Cilj", + "ResourcePermissionPermissions": "Dovoljenja", + "AddResourcePermission": "Dodaj dovoljenje", + "ResourcePermissionDeletionConfirmationMessage": "Ali ste prepričani, da želite izbrisati vsa dovoljenja?", + "AddResourcePermissions": "Dodaj dovoljenja", + "UpdateResourcePermissions": "Posodobi dovoljenja", + "GrantAllResourcePermissions": "Dodeli vse", + "NoResourceProviderKeyLookupServiceFound": "Ni bilo mogoče najti storitve za iskanje ključa ponudnika", + "NoResourcePermissionFound": "Nobeno dovoljenje ni določeno." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sv.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sv.json index d46fca4dc4..4896e51547 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sv.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/sv.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Välj alla", "SaveWithoutAnyPermissionsWarningMessage": "Är du säker på att du vill spara utan några behörigheter?", "PermissionGroup": "Behörighetsgrupp", - "Filter": "Filtrera" + "Filter": "Filtrera", + "ResourcePermissions": "Behörigheter", + "ResourcePermissionTarget": "Mål", + "ResourcePermissionPermissions": "Behörigheter", + "AddResourcePermission": "Lägg till behörighet", + "ResourcePermissionDeletionConfirmationMessage": "Är du säker på att du vill ta bort alla behörigheter?", + "AddResourcePermissions": "Lägg till behörigheter", + "UpdateResourcePermissions": "Uppdatera behörigheter", + "GrantAllResourcePermissions": "Bevilja alla", + "NoResourceProviderKeyLookupServiceFound": "Ingen tjänst för att söka efter leverantörsnyckel hittades", + "NoResourcePermissionFound": "Ingen behörighet är definierad." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/tr.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/tr.json index 960cd8cf02..e1925fe8da 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/tr.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/tr.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Hepsini seç", "SaveWithoutAnyPermissionsWarningMessage": "Hiçbir izin olmadan kaydetmek istediğinize emin misiniz?", "PermissionGroup": "İzin Grubu", - "Filter": "Filtre" + "Filter": "Filtre", + "ResourcePermissions": "İzinler", + "ResourcePermissionTarget": "Hedef", + "ResourcePermissionPermissions": "İzinler", + "AddResourcePermission": "İzin ekle", + "ResourcePermissionDeletionConfirmationMessage": "Tüm izinleri silmek istediğinizden emin misiniz?", + "AddResourcePermissions": "İzinler ekle", + "UpdateResourcePermissions": "İzinleri güncelle", + "GrantAllResourcePermissions": "Tümünü ver", + "NoResourceProviderKeyLookupServiceFound": "Herhangi bir sağlayıcı anahtar arama hizmeti bulunamadı", + "NoResourcePermissionFound": "Herhangi bir izin tanımlı değil." } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/vi.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/vi.json index 5e9a9d8565..7359377b59 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/vi.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/vi.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "Chọn tất cả", "SaveWithoutAnyPermissionsWarningMessage": "Bạn có chắc chắn muốn lưu mà không có bất kỳ quyền nào không?", "PermissionGroup": "Nhóm quyền", - "Filter": "Lọc" + "Filter": "Lọc", + "ResourcePermissions": "Quyền", + "ResourcePermissionTarget": "Mục tiêu", + "ResourcePermissionPermissions": "Quyền", + "AddResourcePermission": "Thêm quyền", + "ResourcePermissionDeletionConfirmationMessage": "Bạn có chắc chắn muốn xóa tất cả quyền không?", + "AddResourcePermissions": "Thêm các quyền", + "UpdateResourcePermissions": "Cập nhật các quyền", + "GrantAllResourcePermissions": "Cấp tất cả", + "NoResourceProviderKeyLookupServiceFound": "Không tìm thấy dịch vụ tra cứu khóa nhà cung cấp", + "NoResourcePermissionFound": "Không có quyền nào được định nghĩa." } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hans.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hans.json index df844ca2bf..548d8ac2ad 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hans.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hans.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "全选", "SaveWithoutAnyPermissionsWarningMessage": "您确定要在没有任何权限的情况下保存吗?", "PermissionGroup": "权限组", - "Filter": "过滤" + "Filter": "过滤", + "ResourcePermissions": "权限", + "ResourcePermissionTarget": "目标", + "ResourcePermissionPermissions": "权限", + "AddResourcePermission": "添加权限", + "ResourcePermissionDeletionConfirmationMessage": "您确定要删除所有权限吗?", + "AddResourcePermissions": "添加权限", + "UpdateResourcePermissions": "更新权限", + "GrantAllResourcePermissions": "授予所有", + "NoResourceProviderKeyLookupServiceFound": "未找到提供者键查找服务", + "NoResourcePermissionFound": "未定义任何权限。" } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hant.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hant.json index 72af56c960..2e114480fb 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hant.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hant.json @@ -8,6 +8,16 @@ "SelectAllInThisTab": "全選", "SaveWithoutAnyPermissionsWarningMessage": "您確定要在沒有任何權限的情況下保存嗎?", "PermissionGroup": "權限組", - "Filter": "過濾" + "Filter": "過濾", + "ResourcePermissions": "權限", + "ResourcePermissionTarget": "目標", + "ResourcePermissionPermissions": "權限", + "AddResourcePermission": "添加權限", + "ResourcePermissionDeletionConfirmationMessage": "您確定要刪除所有權限嗎?", + "AddResourcePermissions": "添加權限", + "UpdateResourcePermissions": "更新權限", + "GrantAllResourcePermissions": "授予所有", + "NoResourceProviderKeyLookupServiceFound": "未找到提供者鍵查找服務", + "NoResourcePermissionFound": "未定義任何權限。" } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionDefinitionRecordConsts.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionDefinitionRecordConsts.cs index 93b1b465c6..0aadef7940 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionDefinitionRecordConsts.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionDefinitionRecordConsts.cs @@ -6,10 +6,14 @@ public class PermissionDefinitionRecordConsts /// Default value: 128 /// public static int MaxNameLength { get; set; } = 128; - + public static int MaxDisplayNameLength { get; set; } = 256; public static int MaxProvidersLength { get; set; } = 128; - + public static int MaxStateCheckersLength { get; set; } = 256; -} \ No newline at end of file + + public static int MaxResourceNameLength { get; set; } = 256; + + public static int MaxManagementPermissionNameLength { get; set; } = 128; +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs index 630f5dc72e..d1008bcbdb 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs @@ -11,4 +11,14 @@ public static class PermissionGrantConsts /// Default value: 64 /// public static int MaxProviderKeyLength { get; set; } = 64; + + /// + /// Default value: 256 + /// + public static int MaxResourceNameLength { get; set; } = 256; + + /// + /// Default value: 256 + /// + public static int MaxResourceKeyLength { get; set; } = 256; } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStore.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStore.cs index f2e73cefc0..ff525ab263 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStore.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/DynamicPermissionDefinitionStore.cs @@ -23,7 +23,7 @@ public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStor protected IAbpDistributedLock DistributedLock { get; } public PermissionManagementOptions PermissionManagementOptions { get; } protected AbpDistributedCacheOptions CacheOptions { get; } - + public DynamicPermissionDefinitionStore( IPermissionGroupDefinitionRecordRepository permissionGroupRepository, IPermissionDefinitionRecordRepository permissionRepository, @@ -72,6 +72,34 @@ public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStor } } + public virtual async Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + if (!PermissionManagementOptions.IsDynamicPermissionStoreEnabled) + { + return null; + } + + using (await StoreCache.SyncSemaphore.LockAsync()) + { + await EnsureCacheIsUptoDateAsync(); + return StoreCache.GetResourcePermissionOrNull(resourceName, name); + } + } + + public virtual async Task> GetResourcePermissionsAsync() + { + if (!PermissionManagementOptions.IsDynamicPermissionStoreEnabled) + { + return Array.Empty(); + } + + using (await StoreCache.SyncSemaphore.LockAsync()) + { + await EnsureCacheIsUptoDateAsync(); + return StoreCache.GetResourcePermissions().ToImmutableList(); + } + } + public virtual async Task> GetGroupsAsync() { if (!PermissionManagementOptions.IsDynamicPermissionStoreEnabled) @@ -94,9 +122,9 @@ public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStor /* We get the latest permission with a small delay for optimization */ return; } - + var stampInDistributedCache = await GetOrSetStampInDistributedCache(); - + if (stampInDistributedCache == StoreCache.CacheStamp) { StoreCache.LastCheckTime = DateTime.Now; @@ -145,7 +173,7 @@ public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStor } stampInDistributedCache = Guid.NewGuid().ToString(); - + await DistributedCache.SetStringAsync( cacheKey, stampInDistributedCache, @@ -163,9 +191,9 @@ public class DynamicPermissionDefinitionStore : IDynamicPermissionDefinitionStor { return $"{CacheOptions.KeyPrefix}_AbpInMemoryPermissionCacheStamp"; } - + protected virtual string GetCommonDistributedLockKey() { return $"{CacheOptions.KeyPrefix}_Common_AbpPermissionUpdateLock"; } -} \ No newline at end of file +} 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 1040ea84a0..15a98c84dd 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 @@ -18,6 +18,7 @@ public class DynamicPermissionDefinitionStoreInMemoryCache : protected IDictionary PermissionGroupDefinitions { get; } protected IDictionary PermissionDefinitions { get; } + protected IList ResourcePermissionDefinitions { get; } protected ISimpleStateCheckerSerializer StateCheckerSerializer { get; } protected ILocalizableStringSerializer LocalizableStringSerializer { get; } @@ -34,6 +35,7 @@ public class DynamicPermissionDefinitionStoreInMemoryCache : PermissionGroupDefinitions = new Dictionary(); PermissionDefinitions = new Dictionary(); + ResourcePermissionDefinitions = new List(); } public Task FillAsync( @@ -42,9 +44,22 @@ public class DynamicPermissionDefinitionStoreInMemoryCache : { PermissionGroupDefinitions.Clear(); PermissionDefinitions.Clear(); + ResourcePermissionDefinitions.Clear(); var context = new PermissionDefinitionContext(null); + var resourcePermissions = permissionRecords.Where(x => !x.ResourceName.IsNullOrWhiteSpace()); + foreach (var resourcePermission in resourcePermissions) + { + context.AddResourcePermission(resourcePermission.Name, + resourcePermission.ResourceName, + resourcePermission.ManagementPermissionName, + resourcePermission.DisplayName != null ? LocalizableStringSerializer.Deserialize(resourcePermission.DisplayName) : null, + resourcePermission.MultiTenancySide, + resourcePermission.IsEnabled); + } + + var permissions = permissionRecords.Where(x => x.ResourceName.IsNullOrWhiteSpace()).ToList(); foreach (var permissionGroupRecord in permissionGroupRecords) { var permissionGroup = context.AddGroup( @@ -59,12 +74,12 @@ public class DynamicPermissionDefinitionStoreInMemoryCache : permissionGroup[property.Key] = property.Value; } - var permissionRecordsInThisGroup = permissionRecords + var permissionRecordsInThisGroup = permissions .Where(p => p.GroupName == permissionGroup.Name); foreach (var permissionRecord in permissionRecordsInThisGroup.Where(x => x.ParentName == null)) { - AddPermissionRecursively(permissionGroup, permissionRecord, permissionRecords); + AddPermissionRecursively(permissionGroup, permissionRecord, permissions); } } @@ -86,6 +101,16 @@ public class DynamicPermissionDefinitionStoreInMemoryCache : return PermissionGroupDefinitions.Values.ToList(); } + public PermissionDefinition GetResourcePermissionOrNull(string resourceName, string name) + { + return ResourcePermissionDefinitions.FirstOrDefault(p => p.ResourceName == resourceName && p.Name == name); + } + + public IReadOnlyList GetResourcePermissions() + { + return ResourcePermissionDefinitions.ToList(); + } + private void AddPermissionRecursively(ICanAddChildPermission permissionContainer, PermissionDefinitionRecord permissionRecord, List allPermissionRecords) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IDynamicPermissionDefinitionStoreInMemoryCache.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IDynamicPermissionDefinitionStoreInMemoryCache.cs index 2dab588ebd..eb079f6c76 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IDynamicPermissionDefinitionStoreInMemoryCache.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IDynamicPermissionDefinitionStoreInMemoryCache.cs @@ -9,9 +9,9 @@ namespace Volo.Abp.PermissionManagement; public interface IDynamicPermissionDefinitionStoreInMemoryCache { string CacheStamp { get; set; } - + SemaphoreSlim SyncSemaphore { get; } - + DateTime? LastCheckTime { get; set; } Task FillAsync( @@ -19,8 +19,12 @@ public interface IDynamicPermissionDefinitionStoreInMemoryCache List permissionRecords); PermissionDefinition GetPermissionOrNull(string name); - + IReadOnlyList GetPermissions(); - + IReadOnlyList GetGroups(); -} \ No newline at end of file + + PermissionDefinition GetResourcePermissionOrNull(string resourceName, string name); + + IReadOnlyList GetResourcePermissions(); +} 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/IPermissionManager.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionManager.cs index 7ec69ad100..ffb934321b 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionManager.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionManager.cs @@ -4,19 +4,39 @@ using JetBrains.Annotations; namespace Volo.Abp.PermissionManagement; -//TODO: Write extension methods for simple IsGranted check - public interface IPermissionManager { - Task GetAsync(string permissionName, string providerName, string providerKey); - - Task GetAsync(string[] permissionNames, string provideName, string providerKey); - - Task> GetAllAsync([NotNull] string providerName, [NotNull] string providerKey); - - Task SetAsync(string permissionName, string providerName, string providerKey, bool isGranted); - - Task UpdateProviderKeyAsync(PermissionGrant permissionGrant, string providerKey); - - Task DeleteAsync(string providerName, string providerKey); -} + Task GetAsync( + string permissionName, + string providerName, + string providerKey + ); + + Task GetAsync( + string[] permissionNames, + string provideName, + string providerKey + ); + + Task> GetAllAsync( + [NotNull] string providerName, + [NotNull] string providerKey + ); + + Task SetAsync( + string permissionName, + string providerName, + string providerKey, + bool isGranted + ); + + Task UpdateProviderKeyAsync( + PermissionGrant permissionGrant, + string providerKey + ); + + Task DeleteAsync( + string providerName, + string providerKey + ); +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionGrantRepository.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionGrantRepository.cs new file mode 100644 index 0000000000..82060c7ea7 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionGrantRepository.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.PermissionManagement; + +public interface IResourcePermissionGrantRepository : IBasicRepository +{ + Task FindAsync( + string name, + string resourceName, + string resourceKey, + string providerName, + string providerKey, + CancellationToken cancellationToken = default + ); + + Task> GetListAsync( + string resourceName, + string resourceKey, + string providerName, + string providerKey, + CancellationToken cancellationToken = default + ); + + Task> GetListAsync( + string[] names, + string resourceName, + string resourceKey, + string providerName, + string providerKey, + CancellationToken cancellationToken = default + ); + + Task> GetListAsync( + string providerName, + string providerKey, + CancellationToken cancellationToken = default + ); + + Task> GetPermissionsAsync( + string resourceName, + string resourceKey, + CancellationToken cancellationToken = default + ); + + Task> GetResourceKeys( + string resourceName, + string name, + CancellationToken cancellationToken = default + ); +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionManagementProvider.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionManagementProvider.cs new file mode 100644 index 0000000000..429e6f6e85 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionManagementProvider.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.PermissionManagement; + +public interface IResourcePermissionManagementProvider : ISingletonDependency //TODO: Consider to remove this pre-assumption +{ + string Name { get; } + + Task CheckAsync( + [NotNull] string name, + [NotNull] string resourceName, + [NotNull] string resourceKey, + [NotNull] string providerName, + [NotNull] string providerKey + ); + + Task CheckAsync( + [NotNull] string[] names, + [NotNull] string resourceName, + [NotNull] string resourceKey, + [NotNull] string providerName, + [NotNull] string providerKey + ); + + Task SetAsync( + [NotNull] string name, + [NotNull] string resourceName, + [NotNull] string resourceKey, + [NotNull] string providerKey, + bool isGranted + ); +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionManager.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionManager.cs new file mode 100644 index 0000000000..5bd2d143ca --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionManager.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; + +namespace Volo.Abp.PermissionManagement; + +public interface IResourcePermissionManager +{ + Task> GetProviderKeyLookupServicesAsync(); + + Task GetProviderKeyLookupServiceAsync(string providerName); + + Task> GetAvailablePermissionsAsync(string resourceName); + + Task GetAsync( + string permissionName, + string resourceName, + string resourceKey, + string providerName, + string providerKey + ); + + Task GetAsync( + string[] permissionNames, + string resourceName, + string resourceKey, + string providerName, + string providerKey + ); + + Task> GetAllAsync( + string resourceName, + string resourceKey + ); + + Task> GetAllAsync( + string resourceName, + string resourceKey, + string providerName, + string providerKey + ); + + Task> GetAllGroupAsync( + string resourceName, + string resourceKey + ); + + Task SetAsync( + string permissionName, + string resourceName, + string resourceKey, + string providerName, + string providerKey, + bool isGranted + ); + + Task UpdateProviderKeyAsync( + ResourcePermissionGrant resourcePermissionGrant, + string providerKey + ); + + Task DeleteAsync( + string resourceName, + string resourceKey, + string providerName, + string providerKey + ); + + Task DeleteAsync( + string name, + string resourceName, + string resourceKey, + string providerName, + string providerKey + ); + + Task DeleteAsync( + string providerName, + string providerKey + ); +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionProviderKeyLookupService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionProviderKeyLookupService.cs new file mode 100644 index 0000000000..aa6ad2a06e --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionProviderKeyLookupService.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Localization; + +namespace Volo.Abp.PermissionManagement; + +public interface IResourcePermissionProviderKeyLookupService +{ + public string Name { get; } + + public ILocalizableString DisplayName { get; } + + Task> SearchAsync(string filter = null, int page = 1, CancellationToken cancellationToken = default); + + Task> SearchAsync(string[] keys, CancellationToken cancellationToken = default); +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/MultipleResourcePermissionValueProviderGrantInfo.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/MultipleResourcePermissionValueProviderGrantInfo.cs new file mode 100644 index 0000000000..4ff1790488 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/MultipleResourcePermissionValueProviderGrantInfo.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement; + +public class MultipleResourcePermissionValueProviderGrantInfo +{ + public Dictionary Result { get; } + + public MultipleResourcePermissionValueProviderGrantInfo() + { + Result = new Dictionary(); + } + + public MultipleResourcePermissionValueProviderGrantInfo(string[] names) + { + Check.NotNull(names, nameof(names)); + + Result = new Dictionary(); + + foreach (var name in names) + { + Result.Add(name, ResourcePermissionValueProviderGrantInfo.NonGranted); + } + } +} 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 7473eb2589..61a6ba1f14 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 @@ -1,4 +1,5 @@ using System; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Data; using Volo.Abp.Domain.Entities; using Volo.Abp.MultiTenancy; @@ -11,6 +12,10 @@ public class PermissionDefinitionRecord : BasicAggregateRoot, IHasExtraPro public string Name { get; set; } + public string ResourceName { get; set; } + + public string ManagementPermissionName { get; set; } + public string ParentName { get; set; } public string DisplayName { get; set; } @@ -41,6 +46,8 @@ public class PermissionDefinitionRecord : BasicAggregateRoot, IHasExtraPro Guid id, string groupName, string name, + string resourceName, + string managementPermissionName, string parentName, string displayName, bool isEnabled = true, @@ -49,8 +56,14 @@ 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; + ManagementPermissionName = managementPermissionName; ParentName = Check.Length(parentName, nameof(parentName), PermissionDefinitionRecordConsts.MaxNameLength); DisplayName = Check.NotNullOrWhiteSpace(displayName, nameof(displayName), PermissionDefinitionRecordConsts.MaxDisplayNameLength); IsEnabled = isEnabled; @@ -69,6 +82,16 @@ public class PermissionDefinitionRecord : BasicAggregateRoot, IHasExtraPro return false; } + if (ResourceName != otherRecord.ResourceName) + { + return false; + } + + if (ManagementPermissionName != otherRecord.ManagementPermissionName) + { + return false; + } + if (GroupName != otherRecord.GroupName) { return false; @@ -119,6 +142,16 @@ public class PermissionDefinitionRecord : BasicAggregateRoot, IHasExtraPro Name = otherRecord.Name; } + if (ResourceName != otherRecord.ResourceName) + { + ResourceName = otherRecord.ResourceName; + } + + if (ManagementPermissionName != otherRecord.ManagementPermissionName) + { + ManagementPermissionName = otherRecord.ManagementPermissionName; + } + if (GroupName != otherRecord.GroupName) { GroupName = otherRecord.GroupName; 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 8e63342502..707a3e89ea 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 @@ -19,7 +19,7 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I public PermissionDefinitionSerializer( IGuidGenerator guidGenerator, - ISimpleStateCheckerSerializer stateCheckerSerializer, + ISimpleStateCheckerSerializer stateCheckerSerializer, ILocalizableStringSerializer localizableStringSerializer) { StateCheckerSerializer = stateCheckerSerializer; @@ -27,16 +27,16 @@ 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(); var permissionRecords = new List(); - + foreach (var permissionGroup in permissionGroups) { permissionGroupRecords.Add(await SerializeAsync(permissionGroup)); - + foreach (var permission in permissionGroup.GetPermissionsWithChildren()) { permissionRecords.Add(await SerializeAsync(permission, permissionGroup)); @@ -45,8 +45,19 @@ 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)) { @@ -60,12 +71,12 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I { permissionGroupRecord.SetProperty(property.Key, property.Value); } - + return Task.FromResult(permissionGroupRecord); } } - - public Task SerializeAsync( + + public virtual Task SerializeAsync( PermissionDefinition permission, PermissionGroupDefinition permissionGroup) { @@ -75,6 +86,8 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I GuidGenerator.Create(), permissionGroup?.Name, permission.Name, + permission.ResourceName, + permission.ManagementPermissionName, permission.Parent?.Name, LocalizableStringSerializer.Serialize(permission.DisplayName), permission.IsEnabled, @@ -87,11 +100,11 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I { permissionRecord.SetProperty(property.Key, property.Value); } - + return Task.FromResult(permissionRecord); } } - + protected virtual string SerializeProviders(ICollection providers) { return providers.Any() @@ -103,4 +116,4 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I { return StateCheckerSerializer.Serialize(stateCheckers); } -} \ No newline at end of file +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManagementOptions.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManagementOptions.cs index 489ae26e3d..2971cc18ae 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManagementOptions.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManagementOptions.cs @@ -9,6 +9,10 @@ public class PermissionManagementOptions public Dictionary ProviderPolicies { get; } + public ITypeList ResourceManagementProviders { get; } + + public ITypeList ResourcePermissionProviderKeyLookupServices { get; } + /// /// Default: true. /// @@ -23,5 +27,8 @@ public class PermissionManagementOptions { ManagementProviders = new TypeList(); ProviderPolicies = new Dictionary(); + + ResourceManagementProviders = new TypeList(); + ResourcePermissionProviderKeyLookupServices = new TypeList(); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionProviderWithPermissions.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionProviderWithPermissions.cs new file mode 100644 index 0000000000..a6507ef0bc --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionProviderWithPermissions.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Volo.Abp.Localization; + +namespace Volo.Abp.PermissionManagement; + +public class PermissionProviderWithPermissions +{ + public string ProviderName { get; set; } + + public string ProviderKey { get; set; } + + public string ProviderDisplayName { get; set; } + + public ILocalizableString ProviderNameDisplayName { get; set; } + + public List Permissions { get; set; } + + public PermissionProviderWithPermissions(string providerName, string providerKey, string providerDisplayName) + { + ProviderName = providerName; + ProviderKey = providerKey; + ProviderDisplayName = providerDisplayName; + Permissions = new List(); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrant.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrant.cs new file mode 100644 index 0000000000..b74da527ae --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrant.cs @@ -0,0 +1,52 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.PermissionManagement; + +//TODO: To aggregate root? +public class ResourcePermissionGrant : Entity, IMultiTenant +{ + public virtual Guid? TenantId { get; protected set; } + + [NotNull] + public virtual string Name { get; protected set; } + + [NotNull] + public virtual string ProviderName { get; protected set; } + + [NotNull] + public virtual string ProviderKey { get; protected internal set; } + + [NotNull] + public virtual string ResourceName { get; protected set; } + + [NotNull] + public virtual string ResourceKey { get; protected set; } + + protected ResourcePermissionGrant() + { + + } + + public ResourcePermissionGrant( + Guid id, + [NotNull] string name, + [NotNull] string resourceName, + [NotNull] string resourceKey, + [NotNull] string providerName, + [CanBeNull] string providerKey, + Guid? tenantId = null) + { + Check.NotNull(name, nameof(name)); + + Id = id; + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + ResourceName = Check.NotNullOrWhiteSpace(resourceName, nameof(resourceName)); + ResourceKey = Check.NotNullOrWhiteSpace(resourceKey, nameof(resourceKey)); + ProviderName = Check.NotNullOrWhiteSpace(providerName, nameof(providerName)); + ProviderKey = Check.NotNullOrWhiteSpace(providerKey, nameof(providerKey)); + TenantId = tenantId; + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItem.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItem.cs new file mode 100644 index 0000000000..59362f6f5f --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItem.cs @@ -0,0 +1,34 @@ +using System; +using System.Linq; +using Volo.Abp.Text.Formatting; + +namespace Volo.Abp.PermissionManagement; + +[Serializable] +public class ResourcePermissionGrantCacheItem +{ + private const string CacheKeyFormat = "rn:{0},rk:{1},pn:{2},pk:{3},n:{4}"; + + public bool IsGranted { get; set; } + + public ResourcePermissionGrantCacheItem() + { + + } + + public ResourcePermissionGrantCacheItem(bool isGranted) + { + IsGranted = isGranted; + } + + public static string CalculateCacheKey(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + return string.Format(CacheKeyFormat, resourceName, resourceKey, providerName, providerKey, name); + } + + public static string GetPermissionNameFormCacheKeyOrNull(string cacheKey) + { + var result = FormattedStringValueExtracter.Extract(cacheKey, CacheKeyFormat, true); + return result.IsMatch ? result.Matches.Last().Value : null; + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItemInvalidator.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItemInvalidator.cs new file mode 100644 index 0000000000..97c116de56 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItemInvalidator.cs @@ -0,0 +1,44 @@ +using System.Threading.Tasks; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionGrantCacheItemInvalidator : + ILocalEventHandler>, + ITransientDependency +{ + protected ICurrentTenant CurrentTenant { get; } + + protected IDistributedCache Cache { get; } + + public ResourcePermissionGrantCacheItemInvalidator(IDistributedCache cache, ICurrentTenant currentTenant) + { + Cache = cache; + CurrentTenant = currentTenant; + } + + public virtual async Task HandleEventAsync(EntityChangedEventData eventData) + { + var cacheKey = CalculateCacheKey( + eventData.Entity.Name, + eventData.Entity.ResourceName, + eventData.Entity.ResourceKey, + eventData.Entity.ProviderName, + eventData.Entity.ProviderKey + ); + + using (CurrentTenant.Change(eventData.Entity.TenantId)) + { + await Cache.RemoveAsync(cacheKey, considerUow: true); + } + } + + protected virtual string CalculateCacheKey(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + return ResourcePermissionGrantCacheItem.CalculateCacheKey(name, resourceName, resourceKey, providerName, providerKey); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManagementProvider.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManagementProvider.cs new file mode 100644 index 0000000000..90d4e176d3 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManagementProvider.cs @@ -0,0 +1,87 @@ +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.PermissionManagement; + +public abstract class ResourcePermissionManagementProvider : IResourcePermissionManagementProvider +{ + public abstract string Name { get; } + + protected IResourcePermissionGrantRepository ResourcePermissionGrantRepository { get; } + + protected IGuidGenerator GuidGenerator { get; } + + protected ICurrentTenant CurrentTenant { get; } + + protected ResourcePermissionManagementProvider( + IResourcePermissionGrantRepository resourcePermissionGrantRepository, + IGuidGenerator guidGenerator, + ICurrentTenant currentTenant) + { + ResourcePermissionGrantRepository = resourcePermissionGrantRepository; + GuidGenerator = guidGenerator; + CurrentTenant = currentTenant; + } + + public virtual async Task CheckAsync(string name, string resourceName,string resourceKey, string providerName, string providerKey) + { + var multiplePermissionValueProviderGrantInfo = await CheckAsync(new[] { name }, resourceName, resourceKey, providerName, providerKey); + + return multiplePermissionValueProviderGrantInfo.Result.First().Value; + } + + public virtual async Task CheckAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) + { + using (ResourcePermissionGrantRepository.DisableTracking()) + { + var multiplePermissionValueProviderGrantInfo = new MultipleResourcePermissionValueProviderGrantInfo(names); + if (providerName != Name) + { + return multiplePermissionValueProviderGrantInfo; + } + + var resourcePermissionGrants = await ResourcePermissionGrantRepository.GetListAsync(names, resourceName, resourceKey, providerName, providerKey); + + foreach (var permissionName in names) + { + var isGrant = resourcePermissionGrants.Any(x => x.Name == permissionName); + multiplePermissionValueProviderGrantInfo.Result[permissionName] = new ResourcePermissionValueProviderGrantInfo(isGrant, providerKey); + } + + return multiplePermissionValueProviderGrantInfo; + } + } + + public virtual Task SetAsync(string name, string resourceName,string resourceKey, string providerKey, bool isGranted) + { + return isGranted + ? GrantAsync(name, resourceName, resourceKey, providerKey) + : RevokeAsync(name, resourceName, resourceKey, providerKey); + } + + protected virtual async Task GrantAsync(string name, string resourceName, string resourceKey, string providerKey) + { + var resourcePermissionGrants = await ResourcePermissionGrantRepository.FindAsync(name, resourceName, resourceKey, Name, providerKey); + if (resourcePermissionGrants != null) + { + return; + } + + resourcePermissionGrants = new ResourcePermissionGrant(GuidGenerator.Create(), name, resourceName, resourceKey, Name, providerKey, CurrentTenant.Id); + await ResourcePermissionGrantRepository.InsertAsync(resourcePermissionGrants, true); + } + + protected virtual async Task RevokeAsync(string name, string resourceName,string resourceKey, string providerKey) + { + var resourcePermissionGrants = await ResourcePermissionGrantRepository.FindAsync(name, resourceName, resourceKey, Name, providerKey); + if (resourcePermissionGrants == null) + { + return; + } + + await ResourcePermissionGrantRepository.DeleteAsync(resourcePermissionGrants, true); + } +} 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 new file mode 100644 index 0000000000..fc06819b47 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs @@ -0,0 +1,405 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionManager : IResourcePermissionManager, ISingletonDependency +{ + protected IResourcePermissionGrantRepository ResourcePermissionGrantRepository { get; } + + protected IPermissionDefinitionManager PermissionDefinitionManager { get; } + + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } + + protected IGuidGenerator GuidGenerator { get; } + + protected ICurrentTenant CurrentTenant { get; } + + protected IReadOnlyList ManagementProviders => _lazyProviders.Value; + + protected PermissionManagementOptions Options { get; } + + protected IDistributedCache Cache { get; } + + private readonly Lazy> _lazyProviders; + + private readonly Lazy> _lazyProviderKeyLookupServices; + + public ResourcePermissionManager( + IPermissionDefinitionManager permissionDefinitionManager, + ISimpleStateCheckerManager simpleStateCheckerManager, + IResourcePermissionGrantRepository resourcePermissionGrantRepository, + IServiceProvider serviceProvider, + IGuidGenerator guidGenerator, + IOptions options, + ICurrentTenant currentTenant, + IDistributedCache cache) + { + GuidGenerator = guidGenerator; + CurrentTenant = currentTenant; + Cache = cache; + SimpleStateCheckerManager = simpleStateCheckerManager; + ResourcePermissionGrantRepository = resourcePermissionGrantRepository; + PermissionDefinitionManager = permissionDefinitionManager; + Options = options.Value; + + _lazyProviders = new Lazy>( + () => Options + .ResourceManagementProviders + .Select(c => serviceProvider.GetRequiredService(c) as IResourcePermissionManagementProvider) + .ToList(), + true + ); + + _lazyProviderKeyLookupServices = new Lazy>( + () => Options + .ResourcePermissionProviderKeyLookupServices + .Select(c => serviceProvider.GetRequiredService(c) as IResourcePermissionProviderKeyLookupService) + .ToList(), + true + ); + } + + public virtual Task> GetProviderKeyLookupServicesAsync() + { + return Task.FromResult(_lazyProviderKeyLookupServices.Value); + } + + public virtual Task GetProviderKeyLookupServiceAsync(string serviceName) + { + var service = _lazyProviderKeyLookupServices.Value.FirstOrDefault(s => s.Name == serviceName); + return service == null + ? throw new AbpException("Unknown resource permission provider key lookup service: " + serviceName) + : Task.FromResult(service); + } + + public virtual async Task> GetAvailablePermissionsAsync(string resourceName) + { + var multiTenancySide = CurrentTenant.GetMultiTenancySide(); + var resourcePermissions = new List(); + foreach (var resourcePermission in (await PermissionDefinitionManager.GetResourcePermissionsAsync()) + .Where(x => x.IsEnabled && x.MultiTenancySide.HasFlag(multiTenancySide) && x.ResourceName == resourceName)) + { + if (await SimpleStateCheckerManager.IsEnabledAsync(resourcePermission)) + { + resourcePermissions.Add(resourcePermission); + } + } + + return resourcePermissions; + } + + public virtual async Task GetAsync(string permissionName, string resourceName, string resourceKey, string providerName, string providerKey) + { + var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(resourceName, permissionName); + if (permission == null || permission.ResourceName != resourceName) + { + return new PermissionWithGrantedProviders(permissionName, false); + } + + return await GetInternalAsync( + permission, + resourceName, + resourceKey, + providerName, + providerKey + ); + } + + public virtual async Task GetAsync(string[] permissionNames, string resourceName, string resourceKey, string providerName, string providerKey) + { + var permissions = new List(); + var undefinedPermissions = new List(); + + foreach (var permissionName in permissionNames) + { + var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(resourceName, permissionName); + if (permission != null && permission.ResourceName == resourceName) + { + permissions.Add(permission); + } + else + { + undefinedPermissions.Add(permissionName); + } + } + + if (!permissions.Any()) + { + return new MultiplePermissionWithGrantedProviders(undefinedPermissions.ToArray()); + } + + var result = await GetInternalAsync( + permissions.ToArray(), + resourceName, + resourceKey, + providerName, + providerKey + ); + + foreach (var undefinedPermission in undefinedPermissions) + { + result.Result.Add(new PermissionWithGrantedProviders(undefinedPermission, false)); + } + + return result; + } + + public virtual async Task> GetAllAsync(string resourceName, string resourceKey) + { + var resourcePermissionDefinitions = await GetAvailablePermissionsAsync(resourceName); + var resourcePermissionGrants = await ResourcePermissionGrantRepository.GetPermissionsAsync(resourceName, resourceKey); + 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) + .ToList(); + + if (grantedPermissions.Any()) + { + permissionWithGrantedProviders.IsGranted = true; + foreach (var grantedPermission in grantedPermissions) + { + permissionWithGrantedProviders.Providers.Add(new PermissionValueProviderInfo(grantedPermission.ProviderName, grantedPermission.ProviderKey)); + } + } + + result.Add(permissionWithGrantedProviders); + } + + return result; + } + + public virtual async Task> GetAllAsync(string resourceName, string resourceKey, string providerName, string providerKey) + { + var permissionDefinitions = await GetAvailablePermissionsAsync(resourceName); + var multiplePermissionWithGrantedProviders = await GetInternalAsync(permissionDefinitions.ToArray(), resourceName, resourceKey, providerName, providerKey); + return multiplePermissionWithGrantedProviders.Result; + } + + public virtual async Task> GetAllGroupAsync(string resourceName, string resourceKey) + { + 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 resourcePermissionGrantsGroup = resourcePermissionGrants.GroupBy(x => new { x.ProviderName, x.ProviderKey }); + var result = new List(); + foreach (var resourcePermissionGrant in resourcePermissionGrantsGroup) + { + result.Add(new PermissionProviderWithPermissions(resourcePermissionGrant.Key.ProviderName, resourcePermissionGrant.Key.ProviderKey, resourcePermissionGrant.Key.ProviderKey) + { + Permissions = resourcePermissionGrant.Select(x => x.Name).ToList() + }); + } + + if (result.Any()) + { + var providerKeyInfos = new Dictionary>(); + var resourcePermissionProviderGroup = resourcePermissionGrants.GroupBy(x => x.ProviderName); + var providerKeyLookupServices = await GetProviderKeyLookupServicesAsync(); + foreach (var resourcePermissionProvider in resourcePermissionProviderGroup) + { + var providerKeyLookupService = providerKeyLookupServices.FirstOrDefault(s => s.Name == resourcePermissionProvider.Key); + if (providerKeyLookupService == null) + { + continue; + } + var keys = resourcePermissionProvider.Select(rp => rp.ProviderKey).Distinct().ToList(); + providerKeyInfos.Add(resourcePermissionProvider.Key, await providerKeyLookupService.SearchAsync(keys.ToArray())); + } + + foreach (var item in result) + { + if (!providerKeyInfos.TryGetValue(item.ProviderName, out var providerKeyInfoList)) + { + continue; + } + + var providerKeyInfo = providerKeyInfoList.FirstOrDefault(p => p.ProviderKey == item.ProviderKey); + if (providerKeyInfo != null) + { + item.ProviderDisplayName = providerKeyInfo.ProviderDisplayName; + item.ProviderNameDisplayName = providerKeyLookupServices + .FirstOrDefault(s => s.Name == item.ProviderName)?.DisplayName; + } + } + } + + return result; + } + + public virtual async Task SetAsync(string permissionName, string resourceName, string resourceKey, string providerName, string providerKey, bool isGranted) + { + var permission = await PermissionDefinitionManager.GetResourcePermissionOrNullAsync(resourceName, permissionName); + if (permission == null || permission.ResourceName != resourceName) + { + /* Silently ignore undefined permissions, + maybe they were removed from dynamic permission definition store */ + return; + } + + if (!permission.IsEnabled || !await SimpleStateCheckerManager.IsEnabledAsync(permission)) + { + //TODO: BusinessException + throw new ApplicationException($"The resource permission named '{permission.Name}' is disabled!"); + } + + if (permission.Providers.Any() && !permission.Providers.Contains(providerName)) + { + //TODO: BusinessException + throw new ApplicationException($"The resource permission named '{permission.Name}' has not compatible with the provider named '{providerName}'"); + } + + if (!permission.MultiTenancySide.HasFlag(CurrentTenant.GetMultiTenancySide())) + { + //TODO: BusinessException + throw new ApplicationException($"The resource permission named '{permission.Name}' has multitenancy side '{permission.MultiTenancySide}' which is not compatible with the current multitenancy side '{CurrentTenant.GetMultiTenancySide()}'"); + } + + var currentGrantInfo = await GetInternalAsync(permission, resourceName, resourceKey, providerName, providerKey); + if (currentGrantInfo.IsGranted == isGranted) + { + return; + } + + var provider = ManagementProviders.FirstOrDefault(m => m.Name == providerName); + if (provider == null) + { + //TODO: BusinessException + throw new AbpException("Unknown resource permission management provider: " + providerName); + } + + await provider.SetAsync(permissionName, resourceName, resourceKey, providerKey, isGranted); + } + + public virtual async Task UpdateProviderKeyAsync(ResourcePermissionGrant resourcePermissionGrant, string providerKey) + { + using (CurrentTenant.Change(resourcePermissionGrant.TenantId)) + { + //Invalidating the cache for the old key + await Cache.RemoveAsync( + ResourcePermissionGrantCacheItem.CalculateCacheKey( + resourcePermissionGrant.Name, + resourcePermissionGrant.ResourceName, + resourcePermissionGrant.ResourceKey, + resourcePermissionGrant.ProviderName, + resourcePermissionGrant.ProviderKey + ) + ); + } + + resourcePermissionGrant.ProviderKey = providerKey; + return await ResourcePermissionGrantRepository.UpdateAsync(resourcePermissionGrant, true); + } + + public virtual async Task UpdateProviderKeyAsync(ResourcePermissionGrant resourcePermissionGrant, string resourceName, string resourceKey, string providerKey) + { + using (CurrentTenant.Change(resourcePermissionGrant.TenantId)) + { + //Invalidating the cache for the old key + await Cache.RemoveAsync( + ResourcePermissionGrantCacheItem.CalculateCacheKey( + resourcePermissionGrant.Name, + resourcePermissionGrant.ResourceName, + resourcePermissionGrant.ResourceKey, + resourcePermissionGrant.ProviderName, + resourcePermissionGrant.ProviderKey + ) + ); + } + + resourcePermissionGrant.ProviderKey = providerKey; + return await ResourcePermissionGrantRepository.UpdateAsync(resourcePermissionGrant, true); + } + + public virtual async Task DeleteAsync(string resourceName, string resourceKey, string providerName, string providerKey) + { + var permissionGrants = await ResourcePermissionGrantRepository.GetListAsync(resourceName, resourceKey, providerName, providerKey); + foreach (var permissionGrant in permissionGrants) + { + await ResourcePermissionGrantRepository.DeleteAsync(permissionGrant, true); + } + } + + public virtual async Task DeleteAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + var permissionGrant = await ResourcePermissionGrantRepository.FindAsync(name, resourceName, resourceKey, providerName, providerKey); + if (permissionGrant != null) + { + await ResourcePermissionGrantRepository.DeleteAsync(permissionGrant, true); + } + } + + public virtual async Task DeleteAsync(string providerName, string providerKey) + { + var permissionGrants = await ResourcePermissionGrantRepository.GetListAsync(providerName, providerKey); + foreach (var permissionGrant in permissionGrants) + { + await ResourcePermissionGrantRepository.DeleteAsync(permissionGrant, true); + } + } + + protected virtual async Task GetInternalAsync(PermissionDefinition permission, string resourceName, string resourceKey, string providerName, string providerKey) + { + var multiplePermissionWithGrantedProviders = await GetInternalAsync( + new[] { permission }, + resourceName, + resourceKey, + providerName, + providerKey + ); + + return multiplePermissionWithGrantedProviders.Result.First(); + } + + protected virtual async Task GetInternalAsync(PermissionDefinition[] permissions, string resourceName, string resourceKey, string providerName, string providerKey) + { + var permissionNames = permissions.Select(x => x.Name).ToArray(); + var multiplePermissionWithGrantedProviders = new MultiplePermissionWithGrantedProviders(permissionNames); + + var resourcePermissions = await GetAvailablePermissionsAsync(resourceName); + if (!resourcePermissions.Any()) + { + return multiplePermissionWithGrantedProviders; + } + + foreach (var provider in ManagementProviders) + { + permissionNames = resourcePermissions.Select(x => x.Name).ToArray(); + var multiplePermissionValueProviderGrantInfo = await provider.CheckAsync(permissionNames, resourceName, resourceKey, providerName, providerKey); + + foreach (var providerResultDict in multiplePermissionValueProviderGrantInfo.Result) + { + if (providerResultDict.Value.IsGranted) + { + var permissionWithGrantedProvider = multiplePermissionWithGrantedProviders.Result + .FirstOrDefault(x => x.Name == providerResultDict.Key); + + if (permissionWithGrantedProvider == null) + { + continue; + } + + permissionWithGrantedProvider.IsGranted = true; + permissionWithGrantedProvider.Providers.Add( + new PermissionValueProviderInfo(provider.Name, providerResultDict.Value.ProviderKey)); + } + } + } + + return multiplePermissionWithGrantedProviders; + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionProviderKeyInfo.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionProviderKeyInfo.cs new file mode 100644 index 0000000000..841277514a --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionProviderKeyInfo.cs @@ -0,0 +1,16 @@ +using Volo.Abp.ObjectExtending; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionProviderKeyInfo +{ + public string ProviderKey { get; set; } + + public string ProviderDisplayName { get; set; } + + public ResourcePermissionProviderKeyInfo(string providerKey, string providerDisplayName) + { + ProviderKey = providerKey; + ProviderDisplayName = providerDisplayName; + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionStore.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionStore.cs new file mode 100644 index 0000000000..9e09ff2db4 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionStore.cs @@ -0,0 +1,249 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionStore : IResourcePermissionStore, ITransientDependency +{ + public ILogger Logger { get; set; } + + protected IResourcePermissionGrantRepository ResourcePermissionGrantRepository { get; } + + protected IPermissionDefinitionManager PermissionDefinitionManager { get; } + + protected IDistributedCache Cache { get; } + + public ResourcePermissionStore( + IResourcePermissionGrantRepository resourcePermissionGrantRepository, + IDistributedCache cache, + IPermissionDefinitionManager permissionDefinitionManager) + { + ResourcePermissionGrantRepository = resourcePermissionGrantRepository; + Cache = cache; + PermissionDefinitionManager = permissionDefinitionManager; + Logger = NullLogger.Instance; + } + + public virtual async Task IsGrantedAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + return (await GetCacheItemAsync(name, resourceName, resourceKey, providerName, providerKey)).IsGranted; + } + + protected virtual async Task GetCacheItemAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + var cacheKey = CalculateCacheKey(name, providerName, providerKey, resourceName, resourceKey); + + Logger.LogDebug($"ResourcePermissionStore.GetCacheItemAsync: {cacheKey}"); + + var cacheItem = await Cache.GetAsync(cacheKey); + + if (cacheItem != null) + { + Logger.LogDebug($"Found in the cache: {cacheKey}"); + return cacheItem; + } + + Logger.LogDebug($"Not found in the cache: {cacheKey}"); + + cacheItem = new ResourcePermissionGrantCacheItem(false); + + await SetCacheItemsAsync(resourceName, resourceKey, providerName, providerKey, name, cacheItem); + + return cacheItem; + } + + protected virtual async Task SetCacheItemsAsync(string resourceName, string resourceKey, string providerName, string providerKey, string currentName, ResourcePermissionGrantCacheItem currentCacheItem) + { + using (ResourcePermissionGrantRepository.DisableTracking()) + { + var permissions = await PermissionDefinitionManager.GetResourcePermissionsAsync(); + + Logger.LogDebug($"Getting all granted resource permissions from the repository for resource name,key:{resourceName},{resourceKey} and provider name,key: {providerName},{providerKey}"); + + var grantedPermissionsHashSet = new HashSet( + (await ResourcePermissionGrantRepository.GetListAsync(resourceName, resourceKey, providerName, providerKey)).Select(p => p.Name) + ); + + Logger.LogDebug($"Setting the cache items. Count: {permissions.Count}"); + + var cacheItems = new List>(); + + foreach (var permission in permissions) + { + var isGranted = grantedPermissionsHashSet.Contains(permission.Name); + + cacheItems.Add(new KeyValuePair( + CalculateCacheKey(permission.Name, resourceName, resourceKey, providerName, providerKey), + new ResourcePermissionGrantCacheItem(isGranted)) + ); + + if (permission.Name == currentName) + { + currentCacheItem.IsGranted = isGranted; + } + } + + await Cache.SetManyAsync(cacheItems); + + Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}"); + } + } + + public virtual async Task IsGrantedAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) + { + Check.NotNullOrEmpty(names, nameof(names)); + + var result = new MultiplePermissionGrantResult(); + + if (names.Length == 1) + { + var name = names.First(); + result.Result.Add(name, + await IsGrantedAsync(names.First(), resourceName, resourceKey, providerName, providerKey) + ? PermissionGrantResult.Granted + : PermissionGrantResult.Undefined); + return result; + } + + var cacheItems = await GetCacheItemsAsync(names, resourceName, resourceKey, providerName, providerKey); + foreach (var item in cacheItems) + { + result.Result.Add(GetPermissionNameFormCacheKeyOrNull(item.Key), + item.Value != null && item.Value.IsGranted + ? PermissionGrantResult.Granted + : PermissionGrantResult.Undefined); + } + + return result; + } + + protected virtual async Task>> GetCacheItemsAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) + { + var cacheKeys = names.Select(x => CalculateCacheKey(x, resourceName, resourceKey, providerName, providerKey)).ToList(); + + Logger.LogDebug($"ResourcePermissionStore.GetCacheItemAsync: {string.Join(",", cacheKeys)}"); + + var cacheItems = (await Cache.GetManyAsync(cacheKeys)).ToList(); + if (cacheItems.All(x => x.Value != null)) + { + Logger.LogDebug($"Found in the cache: {string.Join(",", cacheKeys)}"); + return cacheItems; + } + + var notCacheKeys = cacheItems.Where(x => x.Value == null).Select(x => x.Key).ToList(); + + Logger.LogDebug($"Not found in the cache: {string.Join(",", notCacheKeys)}"); + + var newCacheItems = await SetCacheItemsAsync(resourceName, resourceKey, providerName, providerKey, notCacheKeys); + + var result = new List>(); + foreach (var key in cacheKeys) + { + var item = newCacheItems.FirstOrDefault(x => x.Key == key); + if (item.Value == null) + { + item = cacheItems.FirstOrDefault(x => x.Key == key); + } + + result.Add(new KeyValuePair(key, item.Value)); + } + + return result; + } + + protected virtual async Task>> SetCacheItemsAsync(string resourceName, string resourceKey, string providerName, string providerKey, List notCacheKeys) + { + using (ResourcePermissionGrantRepository.DisableTracking()) + { + var permissionNames = new HashSet(notCacheKeys.Select(GetPermissionNameFormCacheKeyOrNull)); + var permissions = (await PermissionDefinitionManager.GetResourcePermissionsAsync()) + .Where(x => permissionNames.Contains(x.Name)) + .ToList(); + + Logger.LogDebug($"Getting not cache granted permissions from the repository for resource name,key:{resourceName},{resourceKey} and provider name,key: {providerName},{providerKey}"); + + var grantedPermissionsHashSet = new HashSet( + (await ResourcePermissionGrantRepository.GetListAsync(permissionNames.ToArray(), resourceName, resourceKey, providerName, providerKey)).Select(p => p.Name) + ); + + Logger.LogDebug($"Setting the cache items. Count: {permissions.Count}"); + + var cacheItems = new List>(); + + foreach (var permission in permissions) + { + var isGranted = grantedPermissionsHashSet.Contains(permission.Name); + + cacheItems.Add(new KeyValuePair( + CalculateCacheKey(permission.Name, resourceName, resourceKey, providerName, providerKey), + new ResourcePermissionGrantCacheItem(isGranted)) + ); + } + + await Cache.SetManyAsync(cacheItems); + + Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}"); + + return cacheItems; + } + } + + public virtual async Task GetPermissionsAsync(string resourceName, string resourceKey) + { + using (ResourcePermissionGrantRepository.DisableTracking()) + { + var result = new MultiplePermissionGrantResult(); + + var resourcePermissions = (await PermissionDefinitionManager.GetResourcePermissionsAsync()).Where(x => x.ResourceName == resourceName).ToList(); + var permissionGrants = await ResourcePermissionGrantRepository.GetPermissionsAsync(resourceName, resourceKey); + foreach (var resourcePermission in resourcePermissions) + { + var isGranted = permissionGrants.Any(x => x.Name == resourcePermission.Name); + result.Result.Add(resourcePermission.Name, isGranted ? PermissionGrantResult.Granted : PermissionGrantResult.Undefined); + } + + return result; + } + } + + public virtual async Task GetGrantedPermissionsAsync(string resourceName, string resourceKey) + { + var resourcePermissions = (await PermissionDefinitionManager.GetResourcePermissionsAsync()).Where(x => x.ResourceName == resourceName).ToList(); + var grantedPermissions = await ResourcePermissionGrantRepository.GetPermissionsAsync(resourceName, resourceKey); + + var result = new List(); + foreach (var grantedPermission in grantedPermissions) + { + if (resourcePermissions.Any(x => x.Name == grantedPermission.Name)) + { + result.Add(grantedPermission.Name); + } + } + + return result.ToArray(); + } + + public virtual async Task GetGrantedResourceKeysAsync(string resourceName, string name) + { + return (await ResourcePermissionGrantRepository.GetResourceKeys(resourceName, name)).Select(x => x.ResourceKey).ToArray(); + } + + protected virtual string GetPermissionNameFormCacheKeyOrNull(string key) + { + //TODO: throw ex when name is null? + return ResourcePermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(key); + } + + protected virtual string CalculateCacheKey(string name, string resourceName, string resourceKey, string providerName, string providerKey) + { + return ResourcePermissionGrantCacheItem.CalculateCacheKey(name, resourceName, resourceKey, providerName, providerKey); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionValueProviderGrantInfo.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionValueProviderGrantInfo.cs new file mode 100644 index 0000000000..5cb0d5013a --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionValueProviderGrantInfo.cs @@ -0,0 +1,18 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionValueProviderGrantInfo //TODO: Rename to ResourcePermissionGrantInfo +{ + public static ResourcePermissionValueProviderGrantInfo NonGranted { get; } = new ResourcePermissionValueProviderGrantInfo(false); + + public virtual bool IsGranted { get; set; } + + public virtual string ProviderKey { get; set; } + + public ResourcePermissionValueProviderGrantInfo(bool isGranted, [CanBeNull] string providerKey = null) + { + IsGranted = isGranted; + ProviderKey = providerKey; + } +} 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 fa6862abf6..c7bf3f2a5a 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 @@ -27,6 +27,23 @@ public static class AbpPermissionManagementDbContextModelBuilderExtensions b.ApplyObjectExtensionMappings(); }); + builder.Entity(b => + { + b.ToTable(AbpPermissionManagementDbProperties.DbTablePrefix + "ResourcePermissionGrants", AbpPermissionManagementDbProperties.DbSchema); + + b.ConfigureByConvention(); + + b.Property(x => x.Name).HasMaxLength(PermissionDefinitionRecordConsts.MaxNameLength).IsRequired(); + b.Property(x => x.ResourceName).HasMaxLength(PermissionGrantConsts.MaxResourceNameLength).IsRequired(); + b.Property(x => x.ResourceKey).HasMaxLength(PermissionGrantConsts.MaxResourceKeyLength).IsRequired(); + b.Property(x => x.ProviderName).HasMaxLength(PermissionGrantConsts.MaxProviderNameLength).IsRequired(); + b.Property(x => x.ProviderKey).HasMaxLength(PermissionGrantConsts.MaxProviderKeyLength).IsRequired(); + + b.HasIndex(x => new { x.TenantId, x.Name, x.ResourceName, x.ResourceKey, x.ProviderName, x.ProviderKey }).IsUnique(); + + b.ApplyObjectExtensionMappings(); + }); + if (builder.IsHostDatabase()) { builder.Entity(b => @@ -52,16 +69,16 @@ 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.ManagementPermissionName).HasMaxLength(PermissionDefinitionRecordConsts.MaxManagementPermissionNameLength); b.Property(x => x.ParentName).HasMaxLength(PermissionDefinitionRecordConsts.MaxNameLength); - b.Property(x => x.DisplayName).HasMaxLength(PermissionDefinitionRecordConsts.MaxDisplayNameLength) - .IsRequired(); + b.Property(x => x.DisplayName).HasMaxLength(PermissionDefinitionRecordConsts.MaxDisplayNameLength).IsRequired(); b.Property(x => x.Providers).HasMaxLength(PermissionDefinitionRecordConsts.MaxProvidersLength); b.Property(x => x.StateCheckers).HasMaxLength(PermissionDefinitionRecordConsts.MaxStateCheckersLength); - b.HasIndex(x => new { x.Name }).IsUnique(); + b.HasIndex(x => new { x.ResourceName, x.Name }).IsUnique(); b.HasIndex(x => new { x.GroupName }); b.ApplyObjectExtensionMappings(); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreModule.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreModule.cs index ebcc8527c1..da6dfe8b06 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreModule.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreModule.cs @@ -17,6 +17,7 @@ public class AbpPermissionManagementEntityFrameworkCoreModule : AbpModule options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCoreResourcePermissionGrantRepository.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCoreResourcePermissionGrantRepository.cs new file mode 100644 index 0000000000..385a45f989 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCoreResourcePermissionGrantRepository.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace Volo.Abp.PermissionManagement.EntityFrameworkCore; + +public class EfCoreResourcePermissionGrantRepository : EfCoreRepository, IResourcePermissionGrantRepository +{ + public EfCoreResourcePermissionGrantRepository(IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + + } + + public virtual async Task FindAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .OrderBy(x => x.Id) + .FirstOrDefaultAsync(s => + s.Name == name && + s.ResourceName == resourceName && + s.ResourceKey == resourceKey && + s.ProviderName == providerName && + s.ProviderKey == providerKey, + GetCancellationToken(cancellationToken) + ); + } + + public virtual async Task> GetListAsync(string resourceName, string resourceKey, string providerName, string providerKey, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(s => + s.ResourceName == resourceName && + s.ResourceKey == resourceKey && + s.ProviderName == providerName && + s.ProviderKey == providerKey + ).ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task> GetListAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(s => + names.Contains(s.Name) && + s.ResourceName == resourceName && + s.ResourceKey == resourceKey && + s.ProviderName == providerName && + s.ProviderKey == providerKey + ).ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task> GetListAsync(string providerName, string providerKey, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(s => + s.ProviderName == providerName && + s.ProviderKey == providerKey + ).ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task> GetPermissionsAsync(string resourceName, string resourceKey, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(s => + s.ResourceName == resourceName && + s.ResourceKey == resourceKey + ).ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task> GetResourceKeys(string resourceName, string name, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(s => + s.ResourceName == resourceName && + s.Name == name + ).ToListAsync(GetCancellationToken(cancellationToken)); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/IPermissionManagementDbContext.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/IPermissionManagementDbContext.cs index c294c1b248..de02ab70ec 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/IPermissionManagementDbContext.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/IPermissionManagementDbContext.cs @@ -8,8 +8,10 @@ namespace Volo.Abp.PermissionManagement.EntityFrameworkCore; public interface IPermissionManagementDbContext : IEfCoreDbContext { DbSet PermissionGroups { get; } - + DbSet Permissions { get; } - + DbSet PermissionGrants { get; } + + DbSet ResourcePermissionGrants { get; } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/PermissionManagementDbContext.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/PermissionManagementDbContext.cs index fe143fa8ae..59c724bfb7 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/PermissionManagementDbContext.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/PermissionManagementDbContext.cs @@ -10,6 +10,7 @@ public class PermissionManagementDbContext : AbpDbContext PermissionGroups { get; set; } public DbSet Permissions { get; set; } public DbSet PermissionGrants { get; set; } + public DbSet ResourcePermissionGrants { get; set; } public PermissionManagementDbContext(DbContextOptions options) : base(options) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.Generated.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.Generated.cs index 2fe22472f0..bd6e2c5e8e 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.Generated.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.Generated.cs @@ -45,4 +45,72 @@ public partial class PermissionsClientProxy : ClientProxyBase GetResourceProviderKeyLookupServicesAsync(string resourceName) + { + return await RequestAsync(nameof(GetResourceProviderKeyLookupServicesAsync), new ClientProxyRequestTypeValue + { + { typeof(string), resourceName } + }); + } + + public virtual async Task SearchResourceProviderKeyAsync(string resourceName, string serviceName, string filter, int page) + { + return await RequestAsync(nameof(SearchResourceProviderKeyAsync), new ClientProxyRequestTypeValue + { + { typeof(string), resourceName }, + { typeof(string), serviceName }, + { typeof(string), filter }, + { typeof(int), page } + }); + } + + public virtual async Task GetResourceDefinitionsAsync(string resourceName) + { + return await RequestAsync(nameof(GetResourceDefinitionsAsync), new ClientProxyRequestTypeValue + { + { typeof(string), resourceName } + }); + } + + public virtual async Task GetResourceAsync(string resourceName, string resourceKey) + { + return await RequestAsync(nameof(GetResourceAsync), new ClientProxyRequestTypeValue + { + { typeof(string), resourceName }, + { typeof(string), resourceKey } + }); + } + + public virtual async Task GetResourceByProviderAsync(string resourceName, string resourceKey, string providerName, string providerKey) + { + return await RequestAsync(nameof(GetResourceByProviderAsync), new ClientProxyRequestTypeValue + { + { typeof(string), resourceName }, + { typeof(string), resourceKey }, + { typeof(string), providerName }, + { typeof(string), providerKey } + }); + } + + public virtual async Task UpdateResourceAsync(string resourceName, string resourceKey, UpdateResourcePermissionsDto input) + { + await RequestAsync(nameof(UpdateResourceAsync), new ClientProxyRequestTypeValue + { + { typeof(string), resourceName }, + { typeof(string), resourceKey }, + { typeof(UpdateResourcePermissionsDto), input } + }); + } + + public virtual async Task DeleteResourceAsync(string resourceName, string resourceKey, string providerName, string providerKey) + { + await RequestAsync(nameof(DeleteResourceAsync), new ClientProxyRequestTypeValue + { + { typeof(string), resourceName }, + { typeof(string), resourceKey }, + { typeof(string), providerName }, + { typeof(string), providerKey } + }); + } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json index 208271e67d..8b95d9be21 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json @@ -21,7 +21,7 @@ "parametersOnMethod": [ { "name": "input", - "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=9.3.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=10.1.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", "type": "System.Collections.Generic.List", "typeSimple": "[Volo.Abp.PermissionManagement.IsGrantedRequest]", "isOptional": false, @@ -46,7 +46,7 @@ "parametersOnMethod": [ { "name": "input", - "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=9.3.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=10.1.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", "type": "System.Collections.Generic.List", "typeSimple": "[Volo.Abp.PermissionManagement.IsGrantedRequest]", "isOptional": false, @@ -178,6 +178,221 @@ "type": "System.Void", "typeSimple": "System.Void" } + }, + { + "name": "GetResourceProviderKeyLookupServicesAsync", + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetResourceProviderListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetResourceProviderListResultDto" + } + }, + { + "name": "SearchResourceProviderKeyAsync", + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "serviceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "filter", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "page", + "typeAsString": "System.Int32, System.Private.CoreLib", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.SearchProviderKeyListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.SearchProviderKeyListResultDto" + } + }, + { + "name": "GetResourceDefinitionsAsync", + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetResourcePermissionDefinitionListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetResourcePermissionDefinitionListResultDto" + } + }, + { + "name": "GetResourceAsync", + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "resourceKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetResourcePermissionListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetResourcePermissionListResultDto" + } + }, + { + "name": "GetResourceByProviderAsync", + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "resourceKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetResourcePermissionWithProviderListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetResourcePermissionWithProviderListResultDto" + } + }, + { + "name": "UpdateResourceAsync", + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "resourceKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.PermissionManagement.UpdateResourcePermissionsDto, Volo.Abp.PermissionManagement.Application.Contracts", + "type": "Volo.Abp.PermissionManagement.UpdateResourcePermissionsDto", + "typeSimple": "Volo.Abp.PermissionManagement.UpdateResourcePermissionsDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "DeleteResourceAsync", + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "resourceKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } } ] } @@ -393,6 +608,505 @@ }, "allowAnonymous": null, "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" + }, + "GetResourceProviderKeyLookupServicesAsyncByResourceName": { + "uniqueName": "GetResourceProviderKeyLookupServicesAsyncByResourceName", + "name": "GetResourceProviderKeyLookupServicesAsync", + "httpMethod": "GET", + "url": "api/permission-management/permissions/resource-provider-key-lookup-services", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetResourceProviderListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetResourceProviderListResultDto" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" + }, + "SearchResourceProviderKeyAsyncByResourceNameAndServiceNameAndFilterAndPage": { + "uniqueName": "SearchResourceProviderKeyAsyncByResourceNameAndServiceNameAndFilterAndPage", + "name": "SearchResourceProviderKeyAsync", + "httpMethod": "GET", + "url": "api/permission-management/permissions/search-resource-provider-keys", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "serviceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "filter", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "page", + "typeAsString": "System.Int32, System.Private.CoreLib", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "serviceName", + "name": "serviceName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "filter", + "name": "filter", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "page", + "name": "page", + "jsonName": null, + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.SearchProviderKeyListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.SearchProviderKeyListResultDto" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" + }, + "GetResourceDefinitionsAsyncByResourceName": { + "uniqueName": "GetResourceDefinitionsAsyncByResourceName", + "name": "GetResourceDefinitionsAsync", + "httpMethod": "GET", + "url": "api/permission-management/permissions/resource-definitions", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetResourcePermissionDefinitionListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetResourcePermissionDefinitionListResultDto" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" + }, + "GetResourceAsyncByResourceNameAndResourceKey": { + "uniqueName": "GetResourceAsyncByResourceNameAndResourceKey", + "name": "GetResourceAsync", + "httpMethod": "GET", + "url": "api/permission-management/permissions/resource", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "resourceKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "resourceKey", + "name": "resourceKey", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetResourcePermissionListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetResourcePermissionListResultDto" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" + }, + "GetResourceByProviderAsyncByResourceNameAndResourceKeyAndProviderNameAndProviderKey": { + "uniqueName": "GetResourceByProviderAsyncByResourceNameAndResourceKeyAndProviderNameAndProviderKey", + "name": "GetResourceByProviderAsync", + "httpMethod": "GET", + "url": "api/permission-management/permissions/resource/by-provider", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "resourceKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "resourceKey", + "name": "resourceKey", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "providerName", + "name": "providerName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "providerKey", + "name": "providerKey", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetResourcePermissionWithProviderListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetResourcePermissionWithProviderListResultDto" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" + }, + "UpdateResourceAsyncByResourceNameAndResourceKeyAndInput": { + "uniqueName": "UpdateResourceAsyncByResourceNameAndResourceKeyAndInput", + "name": "UpdateResourceAsync", + "httpMethod": "PUT", + "url": "api/permission-management/permissions/resource", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "resourceKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.PermissionManagement.UpdateResourcePermissionsDto, Volo.Abp.PermissionManagement.Application.Contracts", + "type": "Volo.Abp.PermissionManagement.UpdateResourcePermissionsDto", + "typeSimple": "Volo.Abp.PermissionManagement.UpdateResourcePermissionsDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "resourceKey", + "name": "resourceKey", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "jsonName": null, + "type": "Volo.Abp.PermissionManagement.UpdateResourcePermissionsDto", + "typeSimple": "Volo.Abp.PermissionManagement.UpdateResourcePermissionsDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" + }, + "DeleteResourceAsyncByResourceNameAndResourceKeyAndProviderNameAndProviderKey": { + "uniqueName": "DeleteResourceAsyncByResourceNameAndResourceKeyAndProviderNameAndProviderKey", + "name": "DeleteResourceAsync", + "httpMethod": "DELETE", + "url": "api/permission-management/permissions/resource", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "resourceKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "resourceKey", + "name": "resourceKey", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "providerName", + "name": "providerName", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "providerKey", + "name": "providerKey", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" } } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs index ff6d7e6128..c1f65e353e 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs @@ -34,4 +34,50 @@ public class PermissionsController : AbpControllerBase, IPermissionAppService { return PermissionAppService.UpdateAsync(providerName, providerKey, input); } + + [HttpGet("resource-provider-key-lookup-services")] + public virtual Task GetResourceProviderKeyLookupServicesAsync(string resourceName) + { + return PermissionAppService.GetResourceProviderKeyLookupServicesAsync(resourceName); + } + + [HttpGet("search-resource-provider-keys")] + public virtual Task SearchResourceProviderKeyAsync(string resourceName, string serviceName, string filter, int page) + { + return PermissionAppService.SearchResourceProviderKeyAsync(resourceName, serviceName, filter, page); + } + + [HttpGet("resource-definitions")] + public virtual Task GetResourceDefinitionsAsync(string resourceName) + { + return PermissionAppService.GetResourceDefinitionsAsync(resourceName); + } + + [HttpGet] + [Route("resource")] + public virtual Task GetResourceAsync(string resourceName, string resourceKey) + { + return PermissionAppService.GetResourceAsync(resourceName, resourceKey); + } + + [HttpGet] + [Route("resource/by-provider")] + public virtual Task GetResourceByProviderAsync(string resourceName, string resourceKey, string providerName, string providerKey) + { + return PermissionAppService.GetResourceByProviderAsync(resourceName, resourceKey, providerName, providerKey); + } + + [HttpPut] + [Route("resource")] + public virtual Task UpdateResourceAsync(string resourceName, string resourceKey, UpdateResourcePermissionsDto input) + { + return PermissionAppService.UpdateResourceAsync(resourceName, resourceKey, input); + } + + [HttpDelete] + [Route("resource")] + public virtual Task DeleteResourceAsync(string resourceName, string resourceKey, string providerName, string providerKey) + { + return PermissionAppService.DeleteResourceAsync(resourceName, resourceKey, providerName, providerKey); + } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbContextExtensions.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbContextExtensions.cs index 9c7c90af58..4eb8eea3b6 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbContextExtensions.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbContextExtensions.cs @@ -13,15 +13,20 @@ public static class AbpPermissionManagementMongoDbContextExtensions { b.CollectionName = AbpPermissionManagementDbProperties.DbTablePrefix + "PermissionGroups"; }); - + builder.Entity(b => { b.CollectionName = AbpPermissionManagementDbProperties.DbTablePrefix + "Permissions"; }); - + builder.Entity(b => { b.CollectionName = AbpPermissionManagementDbProperties.DbTablePrefix + "PermissionGrants"; }); + + builder.Entity(b => + { + b.CollectionName = AbpPermissionManagementDbProperties.DbTablePrefix + "ResourcePermissionGrants"; + }); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbModule.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbModule.cs index 80831660f8..686d219295 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbModule.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbModule.cs @@ -19,6 +19,7 @@ public class AbpPermissionManagementMongoDbModule : AbpModule options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/IPermissionManagementMongoDbContext.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/IPermissionManagementMongoDbContext.cs index 98015484fb..454875f517 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/IPermissionManagementMongoDbContext.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/IPermissionManagementMongoDbContext.cs @@ -8,8 +8,10 @@ namespace Volo.Abp.PermissionManagement.MongoDB; public interface IPermissionManagementMongoDbContext : IAbpMongoDbContext { IMongoCollection PermissionGroups { get; } - + IMongoCollection Permissions { get; } - + IMongoCollection PermissionGrants { get; } + + IMongoCollection ResourcePermissionGrants { get; } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/MongoResourcePermissionGrantRepository.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/MongoResourcePermissionGrantRepository.cs new file mode 100644 index 0000000000..30db095854 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/MongoResourcePermissionGrantRepository.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver.Linq; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.PermissionManagement.MongoDB; + +public class MongoResourcePermissionGrantRepository : MongoDbRepository, IResourcePermissionGrantRepository +{ + public MongoResourcePermissionGrantRepository(IMongoDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + + } + + public virtual async Task FindAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey, CancellationToken cancellationToken = default) + { + cancellationToken = GetCancellationToken(cancellationToken); + return await (await GetQueryableAsync(cancellationToken)) + .OrderBy(x => x.Id) + .FirstOrDefaultAsync(s => + s.Name == name && + s.ResourceName == resourceName && + s.ResourceKey == resourceKey && + s.ProviderName == providerName && + s.ProviderKey == providerKey, + cancellationToken + ); + } + + public virtual async Task> GetListAsync(string resourceName, string resourceKey, string providerName, string providerKey, CancellationToken cancellationToken = default) + { + cancellationToken = GetCancellationToken(cancellationToken); + return await (await GetQueryableAsync(cancellationToken)) + .Where(s => + s.ResourceName == resourceName && + s.ResourceKey == resourceKey && + s.ProviderName == providerName && + s.ProviderKey == providerKey + ).ToListAsync(cancellationToken); + } + + public virtual async Task> GetListAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey, CancellationToken cancellationToken = default) + { + cancellationToken = GetCancellationToken(cancellationToken); + return await (await GetQueryableAsync(cancellationToken)) + .Where(s => + names.AsEnumerable().Contains(s.Name) && + s.ResourceName == resourceName && + s.ResourceKey == resourceKey && + s.ProviderName == providerName && + s.ProviderKey == providerKey + ).ToListAsync(cancellationToken); + } + + public virtual async Task> GetListAsync(string providerName, string providerKey, CancellationToken cancellationToken = default) + { + cancellationToken = GetCancellationToken(cancellationToken); + return await (await GetQueryableAsync(cancellationToken)) + .Where(s => + s.ProviderName == providerName && + s.ProviderKey == providerKey + ).ToListAsync(cancellationToken); + } + + public virtual async Task> GetPermissionsAsync(string resourceName, string resourceKey, CancellationToken cancellationToken = default) + { + cancellationToken = GetCancellationToken(cancellationToken); + return await (await GetQueryableAsync(cancellationToken)) + .Where(s => + s.ResourceName == resourceName && + s.ResourceKey == resourceKey + ).ToListAsync(cancellationToken); + } + + public virtual async Task> GetResourceKeys(string resourceName, string name, CancellationToken cancellationToken = default) + { + cancellationToken = GetCancellationToken(cancellationToken); + return await (await GetQueryableAsync(cancellationToken)) + .Where(s => + s.ResourceName == resourceName && + s.Name == name + ).ToListAsync(cancellationToken); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/PermissionManagementMongoDbContext.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/PermissionManagementMongoDbContext.cs index c62db52c11..c9ea6ea984 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/PermissionManagementMongoDbContext.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/PermissionManagementMongoDbContext.cs @@ -10,6 +10,7 @@ public class PermissionManagementMongoDbContext : AbpMongoDbContext, IPermission public IMongoCollection PermissionGroups => Collection(); public IMongoCollection Permissions => Collection(); public IMongoCollection PermissionGrants => Collection(); + public IMongoCollection ResourcePermissionGrants => Collection(); protected override void CreateModel(IMongoModelBuilder modelBuilder) { 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 baa27b44ff..e20e38c53a 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/AbpPermissionManagementWebModule.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/AbpPermissionManagementWebModule.cs @@ -20,7 +20,7 @@ public class AbpPermissionManagementWebModule : AbpModule { options.AddAssemblyResource( typeof(AbpPermissionManagementResource), - typeof(AbpPermissionManagementWebModule).Assembly, + typeof(AbpPermissionManagementWebModule).Assembly, typeof(AbpPermissionManagementApplicationContractsModule).Assembly ); }); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/AddResourcePermissionManagementModal.cshtml b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/AddResourcePermissionManagementModal.cshtml new file mode 100644 index 0000000000..be12c7cd1d --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/AddResourcePermissionManagementModal.cshtml @@ -0,0 +1,54 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@using Volo.Abp.Localization +@using Volo.Abp.PermissionManagement.Localization +@using Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement +@model AddResourcePermissionManagementModal +@inject IHtmlLocalizer L + +@{ + Layout = null; +} + + + + +
+ + + + + + +
+
+ @foreach (var provider in Model.ResourceProviders.Providers.Select((value, i) => new { i, value })) + { +
+ + +
+ } +
+ + +
+
+

@L["ResourcePermissionPermissions"]

+
+ + +
+ @foreach (var permission in Model.ResourcePermissionDefinitions.Permissions) + { +
+ + +
+ } +
+
+ +
+
diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/AddResourcePermissionManagementModal.cshtml.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/AddResourcePermissionManagementModal.cshtml.cs new file mode 100644 index 0000000000..d9828ee661 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/AddResourcePermissionManagementModal.cshtml.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement; + +public class AddResourcePermissionManagementModal : AbpPageModel +{ + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ResourceName { get; set; } + + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ResourceKey { get; set; } + + [BindProperty(SupportsGet = true)] + [HiddenInput] + public string ResourceDisplayName { get; set; } + + [BindProperty] + public ResourcePermissionViewModel AddModel { get; set; } + + public GetResourcePermissionDefinitionListResultDto ResourcePermissionDefinitions { get; set; } + public GetResourceProviderListResultDto ResourceProviders { get; set; } + + protected IPermissionAppService PermissionAppService { get; } + + public AddResourcePermissionManagementModal(IPermissionAppService permissionAppService) + { + ObjectMapperContext = typeof(AbpPermissionManagementWebModule); + + PermissionAppService = permissionAppService; + } + + public virtual async Task OnGetAsync() + { + ValidateModel(); + + ResourcePermissionDefinitions = await PermissionAppService.GetResourceDefinitionsAsync(ResourceName); + ResourceProviders = await PermissionAppService.GetResourceProviderKeyLookupServicesAsync(ResourceName); + + return Page(); + } + + public virtual async Task OnPostAsync() + { + ValidateModel(); + + await PermissionAppService.UpdateResourceAsync( + ResourceName, + ResourceKey, + new UpdateResourcePermissionsDto() + { + ProviderName = AddModel.ProviderName, + ProviderKey = AddModel.ProviderKey, + Permissions = AddModel.Permissions ?? new List() + } + ); + + return NoContent(); + } + + public class ResourcePermissionViewModel + { + [Required] + public string ProviderName { get; set; } + + [Required] + public string ProviderKey { get; set; } + + public List Permissions { get; set; } + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml index a9caf5c348..c1241af454 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml @@ -79,5 +79,3 @@ - - \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml new file mode 100644 index 0000000000..5717448c70 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml @@ -0,0 +1,52 @@ +@page +@using System.Web; +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@using Volo.Abp.Localization +@using Volo.Abp.PermissionManagement.Localization +@using Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement +@model ResourcePermissionManagementModal +@inject IHtmlLocalizer L + +@{ + Layout = null; +} + +@if(Model.HasAnyResourcePermission && Model.HasAnyResourceProviderKeyLookupService) +{ + + +
+ + + + + +
+ +
+ +
+ +
+
+} +else +{ + + + + + + + +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml.cs new file mode 100644 index 0000000000..1b1373e017 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml.cs @@ -0,0 +1,51 @@ +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement; + +public class ResourcePermissionManagementModal : AbpPageModel +{ + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ResourceName { get; set; } + + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ResourceKey { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ResourceDisplayName { get; set; } + + public bool HasAnyResourcePermission { get; set; } + public bool HasAnyResourceProviderKeyLookupService { get; set; } + + protected IPermissionAppService PermissionAppService { get; } + + public ResourcePermissionManagementModal(IPermissionAppService permissionAppService) + { + ObjectMapperContext = typeof(AbpPermissionManagementWebModule); + + PermissionAppService = permissionAppService; + } + + public virtual async Task OnGetAsync() + { + HasAnyResourcePermission = (await PermissionAppService.GetResourceDefinitionsAsync(ResourceName)).Permissions.Any(); + if (HasAnyResourcePermission) + { + HasAnyResourceProviderKeyLookupService = (await PermissionAppService.GetResourceProviderKeyLookupServicesAsync(ResourceName)).Providers.Count > 0; + } + return Page(); + } + + public virtual Task OnPostAsync() + { + return Task.FromResult(NoContent()); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/UpdateResourcePermissionManagementModal.cshtml b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/UpdateResourcePermissionManagementModal.cshtml new file mode 100644 index 0000000000..59b7f55236 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/UpdateResourcePermissionManagementModal.cshtml @@ -0,0 +1,42 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@using Volo.Abp.Localization +@using Volo.Abp.PermissionManagement.Localization +@using Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement +@model UpdateResourcePermissionManagementModal +@inject IHtmlLocalizer L + +@{ + Layout = null; +} + + + + +
+ + + + + + + +
+

@L["ResourcePermissionPermissions"]

+
+ + +
+ @foreach (var permission in Model.ResourcePermissions.Permissions) + { +
+ + +
+ } +
+
+ +
+
diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/UpdateResourcePermissionManagementModal.cshtml.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/UpdateResourcePermissionManagementModal.cshtml.cs new file mode 100644 index 0000000000..db2e661993 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/UpdateResourcePermissionManagementModal.cshtml.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement; + +public class UpdateResourcePermissionManagementModal : AbpPageModel +{ + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ResourceName { get; set; } + + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ResourceKey { get; set; } + + [BindProperty(SupportsGet = true)] + public string ResourceDisplayName { get; set; } + + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ProviderName { get; set; } + + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ProviderKey { get; set; } + + [BindProperty(SupportsGet = true)] + public ResourcePermissionViewModel UpdateModel { get; set; } + + public GetResourcePermissionWithProviderListResultDto ResourcePermissions { get; set; } + + protected IPermissionAppService PermissionAppService { get; } + + public UpdateResourcePermissionManagementModal(IPermissionAppService permissionAppService) + { + ObjectMapperContext = typeof(AbpPermissionManagementWebModule); + + PermissionAppService = permissionAppService; + } + + public virtual async Task OnGetAsync() + { + ValidateModel(); + + ResourcePermissions = await PermissionAppService.GetResourceByProviderAsync(ResourceName, ResourceKey, ProviderName, ProviderKey); + + return Page(); + } + + public virtual async Task OnPostAsync() + { + ValidateModel(); + + await PermissionAppService.UpdateResourceAsync( + ResourceName, + ResourceKey, + new UpdateResourcePermissionsDto() + { + ProviderName = ProviderName, + ProviderKey = ProviderKey, + Permissions = UpdateModel.Permissions ?? new List() + } + ); + + return NoContent(); + } + + public class ResourcePermissionViewModel + { + public List Permissions { get; set; } + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/add-resource-permission-management-modal.js b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/add-resource-permission-management-modal.js new file mode 100644 index 0000000000..2fa7f06550 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/add-resource-permission-management-modal.js @@ -0,0 +1,91 @@ +var abp = abp || {}; +(function ($) { + var $all = $("#grantAllresourcePermissions"); + var $items = $("#permissionList input[type='checkbox']").not("#grantAllresourcePermissions"); + $all.on("change", function () { + $items.prop("checked", this.checked); + }); + $items.on("change", function () { + $all.prop("checked", $items.length === $items.filter(":checked").length); + }); + + var $permissionManagementForm = $("#addResourcePermissionManagementForm"); + var $providerKey = $("#AddModel_ProviderKey"); + $providerKey.select2({ + ajax: { + url: '/api/permission-management/permissions/search-resource-provider-keys', + delay: 250, + dataType: "json", + data: function (params) { + var query = {}; + query["resourceName"] = $('#ResourceName').val(); + query["serviceName"] = $('input[name="AddModel.ProviderName"]:checked').val(); + query["page"] = params.page || 1; + query["filter"] = params.term; + return query; + }, + processResults: function (data) { + var keyValues = []; + data.keys.forEach(function (item, index) { + keyValues.push({ + id: item["providerKey"], + text: item["providerDisplayName"], + displayName: item["providerDisplayName"] + }) + }); + return { + results: keyValues, + pagination: { + more: keyValues.length == 10 + } + }; + } + }, + width: '100%', + dropdownParent: $('#addResourcePermissionManagementModal'), + language: abp.localization.currentCulture.cultureName + }); + + $('input[name="AddModel.ProviderName"]').change(function () { + $providerKey.val(null).trigger('change'); + }); + + $providerKey.change(function () { + if ($providerKey.val()) { + $permissionManagementForm.valid(); + } + var providerKey = $providerKey.val(); + if (!providerKey) { + $items.prop('checked', false); + $all.prop("checked", false); + return; + } + + abp.ui.setBusy('#permissionList'); + var resourceName = $("#ResourceName").val(); + var resourceKey = $("#ResourceKey").val(); + var providerName = $('input[name="AddModel.ProviderName"]:checked').val(); + volo.abp.permissionManagement.permissions.getResourceByProvider(resourceName, resourceKey, providerName, providerKey).then(function (result) { + abp.ui.clearBusy(); + var grantedPermissionNames = result.permissions.filter(function (p) { + return p.providers.indexOf(providerName) >= 0 && p.isGranted === true; + }).map(function (p) { + return p.name; + }); + $items.each(function () { + var $checkbox = $(this); + if (grantedPermissionNames.indexOf($checkbox.val()) >= 0) { + $checkbox.prop('checked', true); + } else { + $checkbox.prop('checked', false); + } + }); + $all.prop("checked", $items.length === $items.filter(":checked").length); + }); + }); + + $permissionManagementForm.submit(function () { + $(this).valid(); + }); + +})(jQuery); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/resource-permission-management-modal.js b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/resource-permission-management-modal.js new file mode 100644 index 0000000000..7a6c100c07 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/resource-permission-management-modal.js @@ -0,0 +1,131 @@ +var abp = abp || {}; +(function ($) { + var l = abp.localization.getResource('AbpPermissionManagement'); + var _dataTable = null; + abp.ui.extensions.entityActions.get('permissionManagement.resource').addContributor( + function (actionList) { + return actionList.addManyTail( + [ + { + text: l('Edit'), + action: function (data) { + var _updateResourcePermissionsModal = new abp.ModalManager(abp.appPath + "AbpPermissionManagement/UpdateResourcePermissionManagementModal"); + _updateResourcePermissionsModal.open({ + resourceName: $("#ResourceName").val(), + resourceKey: $("#ResourceKey").val(), + resourceDisplayName: $("#ResourceDisplayName").val(), + providerName: data.record.providerName, + providerKey: data.record.providerKey + }); + _updateResourcePermissionsModal.onResult(function () { + _dataTable.ajax.reloadEx(function (json) { + _dataTable.columns.adjust(); + }); + }); + }, + }, + { + text: l('Delete'), + confirmMessage: function (data) { + return l( + 'ResourcePermissionDeletionConfirmationMessage', + data.record.name + ); + }, + action: function (data) { + volo.abp.permissionManagement.permissions.deleteResource($("#ResourceName").val(), $("#ResourceKey").val(), data.record.providerName, data.record.providerKey).then(function () { + abp.notify.info(l('DeletedSuccessfully')); + _dataTable.ajax.reloadEx(function (json) { + _dataTable.columns.adjust(); + }); + }); + }, + } + ] + ); + } + ); + + abp.ui.extensions.tableColumns.get('permissionManagement.resource').addContributor( + function (columnList) { + columnList.addManyTail( + [ + { + title: l("Actions"), + rowAction: { + items: abp.ui.extensions.entityActions.get('permissionManagement.resource').actions.toArray() + } + }, + { + title: l("ResourcePermissionTarget"), + data: 'providerName', + render: function (data, type, row) { + return '' + row.providerName + '' + row.providerDisplayName; + }, + }, + { + title: l("ResourcePermissionPermissions"), + data: 'permissions', + render: function (data, type, row) { + var spans = ''; + for (var i = 0; i < row.permissions.length; i++) { + spans += '' + row.permissions[i].displayName + ''; + } + return spans; + }, + } + ] + ); + }, + 0 //adds as the first contributor + ); + + abp.modals = abp.modals || {}; + + abp.modals.ResourcePermissionManagement = function () { + var initModal = function (publicApi, args) { + _dataTable = $('#resourcePermissionTable').DataTable( + abp.libs.datatables.normalizeConfiguration({ + order: [], + searching: false, + processing: true, + scrollX: false, + serverSide: false, + paging: true, + ajax: function () { + return function (requestData, callback, settings) { + if (callback) { + volo.abp.permissionManagement.permissions.getResource(args.resourceName, args.resourceKey).then(function (result) { + callback({ + recordsTotal: result.permissions.length, + recordsFiltered: result.permissions.length, + data: result.permissions + }); + }); + } + } + }(), + columnDefs: abp.ui.extensions.tableColumns.get('permissionManagement.resource').columns.toArray(), + }) + ); + + $("#addPermission").click(function () { + var _addResourcePermissionsModal = new abp.ModalManager(abp.appPath + "AbpPermissionManagement/AddResourcePermissionManagementModal"); + _addResourcePermissionsModal.open({ + resourceName: $("#ResourceName").val(), + resourceKey: $("#ResourceKey").val(), + resourceDisplayName: $("#ResourceDisplayName").val() + }); + _addResourcePermissionsModal.onResult(function () { + _dataTable.ajax.reloadEx(function (json) { + _dataTable.columns.adjust(); + }); + }); + }); + }; + + return { + initModal: initModal, + }; + }; +})(jQuery); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/update-resource-permission-management-modal.js b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/update-resource-permission-management-modal.js new file mode 100644 index 0000000000..d1e1f02fa4 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/update-resource-permission-management-modal.js @@ -0,0 +1,11 @@ +var abp = abp || {}; +(function ($) { + var $all = $("#grantAllresourcePermissions"); + var $items = $("#permissionList input[type='checkbox']").not("#grantAllresourcePermissions"); + $all.on("change", function () { + $items.prop("checked", this.checked); + }); + $items.on("change", function () { + $all.prop("checked", $items.length === $items.filter(":checked").length); + }); +})(jQuery); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/wwwroot/client-proxies/permissionManagement-proxy.js b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/wwwroot/client-proxies/permissionManagement-proxy.js index a296877917..893c86ab97 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/wwwroot/client-proxies/permissionManagement-proxy.js +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/wwwroot/client-proxies/permissionManagement-proxy.js @@ -34,6 +34,58 @@ }, ajaxParams)); }; + volo.abp.permissionManagement.permissions.getResourceProviderKeyLookupServices = function(resourceName, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/permission-management/permissions/resource-provider-key-lookup-services' + abp.utils.buildQueryString([{ name: 'resourceName', value: resourceName }]) + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.abp.permissionManagement.permissions.searchResourceProviderKey = function(resourceName, serviceName, filter, page, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/permission-management/permissions/search-resource-provider-keys' + abp.utils.buildQueryString([{ name: 'resourceName', value: resourceName }, { name: 'serviceName', value: serviceName }, { name: 'filter', value: filter }, { name: 'page', value: page }]) + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.abp.permissionManagement.permissions.getResourceDefinitions = function(resourceName, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/permission-management/permissions/resource-definitions' + abp.utils.buildQueryString([{ name: 'resourceName', value: resourceName }]) + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.abp.permissionManagement.permissions.getResource = function(resourceName, resourceKey, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/permission-management/permissions/resource' + abp.utils.buildQueryString([{ name: 'resourceName', value: resourceName }, { name: 'resourceKey', value: resourceKey }]) + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.abp.permissionManagement.permissions.getResourceByProvider = function(resourceName, resourceKey, providerName, providerKey, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/permission-management/permissions/resource/by-provider' + abp.utils.buildQueryString([{ name: 'resourceName', value: resourceName }, { name: 'resourceKey', value: resourceKey }, { name: 'providerName', value: providerName }, { name: 'providerKey', value: providerKey }]) + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.abp.permissionManagement.permissions.updateResource = function(resourceName, resourceKey, input, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/permission-management/permissions/resource' + abp.utils.buildQueryString([{ name: 'resourceName', value: resourceName }, { name: 'resourceKey', value: resourceKey }]) + '', + type: 'PUT', + dataType: null, + data: JSON.stringify(input) + }, ajaxParams)); + }; + + volo.abp.permissionManagement.permissions.deleteResource = function(resourceName, resourceKey, providerName, providerKey, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/permission-management/permissions/resource' + abp.utils.buildQueryString([{ name: 'resourceName', value: resourceName }, { name: 'resourceKey', value: resourceKey }, { name: 'providerName', value: providerName }, { name: 'providerKey', value: providerKey }]) + '', + type: 'DELETE', + dataType: null + }, ajaxParams)); + }; + })(); })(); diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementApplicationTestModule.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementApplicationTestModule.cs index a5e8461a28..e43cc0fa71 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementApplicationTestModule.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementApplicationTestModule.cs @@ -22,6 +22,7 @@ public class AbpPermissionManagementApplicationTestModule : AbpModule options.ProviderPolicies[UserPermissionValueProvider.ProviderName] = UserPermissionValueProvider.ProviderName; options.ProviderPolicies["Test"] = "Test"; options.ManagementProviders.Add(); + options.ResourceManagementProviders.Add(); }); } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs index 11e9e8ca04..61f984a27b 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs @@ -32,34 +32,39 @@ public class PermissionAppService_Tests : AbpPermissionManagementApplicationTest permissionListResultDto.ShouldNotBeNull(); permissionListResultDto.EntityDisplayName.ShouldBe(PermissionTestDataBuilder.User1Id.ToString()); - permissionListResultDto.Groups.Count.ShouldBe(2); + + permissionListResultDto.Groups.Count.ShouldBe(3); permissionListResultDto.Groups.ShouldContain(x => x.Name == "TestGroup"); - permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission1"); - permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission2"); - permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission2.ChildPermission1"); - permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission3"); - permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission4"); + var testGroup = permissionListResultDto.Groups.FirstOrDefault(g => g.Name == "TestGroup"); + testGroup.ShouldNotBeNull(); + testGroup.Permissions.ShouldContain(x => x.Name == "MyPermission1"); + testGroup.Permissions.ShouldContain(x => x.Name == "MyPermission2"); + testGroup.Permissions.ShouldContain(x => x.Name == "MyPermission2.ChildPermission1"); + testGroup.Permissions.ShouldContain(x => x.Name == "MyPermission3"); + testGroup.Permissions.ShouldContain(x => x.Name == "MyPermission4"); - permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyPermission5"); - permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyPermission5.ChildPermission1"); + testGroup.Permissions.ShouldNotContain(x => x.Name == "MyPermission5"); + testGroup.Permissions.ShouldNotContain(x => x.Name == "MyPermission5.ChildPermission1"); using (_currentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "super-admin"))) { var result = await _permissionAppService.GetAsync(UserPermissionValueProvider.ProviderName, PermissionTestDataBuilder.User1Id.ToString()); - result.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission5"); - result.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission5.ChildPermission1"); + var testGroupWithRole = result.Groups.FirstOrDefault(g => g.Name == "TestGroup"); + testGroupWithRole.ShouldNotBeNull(); + testGroupWithRole.Permissions.ShouldContain(x => x.Name == "MyPermission5"); + testGroupWithRole.Permissions.ShouldContain(x => x.Name == "MyPermission5.ChildPermission1"); } - permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission6"); - permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyPermission6.ChildDisabledPermission1"); - permissionListResultDto.Groups.First().Permissions.ShouldContain(x => x.Name == "MyPermission6.ChildPermission2"); + testGroup.Permissions.ShouldContain(x => x.Name == "MyPermission6"); + testGroup.Permissions.ShouldNotContain(x => x.Name == "MyPermission6.ChildDisabledPermission1"); + testGroup.Permissions.ShouldContain(x => x.Name == "MyPermission6.ChildPermission2"); - permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission1"); - permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission2"); - permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission2.ChildPermission1"); - permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission2.ChildPermission2"); - permissionListResultDto.Groups.First().Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission2.ChildPermission2.ChildPermission1"); + testGroup.Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission1"); + testGroup.Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission2"); + testGroup.Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission2.ChildPermission1"); + testGroup.Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission2.ChildPermission2"); + testGroup.Permissions.ShouldNotContain(x => x.Name == "MyDisabledPermission2.ChildPermission2.ChildPermission1"); } [Fact] diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/CalculateHash_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/CalculateHash_Tests.cs index 2e862c8f85..cfec0d27a2 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/CalculateHash_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/CalculateHash_Tests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization.Metadata; using Shouldly; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Json.SystemTextJson.Modifiers; using Xunit; @@ -34,7 +35,7 @@ public class CalculateHash_Tests: PermissionTestBase json.ShouldNotContain(id.ToString("D")); json = JsonSerializer.Serialize(new List() { - new PermissionDefinitionRecord(id, "Test", "Test", "Test", "Test") + new PermissionDefinitionRecord(id, "Test", "Test", "Test", "Test", "Test", "Test") }, jsonSerializerOptions); json.ShouldNotContain("\"Id\""); 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..4dca621a63 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,48 @@ 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, + "Permission1", + 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.ManagementPermissionName.ShouldBe("Permission1"); + 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 +127,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/ResourcePermissionChecker_Basic_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionChecker_Basic_Tests.cs new file mode 100644 index 0000000000..81ba38f7f9 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionChecker_Basic_Tests.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions.Resources; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionChecker_Basic_Tests : PermissionTestBase +{ + private readonly IResourcePermissionChecker _resourcePermissionChecker; + + public ResourcePermissionChecker_Basic_Tests() + { + _resourcePermissionChecker = GetRequiredService(); + } + + [Fact] + public async Task Should_Return_Prohibited_If_Permission_Is_Not_Defined() + { + (await _resourcePermissionChecker.IsGrantedAsync(TestEntityResource.ResourceName, TestEntityResource.ResourceKey1,"UndefinedResourcePermissionName")).ShouldBeFalse(); + } + + [Fact] + public async Task Should_Return_False_As_Default_For_Any_Permission() + { + (await _resourcePermissionChecker.IsGrantedAsync(TestEntityResource.ResourceName, TestEntityResource.ResourceKey1,"MyPermission1")).ShouldBeFalse(); + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionChecker_User_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionChecker_User_Tests.cs new file mode 100644 index 0000000000..261b5136d2 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionChecker_User_Tests.cs @@ -0,0 +1,121 @@ +using System; +using System.Security.Claims; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Security.Claims; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionChecker_User_Tests : PermissionTestBase +{ + private readonly IResourcePermissionChecker _resourcePermissionChecker; + private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor; + + public ResourcePermissionChecker_User_Tests() + { + _resourcePermissionChecker = GetRequiredService(); + _currentPrincipalAccessor = GetRequiredService(); + } + + [Fact] + public async Task Should_Return_True_For_Granted_Current_User() + { + (await _resourcePermissionChecker.IsGrantedAsync( + CreatePrincipal(PermissionTestDataBuilder.User1Id), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1 + )).ShouldBeTrue(); + } + + [Fact] + public async Task Should_Return_False_For_Non_Granted_Current_User() + { + (await _resourcePermissionChecker.IsGrantedAsync( + CreatePrincipal(PermissionTestDataBuilder.User2Id), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1 + )).ShouldBeFalse(); + } + + + [Fact] + public async Task Should_Return_False_For_Granted_Current_User_If_The_Permission_Is_Disabled() + { + //Disabled permissions always returns false! + (await _resourcePermissionChecker.IsGrantedAsync( + CreatePrincipal(PermissionTestDataBuilder.User1Id), + "MyDisabledPermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1 + )).ShouldBeFalse(); + } + + [Fact] + public async Task Should_Return_False_For_Current_User_If_Anonymous() + { + (await _resourcePermissionChecker.IsGrantedAsync( + CreatePrincipal(null), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1 + )).ShouldBeFalse(); + } + + [Fact] + public async Task Should_Not_Allow_Host_Permission_To_Tenant_User_Even_Granted_Before() + { + (await _resourcePermissionChecker.IsGrantedAsync( + CreatePrincipal(PermissionTestDataBuilder.User1Id, Guid.NewGuid()), + "MyResourcePermission3", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey3 + )).ShouldBeFalse(); + } + + [Fact] + public async Task Should_Return_False_For_Granted_Current_User_If_The_Permission_State_Is_Disabled() + { + (await _resourcePermissionChecker.IsGrantedAsync( + CreatePrincipal(PermissionTestDataBuilder.User1Id, Guid.NewGuid()), + "MyResourcePermission5", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey5 + )).ShouldBeFalse(); + } + + [Fact] + public async Task Should_Return_True_For_Granted_Current_User_If_The_Permission_State_Is_Enabled() + { + using (_currentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "super-admin"))) + { + (await _resourcePermissionChecker.IsGrantedAsync( + CreatePrincipal(PermissionTestDataBuilder.User1Id, Guid.NewGuid()), + "MyResourcePermission5", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey5 + )).ShouldBeTrue(); + } + } + + private static ClaimsPrincipal CreatePrincipal(Guid? userId, Guid? tenantId = null) + { + var claimsIdentity = new ClaimsIdentity(); + + if (userId != null) + { + claimsIdentity.AddClaim(new Claim(AbpClaimTypes.UserId, userId.ToString())); + } + + if (tenantId != null) + { + claimsIdentity.AddClaim(new Claim(AbpClaimTypes.TenantId, tenantId.ToString())); + } + + return new ClaimsPrincipal(claimsIdentity); + } +} 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 new file mode 100644 index 0000000000..3bdc4ee69e --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItemInvalidator_Tests.cs @@ -0,0 +1,69 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Caching; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionGrantCacheItemInvalidator_Tests : PermissionTestBase +{ + private readonly IDistributedCache _cache; + private readonly IResourcePermissionStore _resourcePermissionStore; + private readonly IResourcePermissionGrantRepository _resourcePermissionGrantRepository; + + public ResourcePermissionGrantCacheItemInvalidator_Tests() + { + _cache = GetRequiredService>(); + _resourcePermissionStore = GetRequiredService(); + _resourcePermissionGrantRepository = GetRequiredService(); + } + + [Fact] + public async Task PermissionStore_IsGrantedAsync_Should_Cache_PermissionGrant() + { + (await _cache.GetAsync(ResourcePermissionGrantCacheItem.CalculateCacheKey("MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()))).ShouldBeNull(); + + await _resourcePermissionStore.IsGrantedAsync("MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()); + + (await _cache.GetAsync(ResourcePermissionGrantCacheItem.CalculateCacheKey("MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()))).ShouldNotBeNull(); + } + + [Fact] + public async Task Cache_Should_Invalidator_WhenPermissionGrantChanged() + { + // IsGrantedAsync will cache ResourcePermissionGrant + await _resourcePermissionStore.IsGrantedAsync("MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()); + + var resourcePermissionGrant = await _resourcePermissionGrantRepository.FindAsync("MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()); + resourcePermissionGrant.ShouldNotBeNull(); + await _resourcePermissionGrantRepository.DeleteAsync(resourcePermissionGrant); + + (await _cache.GetAsync(ResourcePermissionGrantCacheItem.CalculateCacheKey("MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()))).ShouldBeNull(); + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItem_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItem_Tests.cs new file mode 100644 index 0000000000..1d7b4ea12d --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionGrantCacheItem_Tests.cs @@ -0,0 +1,15 @@ +using Shouldly; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionGrantCacheItem_Tests +{ + [Fact] + public void GetPermissionNameFormCacheKeyOrNull() + { + var key = ResourcePermissionGrantCacheItem.CalculateCacheKey("aaa", TestEntityResource.ResourceName, TestEntityResource.ResourceKey1,"bbb", "ccc"); + ResourcePermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(key).ShouldBe("aaa"); + ResourcePermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull("aaabbbccc").ShouldBeNull(); + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManagementProvider_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManagementProvider_Tests.cs new file mode 100644 index 0000000000..9651c3f313 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManagementProvider_Tests.cs @@ -0,0 +1,90 @@ +using System; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionManagementProvider_Tests : PermissionTestBase +{ + private readonly IResourcePermissionManagementProvider _resourcePermissionManagementProvider; + private readonly IResourcePermissionGrantRepository _resourcePermissionGrantRepository; + + public ResourcePermissionManagementProvider_Tests() + { + _resourcePermissionManagementProvider = GetRequiredService(); + _resourcePermissionGrantRepository = GetRequiredService(); + } + + [Fact] + public async Task CheckAsync() + { + await _resourcePermissionGrantRepository.InsertAsync( + new ResourcePermissionGrant( + Guid.NewGuid(), + "MyPermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test" + ) + ); + + var permissionValueProviderGrantInfo = await _resourcePermissionManagementProvider.CheckAsync( + "MyPermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test"); + + permissionValueProviderGrantInfo.IsGranted.ShouldBeTrue(); + permissionValueProviderGrantInfo.ProviderKey.ShouldBe("Test"); + } + + [Fact] + public async Task Check_Should_Return_NonGranted_When_ProviderName_NotEquals_Name() + { + var permissionValueProviderGrantInfo = await _resourcePermissionManagementProvider.CheckAsync( + "MyPermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "TestNotExist", + "Test"); + + permissionValueProviderGrantInfo.IsGranted.ShouldBeFalse(); + permissionValueProviderGrantInfo.ProviderKey.ShouldBeNull(); + } + + [Fact] + public async Task SetAsync() + { + await _resourcePermissionGrantRepository.InsertAsync( + new ResourcePermissionGrant( + Guid.NewGuid(), + "MyPermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test" + ) + ); + (await _resourcePermissionGrantRepository.FindAsync("MyPermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test")).ShouldNotBeNull(); + + await _resourcePermissionManagementProvider.SetAsync("MyPermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + false); + + (await _resourcePermissionGrantRepository.FindAsync("MyPermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test")).ShouldBeNull(); + } +} 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 new file mode 100644 index 0000000000..73d37a5ff3 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManager_Tests.cs @@ -0,0 +1,337 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionManager_Tests : PermissionTestBase +{ + private readonly IResourcePermissionManager _resourcePermissionManager; + private readonly IResourcePermissionGrantRepository _resourcePermissionGrantRepository; + + public ResourcePermissionManager_Tests() + { + _resourcePermissionManager = GetRequiredService(); + _resourcePermissionGrantRepository = GetRequiredService(); + } + + [Fact] + public async Task GetProviderKeyLookupServicesAsync() + { + var permissionProviderKeyLookupServices = await _resourcePermissionManager.GetProviderKeyLookupServicesAsync(); + + permissionProviderKeyLookupServices.ShouldNotBeNull(); + permissionProviderKeyLookupServices.First().Name.ShouldBe("Test"); + } + + [Fact] + public async Task GetProviderKeyLookupServiceAsync() + { + var testProviderKeyLookupService = await _resourcePermissionManager.GetProviderKeyLookupServiceAsync("Test"); + testProviderKeyLookupService.ShouldNotBeNull(); + testProviderKeyLookupService.Name.ShouldBe("Test"); + + var exception = await Assert.ThrowsAsync(async () => + { + await _resourcePermissionManager.GetProviderKeyLookupServiceAsync("UndefinedProvider"); + }); + exception.Message.ShouldBe("Unknown resource permission provider key lookup service: UndefinedProvider"); + } + + [Fact] + public async Task GetAvailablePermissionsAsync() + { + var availablePermissions = await _resourcePermissionManager.GetAvailablePermissionsAsync(TestEntityResource.ResourceName); + + availablePermissions.ShouldNotBeNull(); + availablePermissions.ShouldContain(p => p.Name == "MyResourcePermission1"); + availablePermissions.ShouldContain(p => p.Name == "MyResourcePermission2"); + availablePermissions.ShouldContain(p => p.Name == "MyResourcePermission3"); + availablePermissions.ShouldContain(p => p.Name == "MyResourcePermission4"); + availablePermissions.ShouldContain(p => p.Name == "MyResourcePermission6"); + availablePermissions.ShouldContain(p => p.Name == "MyResourcePermission7"); + + availablePermissions.ShouldNotContain(p => p.Name == "MyResourcePermission5"); + availablePermissions.ShouldNotContain(p => p.Name == "MyResourceDisabledPermission1"); + availablePermissions.ShouldNotContain(p => p.Name == "MyResourceDisabledPermission2"); + } + + [Fact] + public async Task GetAsync() + { + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test") + ); + + var grantedProviders = await _resourcePermissionManager.GetAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test"); + + grantedProviders.ShouldNotBeNull(); + grantedProviders.IsGranted.ShouldBeTrue(); + grantedProviders.Name.ShouldBe("MyResourcePermission1"); + grantedProviders.Providers.ShouldContain(x => x.Key == "Test"); + } + + [Fact] + public async Task Multiple_GetAsync() + { + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test") + ); + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission2", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test") + ); + + var grantedProviders = await _resourcePermissionManager.GetAsync( + new[] { "MyResourcePermission1", "MyResourcePermission2" }, + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test"); + + grantedProviders.Result.Count.ShouldBe(2); + grantedProviders.Result.First().IsGranted.ShouldBeTrue(); + grantedProviders.Result.First().Name.ShouldBe("MyResourcePermission1"); + grantedProviders.Result.First().Providers.ShouldContain(x => x.Key == "Test"); + + grantedProviders.Result.Last().IsGranted.ShouldBeTrue(); + grantedProviders.Result.Last().Name.ShouldBe("MyResourcePermission2"); + grantedProviders.Result.Last().Providers.ShouldContain(x => x.Key == "Test"); + } + + [Fact] + public async Task Get_Should_Return_Not_Granted_When_Permission_Undefined() + { + var result = await _resourcePermissionManager.GetAsync( + "MyResourcePermission1NotExist", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1,"Test", "Test"); + result.Name.ShouldBe("MyResourcePermission1NotExist"); + result.Providers.ShouldBeEmpty(); + result.IsGranted.ShouldBeFalse(); + } + + [Fact] + public async Task GetAllAsync() + { + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test") + ); + + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission2", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test") + ); + + var permissionWithGrantedProviders = await _resourcePermissionManager.GetAllAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test"); + + permissionWithGrantedProviders.ShouldNotBeNull(); + permissionWithGrantedProviders.ShouldContain(x => + x.IsGranted && x.Name == "MyResourcePermission1" && x.Providers.Any(p => p.Key == "Test")); + permissionWithGrantedProviders.ShouldContain(x => + x.IsGranted && x.Name == "MyResourcePermission2" && x.Providers.Any(p => p.Key == "Test")); + + + permissionWithGrantedProviders = await _resourcePermissionManager.GetAllAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1); + + permissionWithGrantedProviders.ShouldNotBeNull(); + permissionWithGrantedProviders.ShouldContain(x => x.IsGranted && x.Name == "MyResourcePermission1" && x.Providers.Any(p => p.Key == "Test")); + permissionWithGrantedProviders.ShouldContain(x => x.IsGranted && x.Name == "MyResourcePermission2" && x.Providers.Any(p => p.Key == "Test")); + + permissionWithGrantedProviders.ShouldNotContain(x => x.Name == "MyResourcePermission5"); // Not available permission + + permissionWithGrantedProviders.ShouldContain(x => !x.IsGranted && x.Name == "MyResourcePermission3" && x.Providers.Count == 0); + permissionWithGrantedProviders.ShouldContain(x => !x.IsGranted && x.Name == "MyResourcePermission4" && x.Providers.Count == 0); + permissionWithGrantedProviders.ShouldContain(x => !x.IsGranted && x.Name == "MyResourcePermission6" && x.Providers.Count == 0); + permissionWithGrantedProviders.ShouldContain(x => !x.IsGranted && x.Name == "MyResourcePermission7" && x.Providers.Count == 0); + permissionWithGrantedProviders.ShouldContain(x => !x.IsGranted && x.Name == "MyResourcePermission8" && x.Providers.Count == 0); + } + + [Fact] + public async Task GetAllGroupAsync() + { + var group = await _resourcePermissionManager.GetAllGroupAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1); + + group.ShouldNotBeNull(); + group.Count.ShouldBe(1); + group.First().ProviderName.ShouldBe(UserResourcePermissionValueProvider.ProviderName); + group.First().ProviderKey.ShouldBe(PermissionTestDataBuilder.User1Id.ToString()); + group.First().Permissions.Count.ShouldBe(1); + group.First().Permissions.ShouldContain(x => x == "MyResourcePermission1"); + + group = await _resourcePermissionManager.GetAllGroupAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey3); + + group.ShouldNotBeNull(); + group.Count.ShouldBe(1); + group.First().ProviderName.ShouldBe(UserResourcePermissionValueProvider.ProviderName); + group.First().ProviderKey.ShouldBe(PermissionTestDataBuilder.User1Id.ToString()); + group.First().Permissions.Count.ShouldBe(2); + group.First().Permissions.ShouldContain(x => x == "MyResourcePermission3"); + group.First().Permissions.ShouldContain(x => x == "MyResourcePermission6"); + } + + [Fact] + public async Task Set_Should_Silently_Ignore_When_Permission_Undefined() + { + await _resourcePermissionManager.SetAsync( + "MyResourcePermission1NotExist", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test", + true); + } + + [Fact] + public async Task Set_Should_Throw_Exception_If_Provider_Not_Found() + { + var exception = await Assert.ThrowsAsync(async () => + { + await _resourcePermissionManager.SetAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "UndefinedProvider", + "Test", + true); + }); + + exception.Message.ShouldBe("Unknown resource permission management provider: UndefinedProvider"); + } + + [Fact] + public async Task UpdateProviderKey() + { + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test") + ); + var permissionGrant = await _resourcePermissionGrantRepository.FindAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test"); + permissionGrant.ProviderKey.ShouldBe("Test"); + + await _resourcePermissionManager.UpdateProviderKeyAsync(permissionGrant, "NewProviderKey"); + (await _resourcePermissionGrantRepository.FindAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "NewProviderKey")).ShouldNotBeNull(); + } + + [Fact] + public async Task DeleteAsync() + { + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test") + ); + var permissionGrant = await _resourcePermissionGrantRepository.FindAsync("MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test"); + permissionGrant.ProviderKey.ShouldBe("Test"); + + await _resourcePermissionManager.DeleteAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test"); + + (await _resourcePermissionGrantRepository.FindAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test")).ShouldBeNull(); + } + + [Fact] + public async Task DeleteByProviderAsync() + { + await _resourcePermissionGrantRepository.InsertAsync(new ResourcePermissionGrant( + Guid.NewGuid(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test") + ); + + var permissionGrant = await _resourcePermissionGrantRepository.FindAsync("MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test"); + + permissionGrant.ProviderKey.ShouldBe("Test"); + + await _resourcePermissionManager.DeleteAsync( + "Test", + "Test"); + + (await _resourcePermissionGrantRepository.FindAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Test", + "Test")).ShouldBeNull(); + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionStore_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionStore_Tests.cs new file mode 100644 index 0000000000..34e6f89c0c --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionStore_Tests.cs @@ -0,0 +1,119 @@ +using System.Linq; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Authorization.Permissions.Resources; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public class ResourcePermissionStore_Tests : PermissionTestBase +{ + private readonly IResourcePermissionStore _resourcePermissionStore; + + public ResourcePermissionStore_Tests() + { + _resourcePermissionStore = GetRequiredService(); + } + + [Fact] + public async Task IsGrantedAsync() + { + (await _resourcePermissionStore.IsGrantedAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString())).ShouldBeTrue(); + + (await _resourcePermissionStore.IsGrantedAsync( + "MyPermission1NotExist", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString())).ShouldBeFalse(); + } + + [Fact] + public async Task IsGranted_Multiple() + { + var result = await _resourcePermissionStore.IsGrantedAsync( + new[] { "MyResourcePermission1", "MyResourcePermission1NotExist" }, + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()); + + result.Result.Count.ShouldBe(2); + + result.Result.FirstOrDefault(x => x.Key == "MyResourcePermission1").Value.ShouldBe(PermissionGrantResult.Granted); + result.Result.FirstOrDefault(x => x.Key == "MyResourcePermission1NotExist").Value.ShouldBe(PermissionGrantResult.Undefined); + } + + + [Fact] + public async Task GetPermissionsAsync() + { + var permissions = await _resourcePermissionStore.GetPermissionsAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1); + + permissions.Result.Count.ShouldBe(10); + permissions.Result.ShouldContain(p => p.Key == "MyResourcePermission1" && p.Value == PermissionGrantResult.Granted); + permissions.Result.ShouldContain(p => p.Key == "MyResourceDisabledPermission1" && p.Value == PermissionGrantResult.Undefined); + permissions.Result.ShouldContain(p => p.Key == "MyResourcePermission2" && p.Value == PermissionGrantResult.Undefined); + permissions.Result.ShouldContain(p => p.Key == "MyResourcePermission3" && p.Value == PermissionGrantResult.Undefined); + permissions.Result.ShouldContain(p => p.Key == "MyResourcePermission4" && p.Value == PermissionGrantResult.Undefined); + permissions.Result.ShouldContain(p => p.Key == "MyResourcePermission5" && p.Value == PermissionGrantResult.Undefined); + permissions.Result.ShouldContain(p => p.Key == "MyResourcePermission6" && p.Value == PermissionGrantResult.Undefined); + permissions.Result.ShouldContain(p => p.Key == "MyResourceDisabledPermission2" && p.Value == PermissionGrantResult.Undefined); + permissions.Result.ShouldContain(p => p.Key == "MyResourcePermission7" && p.Value == PermissionGrantResult.Undefined); + permissions.Result.ShouldContain(p => p.Key == "MyResourcePermission8" && p.Value == PermissionGrantResult.Undefined); + + permissions = await _resourcePermissionStore.GetPermissionsAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey2); + permissions.Result.ShouldAllBe(x => x.Value == PermissionGrantResult.Undefined); + } + + [Fact] + public async Task GetGrantedPermissionsAsync() + { + var grantedPermissions = await _resourcePermissionStore.GetGrantedPermissionsAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1); + + grantedPermissions.Length.ShouldBe(1); + grantedPermissions.ShouldContain("MyResourcePermission1"); + + grantedPermissions = await _resourcePermissionStore.GetGrantedPermissionsAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey3); + + grantedPermissions.Length.ShouldBe(3); + grantedPermissions.ShouldContain("MyResourcePermission3"); + grantedPermissions.ShouldContain("MyResourcePermission5"); + grantedPermissions.ShouldContain("MyResourcePermission6"); + + } + + + [Fact] + public async Task GetGrantedResourceKeysAsync() + { + var grantedResourceKeys = await _resourcePermissionStore.GetGrantedResourceKeysAsync( + TestEntityResource.ResourceName, + "MyResourcePermission1"); + + grantedResourceKeys.Length.ShouldBe(1); + grantedResourceKeys.ShouldContain(TestEntityResource.ResourceKey1); + + grantedResourceKeys = await _resourcePermissionStore.GetGrantedResourceKeysAsync( + TestEntityResource.ResourceName, + "MyResourcePermission5"); + + grantedResourceKeys.Length.ShouldBe(2); + grantedResourceKeys.ShouldContain(TestEntityResource.ResourceKey3); + grantedResourceKeys.ShouldContain(TestEntityResource.ResourceKey5); + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/ResourcePermissionGrantRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/ResourcePermissionGrantRepository_Tests.cs new file mode 100644 index 0000000000..89fdb9a9d4 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/ResourcePermissionGrantRepository_Tests.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.PermissionManagement.EntityFrameworkCore; + +public class ResourcePermissionGrantRepository_Tests : ResourcePermissionGrantRepository_Tests +{ + +} 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.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/ResourcePermissionGrantRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/ResourcePermissionGrantRepository_Tests.cs new file mode 100644 index 0000000000..32240f998c --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/ResourcePermissionGrantRepository_Tests.cs @@ -0,0 +1,9 @@ +using Xunit; + +namespace Volo.Abp.PermissionManagement.MongoDB; + +[Collection(MongoTestCollection.Name)] +public class ResourcePermissionGrantRepository_Tests : ResourcePermissionGrantRepository_Tests +{ + +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/AbpPermissionManagementTestBaseModule.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/AbpPermissionManagementTestBaseModule.cs index a6102a318e..88c6ea1d69 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/AbpPermissionManagementTestBaseModule.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/AbpPermissionManagementTestBaseModule.cs @@ -18,6 +18,8 @@ public class AbpPermissionManagementTestBaseModule : AbpModule context.Services.Configure(options => { options.ManagementProviders.Add(); + options.ResourceManagementProviders.Add(); + options.ResourcePermissionProviderKeyLookupServices.Add(); }); } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionTestDataBuilder.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionTestDataBuilder.cs index c60dff997a..d0448ea5bd 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionTestDataBuilder.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/PermissionTestDataBuilder.cs @@ -12,12 +12,17 @@ public class PermissionTestDataBuilder : ITransientDependency public static Guid User2Id { get; } = Guid.NewGuid(); private readonly IPermissionGrantRepository _permissionGrantRepository; + private readonly IResourcePermissionGrantRepository _resourcePermissionGrantRepository; private readonly IGuidGenerator _guidGenerator; - public PermissionTestDataBuilder(IGuidGenerator guidGenerator, IPermissionGrantRepository permissionGrantRepository) + public PermissionTestDataBuilder( + IGuidGenerator guidGenerator, + IPermissionGrantRepository permissionGrantRepository, + IResourcePermissionGrantRepository resourcePermissionGrantRepository) { _guidGenerator = guidGenerator; _permissionGrantRepository = permissionGrantRepository; + _resourcePermissionGrantRepository = resourcePermissionGrantRepository; } public async Task BuildAsync() @@ -31,6 +36,15 @@ public class PermissionTestDataBuilder : ITransientDependency ) ); + await _permissionGrantRepository.InsertAsync( + new PermissionGrant( + _guidGenerator.Create(), + "TestEntityManagementPermission", + UserPermissionValueProvider.ProviderName, + User1Id.ToString() + ) + ); + await _permissionGrantRepository.InsertAsync( new PermissionGrant( _guidGenerator.Create(), @@ -57,5 +71,71 @@ public class PermissionTestDataBuilder : ITransientDependency User1Id.ToString() ) ); + + await _resourcePermissionGrantRepository.InsertAsync( + new ResourcePermissionGrant( + _guidGenerator.Create(), + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + User1Id.ToString() + ) + ); + + await _resourcePermissionGrantRepository.InsertAsync( + new ResourcePermissionGrant( + _guidGenerator.Create(), + "MyDisabledResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + User1Id.ToString() + ) + ); + + await _resourcePermissionGrantRepository.InsertAsync( + new ResourcePermissionGrant( + _guidGenerator.Create(), + "MyResourcePermission3", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey3, + UserPermissionValueProvider.ProviderName, + User1Id.ToString() + ) + ); + + await _resourcePermissionGrantRepository.InsertAsync( + new ResourcePermissionGrant( + _guidGenerator.Create(), + "MyResourcePermission5", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey3, + UserPermissionValueProvider.ProviderName, + User1Id.ToString() + ) + ); + + await _resourcePermissionGrantRepository.InsertAsync( + new ResourcePermissionGrant( + _guidGenerator.Create(), + "MyResourcePermission6", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey3, + UserPermissionValueProvider.ProviderName, + User1Id.ToString() + ) + ); + + await _resourcePermissionGrantRepository.InsertAsync( + new ResourcePermissionGrant( + _guidGenerator.Create(), + "MyResourcePermission5", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey5, + UserPermissionValueProvider.ProviderName, + User1Id.ToString() + ) + ); } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/ResourcePermissionGrantRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/ResourcePermissionGrantRepository_Tests.cs new file mode 100644 index 0000000000..90652683b1 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/ResourcePermissionGrantRepository_Tests.cs @@ -0,0 +1,121 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.Abp.PermissionManagement; + +public abstract class ResourcePermissionGrantRepository_Tests : PermissionManagementTestBase + where TStartupModule : IAbpModule +{ + protected IResourcePermissionGrantRepository ResourcePermissionGrantRepository { get; } + + protected ResourcePermissionGrantRepository_Tests() + { + ResourcePermissionGrantRepository = GetRequiredService(); + } + + [Fact] + public async Task FindAsync() + { + (await ResourcePermissionGrantRepository.FindAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString())).ShouldNotBeNull(); + + (await ResourcePermissionGrantRepository.FindAsync( + "Undefined-Permission", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString())).ShouldBeNull(); + + (await ResourcePermissionGrantRepository.FindAsync( + "MyResourcePermission1", + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1, + "Undefined-Provider", + "Unknown-Id")).ShouldBeNull(); + } + + [Fact] + public async Task GetList4Async() + { + var permissionGrants = + await ResourcePermissionGrantRepository.GetListAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey3, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()); + + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission3"); + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission5"); + } + + [Fact] + public async Task GetList5Async() + { + var permissionGrants = + await ResourcePermissionGrantRepository.GetListAsync( + new[] { "MyResourcePermission1", "MyResourcePermission3", "MyResourcePermission5" }, + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey3, + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()); + + permissionGrants.ShouldNotContain(p => p.Name == "MyResourcePermission1"); + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission3"); + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission5"); + } + + [Fact] + public async Task GetList2Async() + { + var permissionGrants = + await ResourcePermissionGrantRepository.GetListAsync( + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User1Id.ToString()); + + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission1" && p.ResourceKey == TestEntityResource.ResourceKey1 && p.ResourceName == TestEntityResource.ResourceName); + permissionGrants.ShouldContain(p => p.Name == "MyDisabledResourcePermission1" && p.ResourceKey == TestEntityResource.ResourceKey1 && p.ResourceName == TestEntityResource.ResourceName); + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission3" && p.ResourceKey == TestEntityResource.ResourceKey3 && p.ResourceName == TestEntityResource.ResourceName); + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission5" && p.ResourceKey == TestEntityResource.ResourceKey3 && p.ResourceName == TestEntityResource.ResourceName); + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission5" && p.ResourceKey == TestEntityResource.ResourceKey5 && p.ResourceName == TestEntityResource.ResourceName); + + permissionGrants = + await ResourcePermissionGrantRepository.GetListAsync( + UserPermissionValueProvider.ProviderName, + PermissionTestDataBuilder.User2Id.ToString()); + + permissionGrants.ShouldBeEmpty(); + } + + [Fact] + public async Task GetPermissionsAsync() + { + var permissionGrants = + await ResourcePermissionGrantRepository.GetPermissionsAsync( + TestEntityResource.ResourceName, + TestEntityResource.ResourceKey1); + + permissionGrants.Count.ShouldBe(2); + permissionGrants.ShouldContain(p => p.Name == "MyResourcePermission1"); + permissionGrants.ShouldContain(p => p.Name == "MyDisabledResourcePermission1"); + } + + [Fact] + public async Task GetResourceKeys() + { + var permissionGrants = + await ResourcePermissionGrantRepository.GetResourceKeys( + TestEntityResource.ResourceName, + "MyResourcePermission5"); + + permissionGrants.Count.ShouldBe(2); + permissionGrants.ShouldContain(p => p.ResourceKey == TestEntityResource.ResourceKey3); + permissionGrants.ShouldContain(p => p.ResourceKey == TestEntityResource.ResourceKey5); + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestEntityResource.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestEntityResource.cs new file mode 100644 index 0000000000..9f631b123d --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestEntityResource.cs @@ -0,0 +1,16 @@ +using System; + +namespace Volo.Abp.PermissionManagement; + +public class TestEntityResource +{ + public static readonly string ResourceName = typeof(TestEntityResource).FullName; + + public static readonly string ResourceKey1 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey2 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey3 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey4 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey5 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey6 = Guid.NewGuid().ToString(); + public static readonly string ResourceKey7 = Guid.NewGuid().ToString(); +} 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 new file mode 100644 index 0000000000..2d5a4d5d99 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionDefinitionProvider.cs @@ -0,0 +1,28 @@ +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.PermissionManagement; + +public class TestResourcePermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + context.AddGroup("TestEntityManagementPermissionGroup").AddPermission("TestEntityManagementPermission"); + + context.AddResourcePermission("MyResourcePermission1", TestEntityResource.ResourceName, "TestEntityManagementPermission"); + context.AddResourcePermission("MyResourceDisabledPermission1", TestEntityResource.ResourceName, "TestEntityManagementPermission", isEnabled: false); + context.AddResourcePermission("MyResourcePermission2", TestEntityResource.ResourceName, "TestEntityManagementPermission"); + context.AddResourcePermission("MyResourcePermission3", TestEntityResource.ResourceName, "TestEntityManagementPermission", multiTenancySide: MultiTenancySides.Host); + context.AddResourcePermission("MyResourcePermission4", TestEntityResource.ResourceName, "TestEntityManagementPermission", multiTenancySide: MultiTenancySides.Host).WithProviders(UserPermissionValueProvider.ProviderName); + + var myPermission5 = context.AddResourcePermission("MyResourcePermission5", TestEntityResource.ResourceName, "TestEntityManagementPermission"); + myPermission5.StateCheckers.Add(new TestRequireRolePermissionStateProvider("super-admin")); + + context.AddResourcePermission("MyResourcePermission6", TestEntityResource.ResourceName, "TestEntityManagementPermission"); + + context.AddResourcePermission("MyResourceDisabledPermission2", TestEntityResource.ResourceName, "TestEntityManagementPermission", isEnabled: false); + + context.AddResourcePermission("MyResourcePermission7", TestEntityResource.ResourceName, "TestEntityManagementPermission"); + context.AddResourcePermission("MyResourcePermission8", TestEntityResource.ResourceName, "TestEntityManagementPermission"); + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionManagementProvider.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionManagementProvider.cs new file mode 100644 index 0000000000..e555c6133d --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionManagementProvider.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.PermissionManagement; + +public class TestResourcePermissionManagementProvider : ResourcePermissionManagementProvider +{ + public override string Name => "Test"; + + public TestResourcePermissionManagementProvider( + IResourcePermissionGrantRepository resourcePermissionGrantRepository, + IGuidGenerator guidGenerator, + ICurrentTenant currentTenant) + : base( + resourcePermissionGrantRepository, + guidGenerator, + currentTenant) + { + + } +} diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionProviderKeyLookupService.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionProviderKeyLookupService.cs new file mode 100644 index 0000000000..f42a204f7a --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestResourcePermissionProviderKeyLookupService.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; + +namespace Volo.Abp.PermissionManagement; + +public class TestResourcePermissionProviderKeyLookupService : IResourcePermissionProviderKeyLookupService, ITransientDependency +{ + public string Name => "Test"; + + public ILocalizableString DisplayName => new LocalizableString("Test", "TestResource"); + + public Task> SearchAsync(string filter = null, int page = 1, CancellationToken cancellationToken = default) + { + throw new System.NotImplementedException(); + } + + public Task> SearchAsync(string[] keys, CancellationToken cancellationToken = default) + { + throw new System.NotImplementedException(); + } +} diff --git a/modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/IRoleData.cs b/modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/IRoleData.cs new file mode 100644 index 0000000000..37656f6588 --- /dev/null +++ b/modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/IRoleData.cs @@ -0,0 +1,19 @@ +using System; +using Volo.Abp.Data; + +namespace Volo.Abp.Users; + +public interface IRoleData : IHasExtraProperties +{ + Guid Id { get; } + + Guid? TenantId { get; } + + string Name { get; } + + bool IsDefault { get; } + + bool IsStatic { get; } + + bool IsPublic { get; } +} diff --git a/modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/RoleData.cs b/modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/RoleData.cs new file mode 100644 index 0000000000..960a3dfcc7 --- /dev/null +++ b/modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/RoleData.cs @@ -0,0 +1,56 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp.Data; + +namespace Volo.Abp.Users; + +public class RoleData : IRoleData +{ + public Guid Id { get; set; } + + public Guid? TenantId { get; set; } + + public string Name { get; set; } + + public bool IsDefault { get; set; } + + public bool IsStatic { get; set; } + + public bool IsPublic { get; set; } + + public ExtraPropertyDictionary ExtraProperties { get; } + + public RoleData() + { + + } + + public RoleData(IRoleData roleData) + { + Id = roleData.Id; + Name = roleData.Name; + IsDefault = roleData.IsDefault; + IsStatic = roleData.IsStatic; + IsPublic = roleData.IsPublic; + TenantId = roleData.TenantId; + ExtraProperties = roleData.ExtraProperties; + } + + public RoleData( + Guid id, + [NotNull] string name, + bool isDefault = false, + bool isStatic = false, + bool isPublic = false, + Guid? tenantId = null, + ExtraPropertyDictionary extraProperties = null) + { + Id = id; + Name = name; + IsDefault = isDefault; + IsStatic = isStatic; + IsPublic = isPublic; + TenantId = tenantId; + ExtraProperties = extraProperties; + } +}