kindergarten
Version:
Kindergarten is a JavaScript library which helps programmers to achieve modular security using sandbox pattern
107 lines (84 loc) • 3.06 kB
JavaScript
;
exports.__esModule = true;
var _isString = require('lodash/isString');
var _isString2 = _interopRequireDefault(_isString);
var _isFunction = require('lodash/isFunction');
var _isFunction2 = _interopRequireDefault(_isFunction);
var _isUndefined = require('lodash/isUndefined');
var _isUndefined2 = _interopRequireDefault(_isUndefined);
var _utils = require('../utils');
var _errors = require('../errors');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The definition of `guard` decorator. Guard decorator is used to protect
* methods in the sandbox. You can pass the name of the rule as a first
* argument otherwise the name of the rule will be detected from name of the
* protected method. Second argument can be a callback function or return value
* that should be returned when child is not allowed to perform certain action.
*
* Example:
*
* class Foo {
* @guard
* foo() {}
*
* @guard('watch')
* bar() {}
*
* @guard('bar', '<div>Not allowed</div>')
* baz() {}
* }
*/
var guard = function guard() {
/**
* Name of the action that should be guarded.
*/
var action = arguments.length <= 0 ? undefined : arguments[0];
/**
* True if the @guard decorator is called `@guard()`
*/
var isCalled = (0, _isString2.default)(action) || arguments.length === 0;
/**
* Return callback or value that should be returned in case guard method
* throws `AccessDenied` error
*/
var callback = void 0;
if (isCalled) {
callback = arguments.length <= 1 ? undefined : arguments[1];
}
var guardFunc = function guardFunc(target, name, descriptor) {
var protectedMethod = descriptor.value;
descriptor.value = function () {
var _this = this;
for (var _len = arguments.length, protectedMethodArgs = Array(_len), _key = 0; _key < _len; _key++) {
protectedMethodArgs[_key] = arguments[_key];
}
if (!(0, _utils.isPerimeter)(this) && !(0, _utils.isSandbox)(this) && !(0, _isFunction2.default)(this.guard)) {
throw new Error('Guard decorator can only be used within perimeter or sandbox.');
}
var guardCall = function guardCall() {
return _this.guard.apply(_this, [isCalled && action ? action : name].concat(protectedMethodArgs));
};
/**
* If callback is specified and guard method throws an error. Then we
* need to return the result of the callback method;
*/
if (!(0, _isUndefined2.default)(callback)) {
try {
guardCall();
} catch (e) {
if (e instanceof _errors.AccessDenied) {
return (0, _isFunction2.default)(callback) ? callback.apply(this, protectedMethodArgs) : callback;
}
}
}
/**
* Call the guard method of the governess
*/
guardCall();
return protectedMethod.apply(this, protectedMethodArgs);
};
};
return isCalled ? guardFunc : guardFunc.apply(undefined, arguments);
};
exports.default = guard;