UNPKG

@parthar/rbac

Version:

Role Based Access Control

116 lines (99 loc) 3.09 kB
"use strict"; const promisify = require("util").promisify; // Grant => Role & Permissions // store => roles & permissions are strings // getRoles() // getRolePermissions(role) // setRolePermissions(role, permissions) // deleteRole(role) const Permissions = require("./Permissions"); async function can(store, roles, resource, action) { let idx; let ret = false; for (idx = 0; idx < roles.length; idx++) { // eslint-disable-line no-magic-numbers ret = new Permissions( await store.getRolePermissions(roles[idx]) // eslint-disable-line no-await-in-loop ).can(resource, action); if (ret) { break; } } return ret; } async function commit(that) { let pArr; if (!that._role) { throw new Error("set role before including roles"); } pArr = that._inherits.map(async (role) => { let permStrs = await that.permissions4role(role); if (!permStrs || permStrs instanceof Error) { throw new Error("cannot inherit from non-existent role: " + role); } that._permissions.include(new Permissions(permStrs)); }); await Promise.all(pArr); // wait to get all inherited-perms that._deny.forEach(function eachPerm(pem) { that._permissions.exclude(pem); }); await that._store.setRolePermissions(that._role, that._permissions.export()); delete that._role; delete that._inherits; delete that._deny; delete that._permissions; } class Grants { constructor(store) { this._store = store; } listRoles(callback) { return callback ? this._store.getRoles(callback) : promisify(this._store.getRoles)(); } permissions4role(role, callback) { return callback ? this._store.getRolePermissions(role, callback) : promisify(this._store.getRolePermissions)(role); } deleteRole(role, callback) { return callback ? this._store.deleteRole(role, callback) : promisify(this._store.deleteRole)(role); } can(roles, resource, action, callback) { return callback ? can(this._store, roles, resource, action) .then(res => callback(null, res)) .catch(err => callback(err)) : can(this._store, roles, resource, action); } // fluent api role(role) { this._role = role; this._inherits = []; this._deny = []; this._permissions = new Permissions(); return this; } inherits(arr) { this._inherits = this._inherits.concat(arr); return this; } allow(permsObj) { this._permissions.include(permsObj); return this; } deny(permsObj) { this._deny.push(permsObj); return this; } commit(callback) { return callback ? commit(this) .then(() => callback(null)) .catch(err => callback(err)) : commit(this); } } module.exports = Grants;