DEV Community

Raúl Julián López Caña
Raúl Julián López Caña

Posted on • Originally published at Medium on

Angular permissions based on roles | Part 2. Permissions for multiple resources

In the previous article, a roles and permits handler, a global service to consume the handler and a directive for easy use have been implemented.

In this article, we will focus on solving the problem of managing different permissions for each resource of the application.

For example, a USER can READ, and ORDER pizza, but can only READ orders.

Glossary:

  1. Define the model Permission
  2. Refactor(PermissionBase and its extended classes)
  3. Refactor(Service): isGranted now controls permissions and resources
  4. Refactor(Directive): now receives resource and permission as parameter
  5. Stackblitz demo

1. Define the model Permission

We need to define a new data structure that relates resources with permissions. For this, we will first define the permissions that the application will handle.

export enum Resource {
  PASTA = 'PASTA',
  PIZZA = 'PIZZA',
  BILL = 'BILL'
}
Enter fullscreen mode Exit fullscreen mode

Once the resources are established, we can define the permission’s structure:

import { Resource } from './resource';
import { PermissionType } from './permission-type';

export class Permission {
  public resource: Resource;
  public permissions: PermissionType[];

  constructor(resource: Resource, permissions: PermissionType[]) {
    this.resource = resource;
    this.permissions = permissions;
  }
}
Enter fullscreen mode Exit fullscreen mode

Each permission will handle a list of permissions for each resource and user.

2. Refactor(PermissionBase and its extended classes)

We will adapt the new PermissionBase class to handle the new permissions.

import { Permission } from '../permission';

export abstract class PermissionBase {
  public permissions: Permission[];

  constructor() {}
}
Enter fullscreen mode Exit fullscreen mode

Now, extended class permissions are defined for each resource:

import { PermissionType } from '../permission-type';
import { Resource } from '../resource';
import { PermissionBase } from './base.permissions';
import {Permission } from '../permission';

export class UserPermission extends PermissionBase {
  constructor() {
    super();
    this.permissions = [
      new Permission(Resource.BILL, [
        PermissionType.READ,
        PermissionType.ORDER
      ]),
      new Permission(Resource.PASTA, [
        PermissionType.READ,
        PermissionType.ORDER
      ]),
      new Permission(Resource.PIZZA, [
        PermissionType.READ,
        PermissionType.ORDER
      ])
    ];
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Refactor(Service): isGranted now controls permissions and resources

Let’s refactor!

isGranted(resource: Resource, permission: PermissionType) {
  for (const res of this.permissions.permissions) {
    if (resource == res.resource) {
      for (const perm of res.permissions) {
        if (perm == permission) {
          return true;
        }
      }
    }
  }
  return false;
}
Enter fullscreen mode Exit fullscreen mode

4. Refactor(Directive): now receives resource and permission as parameter

We adapt the directive so that it receives an Input parameter, composed of a resource and a type of permission.

@Input() set appIsGranted(permission: Array<string>) {  
  this.isGranted(  
    permission[0] as Resource,  
    permission[1] as PermissionType  
  );  
}

private isGranted(resource: Resource, permissionType: PermissionType) {
  if (this.permissionManagerS.isGranted(resource, permissionType)) {
    this.viewContainer.createEmbeddedView(this.templateRef);
  } else {
    this.viewContainer.clear();
  }
}
Enter fullscreen mode Exit fullscreen mode

Now, we can easily use like:

<div *appIsGranted="['PIZZA', 'CREATE']">
  // This block will only be shown to granted users
</div>

<my-component *appIsGranted="['PASTA', 'DELETE']">
  // This component will only be shown to granted users
</my-component>
Enter fullscreen mode Exit fullscreen mode

5. Stackblitz demo implementation

rjlopez-angular-permissions-part2 - StackBlitz

Top comments (0)