Closed Eduardo-Julio closed 6 years ago
I see this useful +1
I personally created a component to handle this quite some time ago.
has-permission.component.js
(function() {
'use strict';
angular
.module('app')
.component('hasPermission', {
bindings: {
permission: '<'
},
templateUrl: 'app/common/permissions/has-permission/has-permission.html',
transclude: true,
controller: Controller
});
/** @ngInject */
function Controller(PermPermissionMap, PermAuthorization) {
let ctrl = this;
ctrl.$onInit = function() {
let PermissionMap = new PermPermissionMap({
only: ctrl.permission
});
let authorizationResult = PermAuthorization.authorizeByPermissionMap(PermissionMap);
authorizationResult
.then(function() {
ctrl.hasPermission = true;
})
.catch(function(rejectedPermission) {
ctrl.hasPermission = false;
});
}
}
})();
has-permission.html
<div ng-if="$ctrl.hasPermission" ng-transclude=""></div>
Usage
<has-permission permission="'panel--read'" class="col-md-6">
<div class="panel panel-app">
<div class="panel-heading">My Panel</div>
<div class="panel-content">
Must have permissions
</div>
</div>
</has-permission>
Thanks for your help, I also created a similar solution but I managed to do it using ng if in a more "direct" way.
<div has-permission="'admin'">
Only users with the permssion "admin" see this
</div>
<div has-permission="['admin', 'user']">
Only users with the permssion "admin" and "user" can see this
</div>
angular.module('app').directive('hasPermission', function(ngIfDirective, PermAuthorization, PermPermissionMap, PermPermissionStore, $rootScope) {
var ngIf = ngIfDirective[0];
return {
transclude: ngIf.transclude,
priority: ngIf.priority - 1,
terminal: ngIf.terminal,
restrict: ngIf.restrict,
scope:{
hasPermission: '@'
},
link: function(scope, element, attributes) {
scope.initialNgIf = attributes.ngIf, scope.ifEvaluator;
scope.checkAuth = function() {
// Check if the user has the permission defined on scope.hasPermission
var checkAuthPromise = PermAuthorization.authorizeByPermissionMap(new PermPermissionMap({only: eval(scope.hasPermission)}));
checkAuthPromise.then(function () {
scope.isPermitted = true
}).catch(function () {
scope.isPermitted = false
})
}
// Check on every StateChange fired by ui-permission in case the user has gained / lost his previous permissions
$rootScope.$on('$stateChangePermissionStart', function(event, toState, toParams, options) {
scope.checkAuth()
});
// The value evaluated by ng-if
attributes.ngIf = function() {
return scope.isPermitted
};
ngIf.link.apply(ngIf, arguments);
}
};
});
I dont like that the directive depends on a promise to check the permission, this is the only way I could find to make it work with ng-if but Im sure someone can make it cleaner (or event better, provide a function and not a promise to check the permissions).
This is a nagularjs service ↓
globalService.checkHasItem = (mainArray, array) => {
// mainArray: all roles will be in this array, you get these from server, for example → ['role1', 'role2', 'role3', 'role4', 'role5', 'role6', ...]
// array: some roles, for example → ['role3', 'role4']
let hasItem = false;
// with this ↓ I check if user has role
array.map((item) => {
// use this for filters → https://github.com/a8m/angular-filter#contains
if ($filter('contains')(mainArray, item)) {
hasItem = true;
}
});
return hasItem;
};
in generlCtrl.js ↓
$rootScope.checkPerms = (perms) {
return globalService.checkHasItem(userPerms, perms);
};
Now in view
<button ng-if="checkPerms(['role4'])">just user with 'role4' can click this button</button>
So a lot of people have commented about the lack of a ng-if type of behavior, this is a basic feature that almost everyone expect from a module that manages roles and permissions.
Yes, I read the docs and I know about the PermPermissionStrategies, but this is just going to make us duplicate the behavior of ng-if and we are probably going to get it wrong, I tried and couldn't make it work like ng-if.
What we can do is use the ng-if directive from angular and pass values from the permissions module so ng-if evaluates them an acts accordingly.
<div permissions ng-if="valueFromPermissions"></div>
I did some research and it seems some people have done it.
https://stackoverflow.com/questions/26907440/enable-angulars-built-in-directives-like-ng-if-to-have-access-to-a-variable-f