UNPKG

casbin

Version:

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

192 lines (191 loc) 6.21 kB
// Copyright 2017 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. // escapeAssertion escapes the dots in the assertion, // because the expression evaluation doesn't support such variable names. import { mustGetDefaultFileSystem } from '../persist'; const escapeAssertionReg = new RegExp(/([()\s|&,=!><+\-*/]|^)((r|p)[0-9]*)\./g); function escapeAssertion(s) { s = s.replace(escapeAssertionReg, (match) => { // Replace only the last dot with underscore (preserve the prefix character) const lastDotIdx = match.lastIndexOf('.'); if (lastDotIdx > 0) { return match.substring(0, lastDotIdx) + '_'; } return match; }); return s; } // removeComments removes the comments starting with # in the text. function removeComments(s) { const pos = s.indexOf('#'); return pos > -1 ? s.slice(0, pos).trim() : s; } // arrayEquals determines whether two string arrays are identical. function arrayEquals(a = [], b = []) { const aLen = a.length; const bLen = b.length; if (aLen !== bLen) { return false; } for (let i = 0; i < aLen; i++) { if (a[i] !== b[i]) { return false; } } return true; } // array2DEquals determines whether two 2-dimensional string arrays are identical. function array2DEquals(a = [], b = []) { const aLen = a.length; const bLen = a.length; if (aLen !== bLen) { return false; } for (let i = 0; i < aLen; i++) { if (!arrayEquals(a[i], b[i])) { return false; } } return true; } // arrayRemoveDuplicates removes any duplicated elements in a string array. function arrayRemoveDuplicates(s) { return [...new Set(s)]; } // arrayToString gets a printable string for a string array. function arrayToString(a) { return a.join(', '); } // paramsToString gets a printable string for variable number of parameters. function paramsToString(...v) { return v.join(', '); } // setEquals determines whether two string sets are identical. function setEquals(a, b) { return arrayEquals(a.sort(), b.sort()); } // readFile return a promise for readFile. function readFile(path, encoding) { const fs = mustGetDefaultFileSystem(); return new Promise((resolve, reject) => { try { const content = fs.readFileSync(path, encoding || 'utf8'); resolve(content); } catch (e) { reject(e); } }); } // writeFile return a promise for writeFile. function writeFile(path, file, encoding) { const fs = mustGetDefaultFileSystem(); return new Promise((resolve, reject) => { try { fs.writeFileSync(path, file, encoding || 'utf-8'); resolve(); } catch (e) { reject(e); } }); } const evalRegG = new RegExp(/\beval\(([^),]*)\)/g); const evalReg = new RegExp(/\beval\(([^),]*)\)/); // hasEval determine whether matcher contains function eval function hasEval(s) { return evalReg.test(s); } // replaceEval replace function eval with the value of its parameters function replaceEval(s, ruleName, rule) { return s.replace(`eval(${ruleName})`, '(' + rule + ')'); } // getEvalValue returns the parameters of function eval function getEvalValue(s) { const subMatch = s.match(evalRegG); const rules = []; if (!subMatch) { return []; } for (const rule of subMatch) { const index = rule.indexOf('('); rules.push(rule.slice(index + 1, -1)); } return rules; } // generatorRunSync handle generator function in Sync model and return value which is not Promise function generatorRunSync(iterator) { let { value, done } = iterator.next(); while (true) { if (value instanceof Promise) { throw new Error('cannot handle Promise in generatorRunSync, Please use generatorRunAsync'); } if (!done) { const temp = value; ({ value, done } = iterator.next(temp)); } else { return value; } } } // generatorRunAsync handle generator function in Async model and return Promise async function generatorRunAsync(iterator) { let { value, done } = iterator.next(); while (true) { if (!done) { const temp = await value; ({ value, done } = iterator.next(temp)); } else { return value; } } } function deepCopy(obj) { if (typeof obj !== 'object') return; const newObj = obj instanceof Array ? [] : {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; } } return newObj; } function customIn(a, b) { if (b instanceof Array) { return b.includes(a); } return (a in b); } function bracketCompatible(exp) { // TODO: This function didn't support nested bracket. if (!(exp.includes(' in ') && exp.includes(' ('))) { return exp; } const re = / \([^)]*\)/g; const array = exp.split(''); let reResult; while ((reResult = re.exec(exp)) !== null) { if (!reResult[0].includes(',')) { continue; } array[reResult.index + 1] = '['; array[re.lastIndex - 1] = ']'; } exp = array.join(''); return exp; } export { escapeAssertion, removeComments, arrayEquals, array2DEquals, arrayRemoveDuplicates, arrayToString, paramsToString, setEquals, readFile, writeFile, hasEval, replaceEval, getEvalValue, generatorRunSync, generatorRunAsync, deepCopy, customIn, bracketCompatible, };