UNPKG

@batolye/bdk-core

Version:

Module to provide core utilities for BulusAtolyesi applications and services

158 lines (122 loc) 5.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _lodash = _interopRequireDefault(require("lodash")); var _lruCache = _interopRequireDefault(require("lru-cache")); var _debug = _interopRequireDefault(require("debug")); var _permissions = require("../../common/permissions"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const debug = (0, _debug.default)("batolye:bdk-core:authorisations:service"); // Global key to store abilities in cache for anonymous users const ANONYMOUS_USER = "anonymous"; var _default = { // Used to change permissions for a subject on a resource // We pass parameters in the query/data object // The params object should be already filled by populate hooks create(data, params) { let query = params.query; let zone = params.resourcesService.zone; // Make hook usable with query params as well let scopeName = data.scope || query.scope; // Get scope name first return Promise.all(params.subjects.map(subject => { // Then retrieve the right scope on the subject let scope = _lodash.default.get(subject, scopeName, []); // scope: user.authorisations = [{ // _id: ObjectId("5c7d473e4bea2527d8929f91"), // scope: "skills", // value: "manager", // count: 1, // permissions: "manager" // }]; // Then the target resource let resource = _lodash.default.find(scope, resource => resource._id && resource._id.toString() === params.resource._id.toString()); // On first authorisation create the resource in scope if (!resource) { resource = Object.assign({}, params.resource); if (zone) { resource.zone = typeof zone === "object" ? zone._id : zone; } scope.push(resource); } // Hooks should have populate subject/resource, // now we have to set permissions on the given subject's scope resource.permissions = data.permissions || query.permissions; // This cover the case when we create the scope on the first auth, // so that if the caller want to get back the update subject he can have it _lodash.default.set(subject, scopeName, scope); debug("Updating scope " + scopeName + " for subject " + subject._id + " on resource " + params.resource._id + ":", scope); return params.subjectsService.patch(subject._id, subject, { user: params.user }).then(subject => { this.core_updateAbilities(subject); debug("Authorisation " + data.permissions + " set for subject " + subject._id + " on resource " + params.resource._id + " with scope " + scopeName); return subject; }); })); }, // Used to remove permissions for a subject on a resource // We use ID as target resource and pass parameters in the query object // The params object should be already filled by populate hooks remove(id, params) { let query = params.query; let scopeName = query.scope; // Get scope name first return Promise.all(params.subjects.map(subject => { // Then retrieve the right scope on the subject let scope = _lodash.default.get(subject, scopeName, []); // Then the target resource scope = scope.filter(resource => resource._id && resource._id.toString() !== id.toString()); // This cover the case when we create the scope on the first auth, // so that if the caller want to get back the update subject he can have it _lodash.default.set(subject, scopeName, scope); // Skip patching if the subject is currently deleted if (!subject.deleted) { debug("Updating scope " + scopeName + " for subject " + subject._id + " on resource " + id + ":", scope); return params.subjectsService.patch(subject._id, subject, { user: params.user }).then(subject => { this.core_updateAbilities(subject); debug("Authorisation unset for subject " + subject._id + " on resource " + id + " with scope " + scopeName); return subject; }); } else { return Promise.resolve(subject); } })); }, setup(app) { const config = app.get("authorisation"); if (config && config.cache) { // Store abilities of the N most active users in LRU cache (defaults to 1000) this.cache = new _lruCache.default(config.cache.maxUsers || 1000); debug("Using LRU cache for user abilities"); } else { debug("Do not use LRU cache for user abilities"); } }, // Compute abilities for a given user and set it in cache the first time // or get it from cache if found // subject: hook.params.user core_getAbilities(subject) { if (this.cache) { if (subject && subject._id) { if (this.cache.has(subject._id.toString())) return this.cache.get(subject._id.toString()); } else { if (this.cache.has(ANONYMOUS_USER)) return this.cache.get(ANONYMOUS_USER); } } let abilities = (0, _permissions.defineAbilities)(subject); if (this.cache) { if (subject && subject._id) { this.cache.set(subject._id.toString(), abilities); } else { this.cache.set(ANONYMOUS_USER, abilities); } } return abilities; }, // Compute abilities for a given user and update it in cache core_updateAbilities(subject) { if (this.cache) { if (subject && subject._id) { this.cache.del(subject._id.toString()); } else { this.cache.del(ANONYMOUS_USER); } } return this.core_getAbilities(subject); } }; exports.default = _default;