rbac-engine
Version:
Role-based access control engine with policy-based permissions
81 lines • 3.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.evaluate = exports.isStatementActive = exports.matches = exports.evaluateCondition = void 0;
const evaluateCondition = (condition, context) => Object.entries(condition).every(([key, value]) => context[key] === value);
exports.evaluateCondition = evaluateCondition;
const escapeRegExp = (string) => string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
const matches = (pattern, value) => {
if (Array.isArray(pattern)) {
return pattern.some(p => (0, exports.matches)(p, value));
}
if (pattern.includes('*')) {
const regexString = "^" + pattern.split('*').map(escapeRegExp).join('.*') + "$";
const regex = new RegExp(regexString);
return regex.test(value);
}
return pattern === value;
};
exports.matches = matches;
const isStatementActive = (statement) => {
const now = new Date();
if (statement.StartDate) {
try {
const startDate = new Date(statement.StartDate);
if (isNaN(startDate.getTime())) {
console.warn(`Invalid StartDate format in policy statement: ${statement.StartDate}`);
return false;
}
if (now.getTime() < startDate.getTime()) {
return false;
}
}
catch (e) {
console.warn(`Error parsing StartDate: ${e}`);
return false;
}
}
if (statement.EndDate) {
try {
const endDate = new Date(statement.EndDate);
if (isNaN(endDate.getTime())) {
console.warn(`Invalid EndDate format in policy statement: ${statement.EndDate}`);
return false;
}
if (now.getTime() > endDate.getTime()) {
return false;
}
}
catch (e) {
console.warn(`Error parsing EndDate: ${e}`);
return false;
}
}
return true;
};
exports.isStatementActive = isStatementActive;
const evaluate = (policies, action, resource, context = {}) => {
let isAllowed = false;
for (const policy of policies) {
const { document } = policy;
const statements = Array.isArray(document.Statement) ? document.Statement : [document.Statement];
for (const statement of statements) {
if (!(0, exports.isStatementActive)(statement)) {
continue;
}
if (statement.Condition && !(0, exports.evaluateCondition)(statement.Condition, context)) {
continue;
}
if ((0, exports.matches)(statement.Action, action) && (0, exports.matches)(statement.Resource, resource)) {
if (statement.Effect === 'Allow') {
isAllowed = true;
}
else if (statement.Effect === 'Deny') {
return false;
}
}
}
}
return isAllowed;
};
exports.evaluate = evaluate;
//# sourceMappingURL=evaluator.js.map