Skip to content

Controlling access in views

AlexKhymenko edited this page Mar 27, 2018 · 16 revisions

Overview

  1. Permission directive
  2. Basic usage
  3. Custom behaviour

Permission directive

Permission module exposes directive ngxPermissionsOnly and ngxPermissionsExcept that can show/hide elements of your application based on set of permissions and roles.

🔥 Important
Else, then syntax is supported.
Note if you use then block don't put anything in main block it will be not visible, only then block will be used.

Permission directive accepts several attributes:

Attribute Value Description
ngxPermissionsOnly [String | String[]] Single or multiple permissions allowed to access content
ngxPermissionsExcept [String | String[]] Single or multiple permissions denied to access content
(permissionsAuthorized) EventEmitter EventEmitter emitted when authorized
(permissionsUnauthorized) EventEmitter EventEmitter emitted when unAuthorized

Basic usage

Directives accepts either single permission or roles that has to be met in order to display it's content, You can use both ngxPermissionsOnly and ngxPermissionsExcept at the same time:

<ng-template [ngxPermissionsOnly]="['ADMIN']" (permissionsAuthorized)="yourCustomAuthorizedFunction()" (permissionsUnauthorized)="yourCustomAuthorizedFunction()">
    <div>You can see this text congrats</div>
 </ng-template>
 <ng-template [ngxPermissionsOnly]="'ADMIN'"  [ngxPermissionsExcept]="'Manager'">
    <div>You can see this text congrats</div>
 </ng-template>
  <ng-template ngxPermissionsOnly="ADMIN">
    <div>You can see this text congrats</div>
 </ng-template>
 
 <ng-template [ngxPermissionsExcept]="['JOHNY']">
   <div> All will see it except JOHNY</div>
 </ng-template>

Or set of permissions separated by 'coma':

<ng-template [ngxPermissionsOnly]="['ADMIN', 'GUEST']">
    <div>You can see this text congrats</div>
</ng-template>

 <ng-template [ngxPermissionsExcept]="['ADMIN', 'JOHNY']">
   <div>All will see it except admin and Johny</div>
 </ng-template>
  <ng-template [ngxPermissionsExcept]="['ADMIN', 'JOHNY']" [ngxPermissionsOnly]="['MANAGER']">
    <div>All will see it except admin and Johny</div>
  </ng-template>
  
  <ng-template [ngxPermissionsExcept]="['MANAGER']" 
  [ngxPermissionsExceptThen]="thenBlock" 
  [ngxPermissionsExceptElse]="elseBlock">
    </ng-template>
   <ng-template #elseBlock>
       <div>elseBlock</div>
   </ng-template>
   <ng-template #thenBlock>
       <div>thenBlock</div>
   </ng-template>
   
   <ng-template
     [ngxPermissionsOnly]="['MANAGER']" 
     [ngxPermissionsOnlyThen]="thenBlock" 
     [ngxPermissionsOnlyElse]="elseBlock">
       </ng-template>
      <ng-template #elseBlock>
          <div>elseBlock</div>
      </ng-template>
      <ng-template #thenBlock>
          <div>thenBlock</div>
      </ng-template>
    
    
 

Or just simply by *

<div *ngxPermissionsOnly="['ADMIN', 'GUEST']">
    <div>You can see this text congrats</div>
</div>

// To not create div use <ng-container></ng-container>
<ng-container *ngxPermissionsOnly="['ADMIN', 'GUEST']">
    <div>You can see this text congrats</div>
</ng-container>

 <div *ngxPermissionsOnly="['THEN_BLOCK']; else elseBlock; then thenBlock">main</div>
     <ng-template #elseBlock>
         <div>elseBlock</div>
     </ng-template>
     <ng-template #thenBlock>
         <div>thenBlock</div>
     </ng-template>
     
 <div *ngxPermissionsExcept="['THEN_BLOCK']; else elseBlock; then thenBlock"></div>
       <ng-template #elseBlock>
           <div>elseBlock</div>
       </ng-template>
       <ng-template #thenBlock>
           <div>thenBlock</div>
       </ng-template>

Note: You cant use * style with other * style directives like *ngIf. You should wrap them. And YES i don't like it either.

 <div *ngxPermissionsOnly="['ADMIN', 'GUEST']">
  <div *ngIf="true">
    You can see this text congrats
  </div>
 </div>

🔥 Important
Using with except and only together should use ngxPermissionsElse or ngxPermissionsThen

    <ng-template [ngxPermissionsExcept]="'FAIL_BLOCK'" 
    [ngxPermissionsOnly]="'ONLY_BLOCK'"
    [ngxPermissionsElse]="elseBlock"
    [ngxPermissionsThen]="thenBlock">
              
    </ng-template>
    <ng-template #elseBlock>
        <div>elseBlock</div>
    </ng-template>
    <ng-template #thenBlock>
        <div>thenBlock</div>
    </ng-template>

Custom behaviour

By default permission directive is manipulating classes DOM elements by adding or removing element from DOM using remove and show behaviour strategies. But permission module exposes additional this 2 strategies or even custom function allowing to customize the way elements are being rendered or decorated.

Built in behaviours are stored in NgxPermissionsPredefinedStrategies enum value containing:

Value Behaviour
remove Removes element from DOM
show Adds element to Dom

To use different strategy pass it as value to authorisedStrategy and unauthorisedStrategy params:

<button  *ngxPermissionsOnly="'ADMIN'; authorisedStrategy: 'show'; unauthorisedStrategy: 'remove'">
     <div>Show me</div>
</button>

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

@Component({selector: 'test-comp',
        template: `
        <button  *ngxPermissionsOnly="'ADMIN'; authorisedStrategy: disabledFunc; unauthorisedStrategy: enableFunc">
            <div>123</div>
         </button>`})
    class TestComp {
        data: any;

        constructor(private renderer2: Renderer2){}

        public disabledFunc(templateRef: TemplateRef<any>) {
             this.renderer2.setAttribute(tF.elementRef.nativeElement.nextSibling, 'disabled', 'true');
        }

       // sometimes it can loose this reference so its better to write like this
       public disabledFunc = (templateRef: TemplateRef<any>) => {
             this.renderer2.setAttribute(tF.elementRef.nativeElement.nextSibling, 'disabled', 'true');
        }
        public enableFunc = (templateRef: TemplateRef<any>) => {
                this.renderer2.removeAttribute(tF.elementRef.nativeElement.nextSibling, 'disabled');
        }
    }

🔥 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.

Changing default directive behaviour

In some situations you may want to use different behaviour in all permission directives without the the need to add authorisedStrategy and unauthorisedStrategy everywhere across your code. To do that you should to use NgxConfigurationService available.

It exposes two methods setDefaultOnAuthorizedStrategy and setDefaultOnUnauthorizedStrategy that accepts as a string. Feel free to extend it and provide your own methods implementation there. You can set up it in your main appComponent or before app starts. If it cant find strategy it will throw an error. Also You can isolate ngxPermissionsConfiguration for child modules.

        this.ngxPermissionsConfigurationService.addPermissionStrategy('disable', (templateRef: TemplateRef) => {
             this.renderer2.setAttribute(tF.elementRef.nativeElement.nextSibling, 'disabled', 'true');
              //or directly not recommended
             templateRef.elementRef.nativeElement.nextSibling.setAttribute('disabled', true)
        });

       this.ngxPermissionsConfigurationService.setDefaultOnAuthorizedStrategy('disable');

       or 

       this.ngxPermissionsConfigurationService.setDefaultOnUnauthorizedStrategy('disable')