Open Closed

Customize permissions page for users. #4509


User avatar
0
stefan@ppibv.nl created

Hey there.

I have been looking through the code for a bit, but couldn't exactly pinpoint how to change this. If possible at all. We noticed that for every user, you can customize the permissions for every user individually, this is great, but we noticed that while you are able to set certain permissions 'on' you're not able to set some permissions 'off' as an exception for that user.

For example, in this user these permissions are granted from the Role that that user has. But would we be able to customize this page to where we can also turn off certain permissions?

  • ABP Framework version: v6.0.2
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes (MVC)

4 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    It's better you create different roles to manage the permissions. https://en.wikipedia.org/wiki/Role-based_access_control Or you can set a role without any permission and manage the permissions on the user side.

  • User Avatar
    0
    stefan@ppibv.nl created

    Hello.

    Thanks for the quick response to my question. I do agree this is a better way of working. But our team would like to see this feature being added regardless.

    Would there still be a possibility to do this?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Yes, it's possible, but it has a lot of work to do and breaks the existing framework design.

    MyRolePermissionManagementProvider

    [ExposeServices(typeof(RolePermissionManagementProvider))]
    public class MyRolePermissionManagementProvider : RolePermissionManagementProvider
    {
        public MyRolePermissionManagementProvider(
            IPermissionGrantRepository permissionGrantRepository,
            IGuidGenerator guidGenerator,
            ICurrentTenant currentTenant,
            IUserRoleFinder userRoleFinder) : base(permissionGrantRepository, guidGenerator, currentTenant, userRoleFinder)
        {
        }
    
        public override async Task<MultiplePermissionValueProviderGrantInfo> CheckAsync(string[] names, string providerName, string providerKey)
        {
            var multiplePermissionValueProviderGrantInfo = await base.CheckAsync(names, providerName, providerKey);
            if (providerName != UserPermissionValueProvider.ProviderName)
            {
                return multiplePermissionValueProviderGrantInfo;
            }
    
            var permissionNotGrants = await PermissionGrantRepository.GetListAsync(names, providerName, $"{providerKey},False");
    
    
            foreach (var permissionNotGrant in permissionNotGrants)
            {
                if (multiplePermissionValueProviderGrantInfo.Result.ContainsKey(permissionNotGrant.Name))
                {
                    multiplePermissionValueProviderGrantInfo.Result[permissionNotGrant.Name] = new PermissionValueProviderGrantInfo(false, providerKey);
                }
            }
    
            return multiplePermissionValueProviderGrantInfo;
        }
    }
    

    It will check the user permissions again and change the result if the permission is not granted to the user.

    MyUserPermissionManagementProvider

    [ExposeServices(typeof(UserPermissionManagementProvider))]
    public class MyUserPermissionManagementProvider : UserPermissionManagementProvider
    {
        protected IUserRoleFinder UserRoleFinder { get; }
    
        public MyUserPermissionManagementProvider(IPermissionGrantRepository permissionGrantRepository, IGuidGenerator guidGenerator, ICurrentTenant currentTenant, IUserRoleFinder userRoleFinder) : base(permissionGrantRepository, guidGenerator, currentTenant)
        {
            UserRoleFinder = userRoleFinder;
        }
    
        public override Task<MultiplePermissionValueProviderGrantInfo> CheckAsync(string[] names, string providerName, string providerKey)
        {
            var key = $"{providerKey},True";
            return base.CheckAsync(names, providerName, key);
        }
    
        public override async Task SetAsync(string name, string providerKey, bool isGranted)
        {
            if (isGranted)
            {
                await RevokeAsync(name, $"{providerKey},False");
                if(await ShouldAddPermissionAsync(name, providerKey))
                {
                    await AddIfNotExistsAsync(name, providerKey, isGranted);
                }
    
                return;
            }
    
    
            await RevokeAsync(name, $"{providerKey},True");
            await AddIfNotExistsAsync(name, providerKey, isGranted);
        }
    
        private async Task<bool> ShouldAddPermissionAsync(string name, string providerKey)
        {
            var userId = Guid.Parse(providerKey);
            var roleNames = await UserRoleFinder.GetRolesAsync(userId);
    
            foreach (var roleName in roleNames)
            {
                var permission = await PermissionGrantRepository.FindAsync(name,RolePermissionValueProvider.ProviderName, roleName);
                if(permission != null)
                {
                    return false;
                }
            }
    
            return true;
        }
    
        private async Task AddIfNotExistsAsync(string name, string providerKey, bool isGranted)
        {
            var key = $"{providerKey},{isGranted}";
    
            if (await PermissionGrantRepository.FindAsync(name, Name, key) != null)
            {
                return;
            }
    
            await PermissionGrantRepository.InsertAsync(
                new PermissionGrant(
                    GuidGenerator.Create(),
                    name,
                    Name,
                    key,
                    CurrentTenant.Id
                )
            );
        }
    }
    

    It will add suffixes True and False to the provider key.

    It should work for you, but I didn't consider all scenarios. you should do the full test to check it and enhance it

  • User Avatar
    0
    stefan@ppibv.nl created

    Yes, thank you for this answer, this will surely work for us.

    Thank you.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11