Skip to content

Managing permissions

Yitzhak Andrade edited this page Jul 25, 2018 · 15 revisions

Overview

  1. Introduction
  2. Defining permissions
  3. Individual permissions
  4. Multiple permissions
  5. Removing permissions
  6. Retrieving permission definitions

Introduction

Let's start with little explanation what permission is. Permission is the most atomic ability that a user can have in your application. So you can think about permission as a smallest action that user can do inside your site.

But can user or anonymous be a permission? Technically yes, but from business point of view you should treat them as Roles that are more complex objects that can store more complex logic.

💡 Note
It's a good convention to start permission with a verb and combine them with resource or object, so permissions like readDocuments or listSongs are meaningful and easy to understand for other programmes. Notice that they are named lowerCamelCase for easy differentiation form roles.

Defining permissions

So, how do you tell Permission what does 'readDocuments' or 'listSongs' mean and how to know if the current user belongs to those definitions?

Well, Permission allows you to set different 'permissions' definitions along with the logic that determines if the current session belongs to them. To do that library exposes special container PermPermissionStore that allows you to manipulate them freely.

Individual permissions

To define permissions individually PermPermissionStore exposes method definePermission that generic usage is shown below:

[...]

PermPermissionStore
  .definePermission('permissionName', /*@ngInject*/ function (permissionName, transitionProperties) {
        [...]
      });
  });

Validation function are injected with any angular services. There are 2 local injectables available that can be used to implement more complex validation logic.

Injectable Local Description
permissionName String representing name of checked permission
transitionProperties TransitionProperties object storing properties of transited states/routes

It also have to return one of values to properly represent results:

Validation result Returned value
Valid [true|$q.resolve()]
Invalid [false|$q.reject()]

💡 Note
You can not define permissions on config stage of modules.

Knowing that let's consider deadly simple example for defining permission. We want user to create seeDashboard permission that not corresponds to any server-related permissions. We can do that inside our top level app module in run section.

angular
  .module('app', ['permission'])
  .run(function (PermPermissionStore) {
    PermPermissionStore
      .definePermission('seeDashboard', function () {
        return true;
      });
  });

In the example above permission seeDashboard is always valid as it always returns true. So as long it's not removed from the PermPermissionStore will always allow user to pass authorization.

Sometimes you will need to call some a back-end api or do some other asynchronous task to check if permission is still valid. For that you can use promises and simply return them from validation function:

PermPermissionStore
  // Define user permission calling back-end
  .definePermission('hasValidSession', /*@ngInject*/function (Session) {
    // Let's assume that Session service calls backend API via $http and return promise:
    // -- $q.resolve() means that session is active 
    // -- $q.reject() means that session expired
    return Session.checkSession();
  });

Multiple permissions

To define multiple permissions that share same validation method method defineManyPermissions can be used. The only difference from definePermission is that it accepts Array of permission names instead of single one.

  [...]
  .defineManyPermissions('permissionNamesArray', /*@ngInject*/ function (permissionName, transitionProperties) {
        [...]
      });
  });

Often meet example of usage is set of permissions (e.g. received from server after user login) that you will iterate over to check if permission is valid. An example implementation of that showing with little lodash magic is shown below:

var permissions = ['listMeeting', 'seeMeeting', 'editMeeting', 'deleteMeeting']

PermPermissionStore.defineManyPermissions(permissions, /*@ngInject*/ function (permissionName) {
  return _.includes(permissions, permissionName);
});

Removing permissions

You can easily remove all permissions form the PermPermissionStore (e.g. after user logged out or switched profile) by calling:

PermPermissionStore.clearStore();

Alternatively you can use removePermissionDefinition to delete defined permissions manually:

PermPermissionStore.removePermissionDefinition('user');

Retrieving permission definitions

To get specific permission use method getPermissionDefinition:

var permissions = PermPermissionStore.getPermissionDefinition('permissionName');

And to get all user permissions use method getStore:

var permissions = PermPermissionStore.getStore();

Next to read: 👉 Managing roles