UNPKG

rolet

Version:

Powerful user permission management

193 lines 6.02 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Rolet = exports.DEFAULT_ROOT = exports.debug_rolet = void 0; const debug_1 = require("debug"); const lodash_1 = require("lodash"); const lodash_uniq_1 = __importDefault(require("lodash.uniq")); const conflict_role_name_1 = require("./error/conflict_role_name"); const rnode_1 = require("./rnode"); exports.debug_rolet = (0, debug_1.debug)('rolet'); const __ = exports.debug_rolet.extend('Rolet'); exports.DEFAULT_ROOT = '_public_'; /** * Role and permission manager */ class Rolet { constructor(tree, opt) { this.opt = Object.assign({ root_name: exports.DEFAULT_ROOT }, opt); this.init(tree); } /** * Analyze Rnode tree and create cache */ analyze() { let roles = [], actions = []; const r = this.root; r.walk_down(node => { const name = node.role; if (roles.includes(name)) { throw new conflict_role_name_1.Conflict_role_name(name); } else { roles.push(name); } actions = actions.concat(node.actions || []); }); this.roles = roles; this.actions = actions; } /** * Collect complete roles upward through ancestors */ calc_complete_actions(roles) { __('calc_complete_actions() input %O', roles); roles = this.roles_normalize(roles); let r = []; for (const it of roles) { r = r.concat(this._calc_complete_values_single(it, 'actions') || []); } r = (0, lodash_uniq_1.default)((0, lodash_1.flatten)(r)); __('calc_complete_actions() output %O', r); return r; } /** * Collect complete roles upward through ancestors */ calc_complete_roles(roles) { roles = this.roles_normalize(roles); let r = []; for (const it of roles) { r = r.concat(this._calc_complete_values_single(it, 'role') || []); } return (0, lodash_uniq_1.default)(r); } /** * Collect complete roles upward through ancestors */ calc_complete_values(roles, path, direction = 'up') { roles = this.roles_normalize(roles); let r = []; for (const it of roles) { r = r.concat(this._calc_complete_values_single(it, path) || []); } return (0, lodash_uniq_1.default)(r); } /** * Permission check * @param roles * @param {T_action} action */ can(roles, action) { var _a; roles = this.roles_normalize(roles); if (this.opt.super && roles.includes(this.opt.super)) { return true; } for (let it of roles) { const actions = (_a = this .find_by_role(it)) === null || _a === void 0 ? void 0 : _a.collect_actions(); if (!(actions === null || actions === void 0 ? void 0 : actions.length)) { continue; } for (let it2 of actions) { if (it2 instanceof RegExp && typeof action === 'string' && it2.test(action)) { return true; } else { if (it2 === action) { return true; } } } } return false; } find_by_role(role_name) { return rnode_1.Rnode.find_by_role(this.root, role_name); } /** * Init rolet * @param node */ init(node) { this.load(node); this.analyze(); } /** * Is {roles} a {role}? * * is(['admin'], 'admin') --> true * is(['admin'], '_public_') --> true * is(['admin', 'employee'], 'employee') --> true * * is(['employee'], 'admin') --> false * is(['_public_'], 'admin') --> false * is(['_public_'], 'employee') --> false */ is(roles, role, { all } = { all: false }) { roles = this.roles_normalize(roles); if (this.opt.super && roles.includes(this.opt.super)) { return true; } for (const it of roles) { const collection = this._calc_complete_values_single(it, 'role'); if (!(collection === null || collection === void 0 ? void 0 : collection.length)) { continue; } if (all) { if (!collection.includes(role)) { return false; } } else { if (collection.includes(role)) { return true; } } } return !!all; } /** * Define raw tree and create rnodes */ load(node) { this.raw = Object.freeze(node); this.root = new rnode_1.Rnode(this.opt.root_name, node); } roles_normalize(roles) { if (!roles) { roles = []; } if (!Array.isArray(roles)) { roles = [roles]; } const root = this.opt.root_name; if (!roles.includes(root)) { roles.push(root); } return roles; } /** * Collect roles upward through ancestors */ _calc_complete_values_single(role, path) { __('_calc_complete_values_single() input:', arguments); let node; let r; if (role === this.opt.super) { node = this.root; r = node === null || node === void 0 ? void 0 : node.collect_values(path, 'down'); } else { node = rnode_1.Rnode.find_by_role(this.root, role); r = node === null || node === void 0 ? void 0 : node.collect_values(path); } __('_calc_complete_values_single() output:', r); return r; } } exports.Rolet = Rolet; //# sourceMappingURL=rolet.js.map