- Create the has-permission directive to enforce permissions according to the logged-in user's role as in community-app.
- Illustrate its usage with at least one component in the accounting section of the web-app.
- Initialize Directives Module
- Initialize Has Permission Directive
- Get user credentials from local/session storage (depending on whether user chose to 'remember me')
- Get user permissions from credentials
- Define
hasPermissions()
function to check if user is permitted. - Check if value passed to directive is a string, Check if value is a negation.
- Show the element if user has permission and value passed is not a negation or If user doesn't have permission but value passed is a negation.
- There are 3 main permissions 'All functions', 'All functions read' and special permissions (permissions other than former two present in user permissions array).
Unlike Community App I don't think there is need to store permissions in local storage explicitly as they aren't being utilized in any other feature than this.
I have kept the code structure similar to Angular's ngIf structural directive.
Pull Request: openMF/web-app#722
Issue: openMF/web-app#721
Accounting.html with 'All functions' Permission
Accounting.html with 'All functions read' Permission only. (Only READ_
features accessible)
Accounting.html with special permissions only
Note that none of entries in this page have special permissions, they are all covered in 'All functions' permission,
So I had to negate the above two permission grants and replace orignal permission with one of listed special permission (CREATE_REPORT
instead of CREATE_JOURNALENTRY
) to get the filtering.
Main.js Community App
// adds user permission as local storage object, not needed as user credentials already contain user permissions
$rootScope.setPermissions = function (permissions) {
$rootScope.permissionList = permissions;
localStorageService.addToLocalStorage('userPermissions', permissions);
$rootScope.$broadcast('permissionsChanged')
};
// main directive functionallity
$rootScope.hasPermission = function (permission) {
permission = permission.trim();
//FYI: getting all permissions from localstorage, because if scope changes permissions array will become undefined
$rootScope.permissionList = localStorageService.getFromLocalStorage('userPermissions');
//If user is a Super user return true
if ($rootScope.permissionList && _.contains($rootScope.permissionList, "ALL_FUNCTIONS")) {
return true;
} else if ($rootScope.permissionList && permission && permission != "") {
//If user have all read permission return true
if (permission.substring(0, 5) == "READ_" && _.contains($rootScope.permissionList, "ALL_FUNCTIONS_READ")) {
return true;
} else if (_.contains($rootScope.permissionList, permission)) {
//check for the permission if user doesn't have any special permissions
return true;
} else {
//return false if user doesn't have permission
return false;
}
} else {
//return false if no value assigned to has-permission directive
return false;
}
;
};
// on login set user permissions in local storage, not needed as in web app
// authentication service login sets user credentials in local/session storage
scope.$on("UserAuthenticationSuccessEvent", function (event, data) {
scope.authenticationFailed = false;
scope.resetPassword = data.shouldRenewPassword;
if (sessionManager.get(data)) {
scope.currentSession = sessionManager.get(data);
scope.start(scope.currentSession);
if (scope.currentSession.user && scope.currentSession.user.userPermissions) {
$rootScope.setPermissions(scope.currentSession.user.userPermissions);
}
location.path('/home').replace();
} else {
scope.loggedInUserId = data.userId;
}
;
});
// Controls user session and storage, may not be needed.
// currently no such session manager in web app
// sets user permissions on session restore
sessionManager.restore(function (session) {
scope.currentSession = session;
scope.start(scope.currentSession);
if (session.user != null && session.user.userPermissions) {
$rootScope.setPermissions(session.user.userPermissions);
localStorageService.addToLocalStorage('userPermissions', session.user.userPermissions);
}
;
});
HasPermissionDirective.js Community App
(function (module) {
mifosX.directives = _.extend(module, {
HasPermissionDirective: function ($rootScope) {
return {
// Throws error if value passed to directive is not a string
link: function (scope, element, attrs) {
if (!_.isString(attrs.hasPermission))
throw "hasPermission value must be a string";
// trim passed value to remove whitespace
var value = attrs.hasPermission.trim();
// check for negation
var notPermissionFlag = value[0] === '!';
if (notPermissionFlag) {
value = value.slice(1).trim();
}
// toggle visibility based on user permissions
function toggleVisibilityBasedOnPermission() {
var hasPermission = $rootScope.hasPermission(value);
if (hasPermission && !notPermissionFlag || !hasPermission && notPermissionFlag)
$(element).show();
else
$(element).hide();
}
// toggle visibility if user permissions changed.
// Not needed.
toggleVisibilityBasedOnPermission();
scope.$on('permissionsChanged', toggleVisibilityBasedOnPermission);
}
};
}
});
}(mifosX.directives || {}));
mifosX.ng.application.directive("hasPermission", ['$rootScope', mifosX.directives.HasPermissionDirective]).run(function ($log) {
$log.info("HasPermissionDirective initialized");
});
https://angular.io/guide/structural-directives
https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_if.ts