UNPKG

happn-3

Version:

pub/sub api as a service using primus and mongo & redis or nedb, can work as cluster, single process or embedded using nedb

65 lines (58 loc) 2.15 kB
const _ = require('lodash'); module.exports = class PermissionsTree { constructor(permissionsObj, utilsService) { this.tree = this.buildTree(permissionsObj || {}); this.utils = utilsService || require('../utils/shared'); } static create(permissionsObj) { return new PermissionsTree(permissionsObj); } buildTree(permissions) { return (this.tree = Object.keys(permissions).reduce(this.mergeBranch(permissions), {})); } mergeBranch(permissions) { return (tree, path) => _.set(tree, path.split('/').slice(path.startsWith('/') ? 1 : 0), { $leaf: path, ...permissions[path] }); } spliceActions(branch, branchSegment, actions) { if (branch[branchSegment].actions) actions.splice(actions.length - 1, 0, ...branch[branchSegment].actions); if (branch[branchSegment].action) actions.splice(actions.length - 1, 0, ...branch[branchSegment].action); if (branch[branchSegment].prohibit) actions.splice( actions.length - 1, 0, ...branch[branchSegment].prohibit.map(action => `!${action}`) ); } matchBranches(actions, permissionPath) { return (tree, segment) => { return tree.reduce((matched, branch) => { Object.keys(branch).forEach(branchSegment => { if ( branch[branchSegment].$leaf && this.utils.wildcardMatch(branch[branchSegment].$leaf, permissionPath, 'PERMISSION-PATH') ) { this.spliceActions(branch, branchSegment, actions); matched.push(branch[branchSegment]); } else if (this.utils.wildcardMatch(branchSegment, segment, 'PERMISSION-SEGMENT')) matched.push(branch[branchSegment]); }); return matched; }, []); }; } search(permissionPath, tree) { const searchTree = tree || this.tree; const actions = []; permissionPath .split('/') .slice(permissionPath.startsWith('/') ? 1 : 0) .reduce(this.matchBranches(actions, permissionPath), [{ ...searchTree }]); return [...new Set(actions)].sort(); //use spread to turn deduplicated Set back into array } };