@jiumao/policy
Version:
[](https://npmjs.org/package/@jiumao/policy) [](https://npmjs.org/package/@jiumao/policy)
196 lines (148 loc) • 4.8 kB
JavaScript
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
}
}
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
function isString(value) {
return typeof value === 'string';
}
function isArray(value) {
return Array.isArray(value) || value instanceof Array;
}
var Policy = function Policy(actions) {
var _this = this;
_classCallCheck(this, Policy);
this.actions = actions;
this.moduleMap = {};
this.getModuleMap = function () {
var actions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var moduleMap = {};
if (actions && actions.length) {
actions.forEach(function (item) {
var moduleName = item.module;
var policyAction = "".concat(item.module, "/").concat(item.action);
if (!moduleMap[moduleName]) {
moduleMap[moduleName] = [policyAction];
} else {
moduleMap[moduleName].push(policyAction);
}
});
}
return moduleMap;
}; // 需要验证组合条件时
// eg: '((goods/create && !goods/list) && goods/info) || * || goods/info'
this.combinationVerify = function (actionStr) {
var reg = /([\w|\d|\*]+\/[\w|*]+)|\*/g;
var matchList = actionStr.match(reg);
matchList.map(function (item) {
var result = _this.singleVerify(item) ? 'true' : 'false';
actionStr = actionStr.replace(/([\w|\d|\*]+\/[\w|*]+)|\*/, result);
});
return !!eval(actionStr);
}; // 验证Action
this.multipleVerify = function (actions) {
if (isString(actions)) {
return _this.singleVerify(actions);
}
if (isArray(actions)) {
for (var i = 0, len = actions.length; i < len; i++) {
var result = _this.singleVerify(actions[i]);
if (!result) {
return false;
}
}
return true;
}
}; // 验证单个action
// * | 'module1/action1'
this.singleVerify = function (action) {
// 表示任何用户皆可以访问
if (action === '*') {
return true;
} else {
// 命中不允许使用的权限
if (_this.denyActions.includes(action)) {
return false;
}
if (_this.allowActions.includes(action)) {
return true;
}
} // 默认不允许访问
return false;
};
this.addPolicy = function (policy) {
if (!policy) return;
var statement = policy.statement;
if (statement && statement.length) {
statement.forEach(function (item) {
var effect = item.effect,
action = item.action;
var actions = [];
if (isString(action)) {
actions = _this.parseAction(action);
}
if (isArray(action)) {
action.forEach(function (item) {
actions = actions.concat(_this.parseAction(item));
});
}
if (effect === 'allow') {
var actionList = _this.allowActions.concat(actions);
_this.allowActions = _toConsumableArray(new Set(actionList));
return;
}
if (effect === 'deny') {
var _actionList = _this.denyActions.concat(actions);
_this.denyActions = _toConsumableArray(new Set(_actionList));
return;
}
});
}
}; // 解析Action
this.parseAction = function (action) {
var actions = _this.getAllAction();
var result = [];
if (action === '*') {
result = actions;
} else {
var list = action.split('/');
if (list.length === 2) {
var moduleName = list[0];
var actionName = list[1];
if (actionName === '*') {
actions.length && (result = _this.moduleMap[moduleName] || []);
} else {
result = [action];
}
}
}
return result;
}; // 获取所有的Action
this.getAllAction = function () {
var actions = [];
var modules = Object.keys(_this.moduleMap);
modules.forEach(function (key) {
actions = actions.concat(_this.moduleMap[key]);
});
return actions;
}; // 模块的操作集合
this.moduleMap = this.getModuleMap(actions); // 允许的操作
this.allowActions = []; // 拒绝的操作
this.denyActions = [];
};
export default Policy;