Skip to content

Controlling access in views

Błażej Krysiak edited this page May 28, 2016 · 14 revisions

Before start

Make sure you are familiar with:

Overview

  1. Permission directive
  2. Basic usage
  3. Custom behaviour
  4. Async calls for permissions in initial state

Permission directive

Permission module exposes directive permission that can show/hide elements of your application based on set of permissions.

Permission directive accepts several attributes:

Attribute Value Description
permission-only [String|Array] Single or multiple roles/permissions allowed to access content
permission-except [String|Array] Single or multiple roles/permissions denied to access content
permission-on-authorized [Function] Custom function invoked when authorized
permission-on-unauthorized [Function] Custom function invoked when unauthorized

Basic usage

Directives accepts either single permission that has to be met in order to display it's content:

<div permission 
     permission-only="'canReadInvoice'">
  <span>Congrats! You are logged in.</span>  
</div>

Or set of permissions separated by 'coma':

<div permission 
     permission-except="['USER','ADMIN']">
  <span>You are not 'ADMIN' nor 'USER'.</span>  
</div>

🔥 Important
Do not use permission directive outside ui-view/ng-view, as they are only html elements, that content respond to router state/route changes.

Custom behaviour

By default permission directive is manipulating classes DOM elements by adding or removing ng-hide class using hideElement and showElement behaviour strategies. But permission module exposes additional strategies or even custom function allowing to customize the way elements are being rendered or decorated.

Built in behaviours are stored in PermissionStrategies value containing:

Value Behaviour
enableElement Removes disabled attribute from element
disableElement Adds disabled attribute to element
showElement Removes ng-hide class showing element
hideElement Adds ng-hide class hiding element

To use different strategy pass it as value to permission-on-authorized and permission-on-unauthorized params:

<button 
     type="button" 
     permission 
     permission-only="'canEditInvoice'"
     permission-on-authorized="PermissionStrategies.enableElement"
     permission-on-unauthorized="PermissionStrategies.disableElement">
  Edit Invoice  
</button>

Or you can provide custom function defined inside controller or link function that will be invoked based on authorization results:

angular.controller('InvoiceController', function($scope){
  $scope.onAuthorized = function(element){ 
    element.prepend('<span>Great!</span>');
  };
  
  $scope.onUnauthorized = function(element){ 
    element.prepend('<span>Sad!</span>');
  };
});

And then passed in view to permission attributes:

<button 
     type="button" 
     permission 
     permission-only="'canEditInvoice'"
     permission-on-authorized="onAuthorized"
     permission-on-unauthorized="onUnauthorized">
  Edit Invoice  
</button>

🔥 Important
Notice that functions are being passed as reference (without brackets ()). It is required to allow later invocation. If you pass function with brackets, they simply won't work.

Async calls for permissions in initial states

When using async calls to fetch permissions in initial states make sure that modules (or app) are waiting for permissions to be resolved before running them. To ensure that you should use deferIntercept to create delayed router start.

 var app = ng.module('app', ['ui.router', 'permission', 'permission.ui']);
 
 app
  .config(function ($urlRouterProvider) {
    [...]

    // Prevent router from automatic state resolving
    $urlRouterProvider.deferIntercept();
  })
  .run(function($urlRouter, $http){
    // Example ajax call
    $http
      .get('/permissions')
      .then(function(permissions){
        // Use RoleStore and PermissionStore to define permissions and roles 
        // or even set up whole session
      })
      .then(function(){
        // Once permissions are set-up 
        // kick-off router and start the application rendering
        $urlRouter.sync();
        // Also enable router to listen to url changes
        $urlRouter.listen();
      });
 });

Next to read: 👉 Installation guide for ui-router
Next to read: 👉 Installation guide for ng-route