UNPKG

@incdevco/framework

Version:
198 lines (102 loc) 3.64 kB
'use strict'; var Promise = require('bluebird'); var Utilities = require('../utilities'); class ACL { constructor() { this.parents = {}; this.resources = {}; this.rules = {}; } allow(role, resource, privileges, assertion) { var self = this; resource = resource || '*'; privileges = privileges || '*'; if (typeof assertion !== 'function') { assertion = true; } if (!Array.isArray(privileges)) { privileges = [privileges]; } this.rules[role] = this.rules[role] || {}; this.resources[resource] = this.resources[resource] || {}; this.rules[role][resource] = this.rules[role][resource] || {}; privileges.forEach(function(privilege) { self.resources[resource][privilege] = assertion; self.rules[role][resource][privilege] = assertion; }); return this; } getRoleParents(role, parents) { var first, rolesParents, self = this; first = (parents) ? false : true; parents = parents || []; rolesParents = this.parents[role] || []; parents = parents.concat(rolesParents); rolesParents.forEach(function (rolesParent) { parents = self.getRoleParents(rolesParent, parents); }); if (first) { // run only once // remove duplicates parents = Utilities.unique(parents); } return parents; } inherit(role, parents) { this.parents[role] = this.parents[role] || []; this.parents[role] = this.parents[role].concat(parents); return this; } isAllowed(role, resource, privileges, locals) { var promise = Promise.resolve(false), roles = [role], self = this; roles = roles.concat(this.getRoleParents(role)); roles.forEach(function (role) { promise = promise.then(function (result) { if (result) { // is allowed return result; } else { // not allowed, try next one return self.isRoleAllowed(role, resource, privileges, locals); } }); }); return promise; } isRoleAllowed(role, resource, privileges, locals) { var promises= [], self = this; if (!Array.isArray(privileges)) { privileges = [privileges]; } privileges.forEach(function(privilege) { promises.push(self.isRoleAllowedPrivilege(role, resource, privilege, locals)); }); return Promise.all(promises) .then(function (results) { var allowed = false; var notAllowed = false; results.forEach(function (result) { if (!result) { notAllowed = true; } }); if (!notAllowed) { allowed = true; } return allowed; }); } isRoleAllowedPrivilege(role, resource, privilege, locals) { var self = this; return Promise.try(function () { var assertion = false; if (self.rules[role] && self.rules[role][resource]) { assertion = self.rules[role][resource][privilege]; if (assertion && typeof assertion === 'function') { return assertion(locals); } } return assertion; }); } } module.exports = ACL;