From 6c28b871837a22e8ddd083a95356f8a652217265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 15 Feb 2018 15:29:39 +0300 Subject: [PATCH] Working on permission management --- .../AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs | 6 + .../AbpDeskPermissionDefinitionProvider.cs | 18 +++ .../Abp/Identity/AbpIdentityDomainModule.cs | 6 + .../RolePermissionManagementProvider.cs | 51 +++++++ .../UserPermissionManagementProvider.cs | 31 ++++ .../UserPermissionManagerExtensions.cs | 13 +- .../Abp/Permissions/PermissionAppService.cs | 2 + .../IPermissionManagementProvider.cs | 11 ++ .../Abp/Permissions/IPermissionManager.cs | 8 +- .../PermissionManagementOptions.cs | 14 ++ .../Volo/Abp/Permissions/PermissionManager.cs | 140 ++++++++++++------ .../PermissionValueProviderInfo.cs | 20 +++ .../PermissionWithGrantedProviders.cs | 24 +++ .../Permissions/IPermissionValueProvider.cs | 3 +- .../Volo/Abp/Permissions/PermissionChecker.cs | 8 +- .../Permissions/PermissionValueProvider.cs | 3 +- 16 files changed, 296 insertions(+), 62 deletions(-) create mode 100644 src/AbpDesk/AbpDesk.Web.Mvc/Permissions/AbpDeskPermissionDefinitionProvider.cs create mode 100644 src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RolePermissionManagementProvider.cs create mode 100644 src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserPermissionManagementProvider.cs create mode 100644 src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/IPermissionManagementProvider.cs create mode 100644 src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionManagementOptions.cs create mode 100644 src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionValueProviderInfo.cs create mode 100644 src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionWithGrantedProviders.cs diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs b/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs index dc30260453..80b48ab86e 100644 --- a/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs +++ b/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO; using AbpDesk.EntityFrameworkCore; using AbpDesk.Web.Mvc.Navigation; +using AbpDesk.Web.Mvc.Permissions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Localization; @@ -78,6 +79,11 @@ namespace AbpDesk.Web.Mvc options.MenuContributors.Add(new MainMenuContributor()); }); + services.Configure(options => + { + options.DefinitionProviders.Add(); + }); + //services.Configure(configuration); //Needed when we use Volo.Abp.Identity.HttpApi.Client var authentication = services.AddAuthentication(); diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Permissions/AbpDeskPermissionDefinitionProvider.cs b/src/AbpDesk/AbpDesk.Web.Mvc/Permissions/AbpDeskPermissionDefinitionProvider.cs new file mode 100644 index 0000000000..8300ce13f6 --- /dev/null +++ b/src/AbpDesk/AbpDesk.Web.Mvc/Permissions/AbpDeskPermissionDefinitionProvider.cs @@ -0,0 +1,18 @@ +using Volo.Abp.Permissions; + +namespace AbpDesk.Web.Mvc.Permissions +{ + public class AbpDeskPermissionDefinitionProvider : IPermissionDefinitionProvider + { + public void Define(IPermissionDefinitionContext context) + { + var tickets = context.Add("AbpDesk.Tickets"); + tickets.AddChild("AbpDesk.Tickets.Reply"); + tickets.AddChild("AbpDesk.Tickets.Close"); + + var customers = context.Add("AbpDesk.Customers"); + customers.AddChild("AbpDesk.Customers.Create"); + customers.AddChild("AbpDesk.Customers.Delete"); + } + } +} diff --git a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs index ae29666b8e..ef9a3d23bd 100644 --- a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs +++ b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs @@ -11,6 +11,12 @@ namespace Volo.Abp.Identity { public override void ConfigureServices(IServiceCollection services) { + services.Configure(options => + { + options.ManagementProviders.Add(); + options.ManagementProviders.Add(); + }); + var identityBuilder = services.AddAbpIdentity(); services.ExecutePreConfiguredActions(identityBuilder); diff --git a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RolePermissionManagementProvider.cs b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RolePermissionManagementProvider.cs new file mode 100644 index 0000000000..57a8a0975e --- /dev/null +++ b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RolePermissionManagementProvider.cs @@ -0,0 +1,51 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Permissions; + +namespace Volo.Abp.Identity +{ + public class RolePermissionManagementProvider : IPermissionManagementProvider + { + public string Name => "Role"; + + private readonly IIdentityUserRepository _identityUserRepository; + private readonly IPermissionGrantRepository _permissionGrantRepository; + + public RolePermissionManagementProvider( + IPermissionGrantRepository permissionGrantRepository, + IIdentityUserRepository identityUserRepository) + { + _permissionGrantRepository = permissionGrantRepository; + _identityUserRepository = identityUserRepository; + } + + public async Task CheckAsync(string name, string providerName, string providerKey) + { + if (providerName == Name) + { + return new PermissionValueProviderGrantInfo( + await _permissionGrantRepository.FindAsync(name, providerName, providerKey) != null, + providerKey + ); + } + + if (providerName == "User") + { + var userId = Guid.Parse(providerKey); + + var roleNames = await _identityUserRepository.GetRoleNamesAsync(userId); + + foreach (var roleName in roleNames) + { + var pg = await _permissionGrantRepository.FindAsync(name, providerName, roleName); + if (pg != null) + { + return new PermissionValueProviderGrantInfo(true, roleName); + } + } + } + + return PermissionValueProviderGrantInfo.NonGranted; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserPermissionManagementProvider.cs b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserPermissionManagementProvider.cs new file mode 100644 index 0000000000..f0969a758a --- /dev/null +++ b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserPermissionManagementProvider.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Permissions; + +namespace Volo.Abp.Identity +{ + public class UserPermissionManagementProvider : IPermissionManagementProvider, ITransientDependency + { + public string Name => "User"; + + private readonly IPermissionGrantRepository _permissionGrantRepository; + + public UserPermissionManagementProvider(IPermissionGrantRepository permissionGrantRepository) + { + _permissionGrantRepository = permissionGrantRepository; + } + + public async Task CheckAsync(string name, string providerName, string providerKey) + { + if (providerName != Name) + { + return PermissionValueProviderGrantInfo.NonGranted; + } + + return new PermissionValueProviderGrantInfo( + await _permissionGrantRepository.FindAsync(name, providerName, providerKey) != null, + providerKey + ); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Domain/Volo/Abp/Permissions/UserPermissionManagerExtensions.cs b/src/Volo.Abp.Identity.Domain/Volo/Abp/Permissions/UserPermissionManagerExtensions.cs index 1ea6696f39..8bd2fa730f 100644 --- a/src/Volo.Abp.Identity.Domain/Volo/Abp/Permissions/UserPermissionManagerExtensions.cs +++ b/src/Volo.Abp.Identity.Domain/Volo/Abp/Permissions/UserPermissionManagerExtensions.cs @@ -11,22 +11,25 @@ namespace Volo.Abp.Permissions public static Task IsGrantedForUserAsync(this IPermissionManager permissionManager, [NotNull] string name, Guid userId) { - return permissionManager.IsGrantedAsync(name, ProviderName, userId.ToString()); + throw new NotImplementedException(); + //return permissionManager.GetAsync(name, ProviderName, userId.ToString()); } - public static Task> GetAllGrantedForUserAsync(this IPermissionManager permissionManager, Guid userId) + public static Task> GetAllAsync(this IPermissionManager permissionManager, Guid userId) { - return permissionManager.GetAllGrantedAsync(ProviderName, userId.ToString()); + return permissionManager.GetAllAsync(ProviderName, userId.ToString()); } public static Task GrantForUserAsync(this IPermissionManager permissionManager, Guid userId, [NotNull] string name) { - return permissionManager.GrantAsync(name, ProviderName, userId.ToString()); + throw new NotImplementedException(); + //return permissionManager.GrantAsync(name, ProviderName, userId.ToString()); } public static Task RevokeForUserAsync(this IPermissionManager permissionManager, Guid userId, [NotNull] string name) { - return permissionManager.RevokeAsync(name, ProviderName, userId.ToString()); + throw new NotImplementedException(); + //return permissionManager.RevokeAsync(name, ProviderName, userId.ToString()); } } } diff --git a/src/Volo.Abp.Permissions.Application/Volo/Abp/Permissions/PermissionAppService.cs b/src/Volo.Abp.Permissions.Application/Volo/Abp/Permissions/PermissionAppService.cs index 3ecd3a4797..fda7e42430 100644 --- a/src/Volo.Abp.Permissions.Application/Volo/Abp/Permissions/PermissionAppService.cs +++ b/src/Volo.Abp.Permissions.Application/Volo/Abp/Permissions/PermissionAppService.cs @@ -21,6 +21,8 @@ namespace Volo.Abp.Permissions public async Task GetListAsync(string providerName, string providerKey) { + var permissionInfos = await _permissionManager.GetAllAsync(providerName, providerKey); + return new GetPermissionListResultDto { Groups = new List diff --git a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/IPermissionManagementProvider.cs b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/IPermissionManagementProvider.cs new file mode 100644 index 0000000000..83ec4413ce --- /dev/null +++ b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/IPermissionManagementProvider.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Permissions +{ + public interface IPermissionManagementProvider + { + string Name { get; } + + Task CheckAsync(string name, string providerName, string providerKey); + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/IPermissionManager.cs b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/IPermissionManager.cs index 0c6d04cc7b..bd166bdfde 100644 --- a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/IPermissionManager.cs +++ b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/IPermissionManager.cs @@ -6,12 +6,12 @@ namespace Volo.Abp.Permissions { public interface IPermissionManager { - Task IsGrantedAsync([NotNull]string name, [NotNull] string providerName, [NotNull] string providerKey); + //Task GetAsync([NotNull]string name, [NotNull] string providerName, [NotNull] string providerKey); - Task> GetAllGrantedAsync([NotNull] string providerName, [NotNull] string providerKey); + Task> GetAllAsync([NotNull] string providerName, [NotNull] string providerKey); - Task GrantAsync([NotNull] string name, [NotNull] string providerName, [NotNull] string providerKey); + //Task GrantAsync([NotNull] string name, [NotNull] string providerName, [NotNull] string providerKey); - Task RevokeAsync([NotNull] string name, [NotNull] string providerName, [NotNull] string providerKey); + //Task RevokeAsync([NotNull] string name, [NotNull] string providerName, [NotNull] string providerKey); } } \ No newline at end of file diff --git a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionManagementOptions.cs b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionManagementOptions.cs new file mode 100644 index 0000000000..feae64a183 --- /dev/null +++ b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionManagementOptions.cs @@ -0,0 +1,14 @@ +using Volo.Abp.Collections; + +namespace Volo.Abp.Permissions +{ + public class PermissionManagementOptions + { + public ITypeList ManagementProviders { get; } + + public PermissionManagementOptions() + { + ManagementProviders = new TypeList(); + } + } +} diff --git a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionManager.cs b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionManager.cs index f439dd6f57..f47476e0fa 100644 --- a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionManager.cs +++ b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionManager.cs @@ -1,6 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; @@ -9,77 +12,120 @@ namespace Volo.Abp.Permissions public class PermissionManager : IPermissionManager, ISingletonDependency { protected IPermissionGrantRepository PermissionGrantRepository { get; } + protected IPermissionDefinitionManager PermissionDefinitionManager { get; } + protected IGuidGenerator GuidGenerator { get; } + protected IReadOnlyList ManagementProviders => _lazyProviders.Value; + + protected PermissionManagementOptions Options { get; } + + private readonly Lazy> _lazyProviders; + public PermissionManager( IPermissionDefinitionManager permissionDefinitionManager, IPermissionGrantRepository permissionGrantRepository, - IGuidGenerator guidGenerator) + IServiceProvider serviceProvider, + IGuidGenerator guidGenerator, + IOptions options) { GuidGenerator = guidGenerator; PermissionGrantRepository = permissionGrantRepository; PermissionDefinitionManager = permissionDefinitionManager; + Options = options.Value; + + _lazyProviders = new Lazy>( + () => Options + .ManagementProviders + .Select(c => serviceProvider.GetRequiredService(c) as IPermissionManagementProvider) + .ToList(), + true + ); } - public async Task IsGrantedAsync(string providerName, string providerKey, string name) - { - Check.NotNull(providerName, nameof(providerName)); - Check.NotNull(providerKey, nameof(providerKey)); - Check.NotNull(name, nameof(name)); + //public async Task IsGrantedAsync(string providerName, string providerKey, string name) + //{ + // Check.NotNull(providerName, nameof(providerName)); + // Check.NotNull(providerKey, nameof(providerKey)); + // Check.NotNull(name, nameof(name)); - return await PermissionGrantRepository.FindAsync(name, providerName, providerKey) != null; - } + // return await PermissionGrantRepository.FindAsync(name, providerName, providerKey) != null; + //} - public async Task> GetAllGrantedAsync(string providerName, string providerKey) - { - Check.NotNull(providerName, nameof(providerName)); - Check.NotNull(providerKey, nameof(providerKey)); + //public async Task> GetAllGrantedAsync(string providerName, string providerKey) + //{ + // Check.NotNull(providerName, nameof(providerName)); + // Check.NotNull(providerKey, nameof(providerKey)); - return (await PermissionGrantRepository.GetListAsync(providerName, providerKey)) - .Select(p => p.Name) - .ToList(); - } + // return (await PermissionGrantRepository.GetListAsync(providerName, providerKey)) + // .Select(p => p.Name) + // .ToList(); + //} - public async Task GrantAsync(string name, string providerName, string providerKey) - { - Check.NotNull(name, nameof(name)); - Check.NotNull(providerName, nameof(providerName)); - Check.NotNull(providerKey, nameof(providerKey)); + //public async Task GrantAsync(string name, string providerName, string providerKey) + //{ + // Check.NotNull(name, nameof(name)); + // Check.NotNull(providerName, nameof(providerName)); + // Check.NotNull(providerKey, nameof(providerKey)); - if (await IsGrantedAsync(providerName, providerKey, name)) - { - return; - } + // if (await IsGrantedAsync(providerName, providerKey, name)) + // { + // return; + // } - await PermissionGrantRepository.InsertAsync( - new PermissionGrant( - GuidGenerator.Create(), - name, - providerName, - providerKey - ) - ); - } + // await PermissionGrantRepository.InsertAsync( + // new PermissionGrant( + // GuidGenerator.Create(), + // name, + // providerName, + // providerKey + // ) + // ); + //} + + //public async Task RevokeAsync(string providerName, string providerKey, string name) + //{ + // Check.NotNull(providerName, nameof(providerName)); + // Check.NotNull(providerKey, nameof(providerKey)); + // Check.NotNull(name, nameof(name)); + + // if (await IsGrantedAsync(providerName, providerKey, name)) + // { + // return; + // } - public async Task RevokeAsync(string providerName, string providerKey, string name) + // var grant = await PermissionGrantRepository.FindAsync(name, providerName, providerKey); + // if (grant == null) + // { + // return; + // } + + // await PermissionGrantRepository.DeleteAsync(grant); + //} + + public async Task> GetAllAsync(string providerName, string providerKey) { - Check.NotNull(providerName, nameof(providerName)); - Check.NotNull(providerKey, nameof(providerKey)); - Check.NotNull(name, nameof(name)); + var results = new List(); - if (await IsGrantedAsync(providerName, providerKey, name)) + foreach (var permissionDefinition in PermissionDefinitionManager.GetAll()) { - return; - } + var result = new PermissionWithGrantedProviders(permissionDefinition.Name, false); - var grant = await PermissionGrantRepository.FindAsync(name, providerName, providerKey); - if (grant == null) - { - return; + foreach (var provider in ManagementProviders) + { + var providerResult = await provider.CheckAsync(permissionDefinition.Name, providerName, providerKey); + if (providerResult.IsGranted) + { + result.IsGranted = true; + result.Providers.Add(new PermissionValueProviderInfo(provider.Name, providerResult.ProviderKey)); + } + } + + results.Add(result); } - await PermissionGrantRepository.DeleteAsync(grant); + return results; } } } \ No newline at end of file diff --git a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionValueProviderInfo.cs b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionValueProviderInfo.cs new file mode 100644 index 0000000000..e94ba47595 --- /dev/null +++ b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionValueProviderInfo.cs @@ -0,0 +1,20 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Permissions +{ + public class PermissionValueProviderInfo + { + public string Name { get; } + + public string Key { get; } + + public PermissionValueProviderInfo([NotNull]string name, [NotNull]string key) + { + Check.NotNull(name, nameof(name)); + Check.NotNull(key, nameof(key)); + + Name = name; + Key = key; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionWithGrantedProviders.cs b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionWithGrantedProviders.cs new file mode 100644 index 0000000000..a196d3a987 --- /dev/null +++ b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionWithGrantedProviders.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.Permissions +{ + public class PermissionWithGrantedProviders + { + public string Name { get; } + + public bool IsGranted { get; set; } + + public List Providers { get; set; } + + public PermissionWithGrantedProviders([NotNull] string name, bool isGranted) + { + Check.NotNull(name, nameof(name)); + + Name = name; + IsGranted = isGranted; + + Providers = new List(); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/IPermissionValueProvider.cs b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/IPermissionValueProvider.cs index a5ac1d3dba..eb6b83fc6e 100644 --- a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/IPermissionValueProvider.cs +++ b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/IPermissionValueProvider.cs @@ -1,8 +1,9 @@ using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.Permissions { - public interface IPermissionValueProvider + public interface IPermissionValueProvider : ISingletonDependency { string Name { get; } diff --git a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionChecker.cs b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionChecker.cs index 542905222a..433f100e22 100644 --- a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionChecker.cs +++ b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionChecker.cs @@ -12,11 +12,12 @@ namespace Volo.Abp.Permissions { protected IPermissionDefinitionManager PermissionDefinitionManager { get; } - protected List Providers => _lazyProviders.Value; - private readonly Lazy> _lazyProviders; + protected IReadOnlyList ValueProviders => _lazyProviders.Value; protected PermissionOptions Options { get; } + private readonly Lazy> _lazyProviders; + public PermissionChecker( IOptions options, IServiceProvider serviceProvider, @@ -34,6 +35,7 @@ namespace Volo.Abp.Permissions ); } + public Task CheckAsync(string name) { var permission = PermissionDefinitionManager.Get(name); @@ -43,7 +45,7 @@ namespace Volo.Abp.Permissions protected virtual async Task GetPermissionGrantInfo(PermissionDefinition permission) { - foreach (var provider in Providers) + foreach (var provider in ValueProviders) { var result = await provider.CheckAsync(permission); if (result.IsGranted) diff --git a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionValueProvider.cs b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionValueProvider.cs index 1bb6d1c616..48441d5a5e 100644 --- a/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionValueProvider.cs +++ b/src/Volo.Abp.Permissions/Volo/Abp/Permissions/PermissionValueProvider.cs @@ -1,9 +1,8 @@ using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; namespace Volo.Abp.Permissions { - public abstract class PermissionValueProvider : IPermissionValueProvider, ISingletonDependency + public abstract class PermissionValueProvider : IPermissionValueProvider { public abstract string Name { get; }