kindergarten
Version:
Kindergarten is a JavaScript library which helps programmers to achieve modular security using sandbox pattern
158 lines (113 loc) • 5.34 kB
JavaScript
;
exports.__esModule = true;
exports.default = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _each = require('lodash/each');
var _each2 = _interopRequireDefault(_each);
var _isEmpty = require('lodash/isEmpty');
var _isEmpty2 = _interopRequireDefault(_isEmpty);
var _isFunction = require('lodash/isFunction');
var _isFunction2 = _interopRequireDefault(_isFunction);
var _isString = require('lodash/isString');
var _isString2 = _interopRequireDefault(_isString);
var _AllowedMethodsService = require('./utils/AllowedMethodsService');
var _AllowedMethodsService2 = _interopRequireDefault(_AllowedMethodsService);
var _Logger = require('./Logger');
var _Logger2 = _interopRequireDefault(_Logger);
var _utils = require('./utils');
var _errors = require('./errors');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Definition of Purpose class.
*
* Purpose is a connection between Sandbox and Perimeter.
* Whenever a Perimeter is added to a Sandbox new Purpose is created.
* And all exposed methods from Perimeter and copied to Purpose.
* Purpose should have as less methods as possible.
* Purpose is used internally by Sandbox and shouldn't be used as standalone
* object.
*/
var Purpose = function () {
/**
* Create new instance of purpose.
*/
function Purpose(name, sandbox) {
_classCallCheck(this, Purpose);
this._name = name;
this._sandbox = sandbox;
if (!(0, _isString2.default)(this._name)) {
throw new _errors.ArgumentError('Purpose must have a name.');
}
if (!(0, _utils.isSandbox)(this._sandbox)) {
throw new _errors.ArgumentError('Purpose must have a sandbox.');
}
}
/**
* Load perimeter & copy all exposed method into the purpose.
* This method is used internally by Sandbox and it is not recommended to use
* it externally.
*/
_createClass(Purpose, [{
key: '_loadPerimeter',
value: function _loadPerimeter(perimeter) {
var _this = this;
if (!(0, _utils.isPerimeter)(perimeter)) {
throw new _errors.ArgumentError('Cannot load perimeter. Is it an instance of perimeter?');
}
var exposedMethods = perimeter.expose;
var allowedMethodsService = new _AllowedMethodsService2.default(this, false);
if ((0, _isEmpty2.default)(exposedMethods)) return;
(0, _each2.default)(exposedMethods, function (exposedMethod) {
if (allowedMethodsService.isRestricted(exposedMethod)) {
throw new _errors.RestrictedMethodError('Cannot create a method ' + exposedMethods + '. It is restricted.');
}
if ((0, _isFunction2.default)(_this[exposedMethod])) {
_Logger2.default.warn('Overriding already sandboxed method ' + _this._name + '.' + exposedMethod + '.');
}
if (!(0, _isFunction2.default)(perimeter[exposedMethod])) {
throw new _errors.NoExposedMethodError('The exposed method ' + exposedMethod + ' is not defined on perimeter ' + perimeter.purpose + '.');
}
// Call the method in context of perimeter and governed by a governess
_this[exposedMethod] = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return perimeter.governed(perimeter[exposedMethod], args, perimeter);
};
});
}
/**
* Return true if perimeter is allowed to perform an action. It uses the
* governess of the perimeter.
*/
}, {
key: 'isAllowed',
value: function isAllowed() {
var _perimeter$purposeGov;
var perimeter = this._sandbox.getPerimeter(this._name);
return perimeter.hasOwnGoverness() ? perimeter.isAllowed.apply(perimeter, arguments) : (_perimeter$purposeGov = perimeter.purposeGoverness).isAllowed.apply(_perimeter$purposeGov, arguments);
}
/**
* Return true if perimeter is not allowed to perform an action. It uses the
* governess of the perimeter.
*/
}, {
key: 'isNotAllowed',
value: function isNotAllowed() {
return !this.isAllowed.apply(this, arguments);
}
/**
* Forward guard call to governess.
*/
}, {
key: 'guard',
value: function guard() {
var _perimeter$purposeGov2;
var perimeter = this._sandbox.getPerimeter(this._name);
return perimeter.hasOwnGoverness() ? perimeter.guard.apply(perimeter, arguments) : (_perimeter$purposeGov2 = perimeter.purposeGoverness).guard.apply(_perimeter$purposeGov2, arguments);
}
}]);
return Purpose;
}();
exports.default = Purpose;