How to implement dynamic resource permission in asp.net MVC?

511 Views Asked by At

I want to implement dynamic authorization in my ASP.NET MVC project where resource permissions can be assigned to both user and role dynamically by the system admin. I'm using the following tables to manage permissions.

  1. Resource
  2. ResourcePermission

Models for these tables are

public class Resource
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int? ParentResourceId { get; set; }
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public int Order { get; set; }
    public Resource ParentResource { get; set; }
    public ICollection<Permission> Permissions { get; set; }
}

public class Permission
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int ResourceId { get; set; }
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public int Order { get; set; }
    public Resource Resource { get; set; }
}

I need to display resource permissions according to resource hierarchy on a UI like treeview so that admin can check and assign permissions to the users and roles. Using a recursive function (given below) I can make the resource hierarchy (from resource table only) but can't include permission to this hierarchy.

The code I've tried so far is given below:

public List<PermissionTreeDto> GetPermissions()
    {
        var permissions = _context.Resources
                          .Where(r => r.OrganizationId == OrganizationId)
                          .ToList();

        return permissions.Where(r => r.ParentResourceId == null)
                        .OrderBy(r => r.Order)
                        .Select(r => new PermissionTreeDto
                        {
                            id = 0,
                            text = r.DisplayName,
                            @checked = false,
                            children = GetChildren(permissions, r.Id)
                        }).ToList();
    }

    private List<PermissionTreeDto> GetChildren(List<Resource> permissions, int parentId)
    {
        return permissions.Where(r => r.ParentResourceId == parentId)
            .OrderBy(r => r.Order)
            .Select(r => new PermissionTreeDto
            {
                id = 0,
                text = r.DisplayName,
                @checked = false,
                children = GetChildren(permissions, r.Id)
            }).ToList();
    }

I'm using gijgo bootstrap treeview:

enter image description here

There might be any fault in my model design also. In that case, please suggest any better approach to achieve the same goal I'm expecting.

1

There are 1 best solutions below

0
Chanchal Zoarder On BEST ANSWER

I've managed the hierarchy with permission in this way-

public List<ResourceTreeDto> GetPermissions()
    {
        var resources = _context.Resources.Include(r=>r.Permissions)
                          .Where(r => r.OrganizationId == OrganizationId)
                          .ToList();

        return resources.Where(r => r.ParentResourceId == null)
                        .OrderBy(r => r.Order)
                        .Select(r => new ResourceTreeDto
                        {
                            id = 0,
                            text = r.DisplayName,
                            @checked = false,
                            children = r.Permissions.OrderBy(p=>p.Order).Select(p => new ResourceTreeDto()
                            {
                                id = p.Id,
                                text = p.DisplayName,
                                @checked = false
                            }).Union(GetChildren(resources, r.Id))
                        }).ToList();
    }

 private IEnumerable<ResourceTreeDto> GetChildren(List<Resource> resources, int parentId)
    {
        return resources.Where(r => r.ParentResourceId == parentId)
            .OrderBy(r => r.Order)
            .Select(r => new ResourceTreeDto
            {
                id = 0,
                text = r.DisplayName,
                @checked = false,
                children = r.Permissions.OrderBy(p => p.Order).Select(p => new ResourceTreeDto()
                {
                    id = p.Id,
                    text = p.DisplayName,
                    @checked = false
                }).Union(GetChildren(resources, r.Id))
            });
    }

And now I'm getting the expected output like- enter image description here