UNPKG

casbin

Version:

An authorization library that supports access control models like ACL, RBAC, ABAC in Node.JS

454 lines (453 loc) 16.5 kB
"use strict"; // Copyright 2018 The Casbin Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.newEnforcer = exports.newEnforcerWithClass = exports.Enforcer = void 0; const managementEnforcer_1 = require("./managementEnforcer"); const model_1 = require("./model"); const persist_1 = require("./persist"); const log_1 = require("./log"); const util_1 = require("./util"); /** * Enforcer = ManagementEnforcer + RBAC API. */ class Enforcer extends managementEnforcer_1.ManagementEnforcer { /** * initWithFile initializes an enforcer with a model file and a policy file. * @param modelPath model file path * @param policyPath policy file path */ initWithFile(modelPath, policyPath) { return __awaiter(this, void 0, void 0, function* () { const a = new persist_1.FileAdapter(policyPath); yield this.initWithAdapter(modelPath, a); }); } /** * initWithFile initializes an enforcer with a model file and a policy file. * @param modelPath model file path * @param policyString policy CSV string */ initWithString(modelPath, policyString) { return __awaiter(this, void 0, void 0, function* () { const a = new persist_1.StringAdapter(policyString); yield this.initWithAdapter(modelPath, a); }); } /** * initWithAdapter initializes an enforcer with a database adapter. * @param modelPath model file path * @param adapter current adapter instance */ initWithAdapter(modelPath, adapter) { return __awaiter(this, void 0, void 0, function* () { const m = model_1.newModel(modelPath, ''); yield this.initWithModelAndAdapter(m, adapter); this.modelPath = modelPath; }); } /** * initWithModelAndAdapter initializes an enforcer with a model and a database adapter. * @param m model instance * @param adapter current adapter instance */ initWithModelAndAdapter(m, adapter) { return __awaiter(this, void 0, void 0, function* () { if (adapter) { this.adapter = adapter; } this.model = m; this.model.printModel(); if (this.adapter) { yield this.loadPolicy(); } }); } /** * getRolesForUser gets the roles that a user has. * * @param name the user. * @param domain the domain. * @return the roles that the user has. */ getRolesForUser(name, domain) { return __awaiter(this, void 0, void 0, function* () { if (domain == null) { return this.rm.getRoles(name); } else { return this.rm.getRoles(name, domain); } }); } /** * getUsersForRole gets the users that has a role. * * @param name the role. * @param domain the domain. * @return the users that has the role. */ getUsersForRole(name, domain) { return __awaiter(this, void 0, void 0, function* () { if (domain == null) { return this.rm.getUsers(name); } else { return this.rm.getUsers(name, domain); } }); } /** * hasRoleForUser determines whether a user has a role. * * @param name the user. * @param role the role. * @param domain the domain. * @return whether the user has the role. */ hasRoleForUser(name, role, domain) { return __awaiter(this, void 0, void 0, function* () { const roles = yield this.getRolesForUser(name, domain); let hasRole = false; for (const r of roles) { if (r === role) { hasRole = true; break; } } return hasRole; }); } /** * addRoleForUser adds a role for a user. * Returns false if the user already has the role (aka not affected). * * @param user the user. * @param role the role. * @param domain the domain. * @return succeeds or not. */ addRoleForUser(user, role, domain) { return __awaiter(this, void 0, void 0, function* () { if (domain == null) { return this.addGroupingPolicy(user, role); } else { return this.addGroupingPolicy(user, role, domain); } }); } /** * deleteRoleForUser deletes a role for a user. * Returns false if the user does not have the role (aka not affected). * * @param user the user. * @param role the role. * @param domain the domain. * @return succeeds or not. */ deleteRoleForUser(user, role, domain) { return __awaiter(this, void 0, void 0, function* () { if (domain == null) { return this.removeGroupingPolicy(user, role); } else { return this.removeGroupingPolicy(user, role, domain); } }); } /** * deleteRolesForUser deletes all roles for a user. * Returns false if the user does not have any roles (aka not affected). * * @param user the user. * @param domain the domain. * @return succeeds or not. */ deleteRolesForUser(user, domain) { return __awaiter(this, void 0, void 0, function* () { if (domain == null) { return this.removeFilteredGroupingPolicy(0, user); } else { return this.removeFilteredGroupingPolicy(0, user, '', domain); } }); } /** * deleteUser deletes a user. * Returns false if the user does not exist (aka not affected). * * @param user the user. * @return succeeds or not. */ deleteUser(user) { return __awaiter(this, void 0, void 0, function* () { const res1 = yield this.removeFilteredGroupingPolicy(0, user); const res2 = yield this.removeFilteredPolicy(0, user); return res1 || res2; }); } /** * deleteRole deletes a role. * Returns false if the role does not exist (aka not affected). * * @param role the role. * @return succeeds or not. */ deleteRole(role) { return __awaiter(this, void 0, void 0, function* () { const res1 = yield this.removeFilteredGroupingPolicy(1, role); const res2 = yield this.removeFilteredPolicy(0, role); return res1 || res2; }); } /** * deletePermission deletes a permission. * Returns false if the permission does not exist (aka not affected). * * @param permission the permission, usually be (obj, act). It is actually the rule without the subject. * @return succeeds or not. */ deletePermission(...permission) { return __awaiter(this, void 0, void 0, function* () { return this.removeFilteredPolicy(1, ...permission); }); } /** * addPermissionForUser adds a permission for a user or role. * Returns false if the user or role already has the permission (aka not affected). * * @param user the user. * @param permission the permission, usually be (obj, act). It is actually the rule without the subject. * @return succeeds or not. */ addPermissionForUser(user, ...permission) { return __awaiter(this, void 0, void 0, function* () { permission.unshift(user); return this.addPolicy(...permission); }); } /** * deletePermissionForUser deletes a permission for a user or role. * Returns false if the user or role does not have the permission (aka not affected). * * @param user the user. * @param permission the permission, usually be (obj, act). It is actually the rule without the subject. * @return succeeds or not. */ deletePermissionForUser(user, ...permission) { return __awaiter(this, void 0, void 0, function* () { permission.unshift(user); return this.removePolicy(...permission); }); } /** * deletePermissionsForUser deletes permissions for a user or role. * Returns false if the user or role does not have any permissions (aka not affected). * * @param user the user. * @return succeeds or not. */ deletePermissionsForUser(user) { return __awaiter(this, void 0, void 0, function* () { return this.removeFilteredPolicy(0, user); }); } /** * getPermissionsForUser gets permissions for a user or role. * * @param user the user. * @return the permissions, a permission is usually like (obj, act). It is actually the rule without the subject. */ getPermissionsForUser(user) { return __awaiter(this, void 0, void 0, function* () { return this.getFilteredPolicy(0, user); }); } /** * hasPermissionForUser determines whether a user has a permission. * * @param user the user. * @param permission the permission, usually be (obj, act). It is actually the rule without the subject. * @return whether the user has the permission. */ hasPermissionForUser(user, ...permission) { return __awaiter(this, void 0, void 0, function* () { permission.unshift(user); return this.hasPolicy(...permission); }); } /** * getImplicitRolesForUser gets implicit roles that a user has. * Compared to getRolesForUser(), this function retrieves indirect roles besides direct roles. * For example: * g, alice, role:admin * g, role:admin, role:user * * getRolesForUser("alice") can only get: ["role:admin"]. * But getImplicitRolesForUser("alice") will get: ["role:admin", "role:user"]. */ getImplicitRolesForUser(name, ...domain) { return __awaiter(this, void 0, void 0, function* () { const res = new Set(); const q = [name]; let n; while ((n = q.shift()) != undefined) { const role = yield this.getRoleManager().getRoles(n, ...domain); role.forEach(r => { if (!res.has(r)) { res.add(r); q.push(r); } }); } return Array.from(res); }); } /** * getImplicitPermissionsForUser gets implicit permissions for a user or role. * Compared to getPermissionsForUser(), this function retrieves permissions for inherited roles. * For example: * p, admin, data1, read * p, alice, data2, read * g, alice, admin * * getPermissionsForUser("alice") can only get: [["alice", "data2", "read"]]. * But getImplicitPermissionsForUser("alice") will get: [["admin", "data1", "read"], ["alice", "data2", "read"]]. */ getImplicitPermissionsForUser(user, ...domain) { return __awaiter(this, void 0, void 0, function* () { const roles = yield this.getImplicitRolesForUser(user, ...domain); roles.unshift(user); const res = []; const withDomain = domain && domain.length !== 0; for (const n of roles) { if (withDomain) { const p = yield this.getFilteredPolicy(0, n, ...domain); res.push(...p); } else { const p = yield this.getPermissionsForUser(n); res.push(...p); } } return res; }); } /** * getImplicitUsersForPermission gets implicit users for a permission. * For example: * p, admin, data1, read * p, bob, data1, read * g, alice, admin * * getImplicitUsersForPermission("data1", "read") will get: ["alice", "bob"]. * Note: only users will be returned, roles (2nd arg in "g") will be excluded. */ getImplicitUsersForPermission(...permission) { return __awaiter(this, void 0, void 0, function* () { const res = []; const policySubjects = yield this.getAllSubjects(); const subjects = util_1.arrayRemoveDuplicates([...policySubjects, ...this.model.getValuesForFieldInPolicyAllTypes('g', 0)]); const inherits = this.model.getValuesForFieldInPolicyAllTypes('g', 1); for (const user of subjects) { const allowed = yield this.enforce(user, ...permission); if (allowed) { res.push(user); } } return res.filter(n => !inherits.some(m => n === m)); }); } } exports.Enforcer = Enforcer; function newEnforcerWithClass(enforcer, ...params) { return __awaiter(this, void 0, void 0, function* () { const e = new enforcer(); let parsedParamLen = 0; if (params.length >= 1) { const enableLog = params[params.length - 1]; if (typeof enableLog === 'boolean') { log_1.getLogger().enableLog(enableLog); parsedParamLen++; } } if (params.length - parsedParamLen === 2) { if (typeof params[0] === 'string') { if (typeof params[1] === 'string') { yield e.initWithFile(params[0].toString(), params[1].toString()); } else { yield e.initWithAdapter(params[0].toString(), params[1]); } } else { if (typeof params[1] === 'string') { throw new Error('Invalid parameters for enforcer.'); } else { yield e.initWithModelAndAdapter(params[0], params[1]); } } } else if (params.length - parsedParamLen === 1) { if (typeof params[0] === 'string') { yield e.initWithFile(params[0], ''); } else { yield e.initWithModelAndAdapter(params[0]); } } else if (params.length === parsedParamLen) { yield e.initWithFile('', ''); } else { throw new Error('Invalid parameters for enforcer.'); } return e; }); } exports.newEnforcerWithClass = newEnforcerWithClass; /** * newEnforcer creates an enforcer via file or DB. * * File: * ```js * const e = new Enforcer('path/to/basic_model.conf', 'path/to/basic_policy.csv'); * ``` * * MySQL DB: * ```js * const a = new MySQLAdapter('mysql', 'mysql_username:mysql_password@tcp(127.0.0.1:3306)/'); * const e = new Enforcer('path/to/basic_model.conf', a); * ``` * * @param params */ function newEnforcer(...params) { return __awaiter(this, void 0, void 0, function* () { return newEnforcerWithClass(Enforcer, ...params); }); } exports.newEnforcer = newEnforcer;