@parthar/rbac
Version:
Role Based Access Control
116 lines (99 loc) • 3.09 kB
JavaScript
;
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;