deep-security
Version:
DEEP Security Library
434 lines (330 loc) • 12.4 kB
JavaScript
/**
* Created by mgoria on 6/17/15.
*/
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Security = 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 _deepKernel = require('deep-kernel');
var _deepKernel2 = _interopRequireDefault(_deepKernel);
var _deepCore = require('deep-core');
var _deepCore2 = _interopRequireDefault(_deepCore);
var _Exception = require('./Exception/Exception');
var _Token = require('./Token');
var _LocalToken = require('./LocalToken');
var _FrontendUserProvider = require('./FrontendUserProvider');
var _BackendUserProvider = require('./BackendUserProvider');
var _IdentityProvider = require('./IdentityProvider');
var _LocalIdentityProvider = require('./LocalIdentityProvider');
var _RoleResolver = require('./RoleResolver');
var _RoleProvider = require('./RoleProvider');
var _util = require('util');
var _util2 = _interopRequireDefault(_util);
var _crypto = require('crypto');
var _crypto2 = _interopRequireDefault(_crypto);
var _awsSdk = require('aws-sdk');
var _awsSdk2 = _interopRequireDefault(_awsSdk);
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"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Deep Security implementation
*/
let Security = exports.Security = function (_Kernel$ContainerAwar) {
_inherits(Security, _Kernel$ContainerAwar);
/**
* Defines all class private properties
*
* @param {String} identityPoolId
* @param {Object} identityProviders
*/
function Security() {
let identityPoolId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
let identityProviders = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Security);
var _this = _possibleConstructorReturn(this, (Security.__proto__ || Object.getPrototypeOf(Security)).call(this));
_this._identityPoolId = identityPoolId;
_this._identityProviders = identityProviders;
_this._token = null;
_this._userProvider = null;
_this._userProviderEndpoint = null;
_this._userModelName = null;
_this._roleProviderEndpoint = null;
_this._roleResolver = null;
_this._roleProvider = null;
return _this;
}
/**
* @returns {String}
*/
_createClass(Security, [{
key: 'boot',
/**
* Booting a certain service
*
* @param {Kernel} kernel
* @param {Function} callback
*/
value: function boot(kernel, callback) {
let globals = kernel.config.globals;
this._identityPoolId = kernel.config.identityPoolId;
this._identityProviders = kernel.config.identityProviders || {};
this._userProviderEndpoint = globals.userProviderEndpoint || null;
this._userModelName = globals.userModelName || 'User';
this._roleProviderEndpoint = globals.roleProviderEndpoint || null;
callback();
}
/**
* @inheritDoc
*/
}, {
key: 'cleanup',
value: function cleanup() {
this.roleProvider.invalidateCache();
if (this._token) {
this._token.user = null;
}
}
/**
* @returns {null|Token}
*/
}, {
key: 'login',
/**
* @param {String} providerName
* @param {Object} identityMetadata
* @param {Function} callback
* @returns {Token}
*/
value: function login(providerName, identityMetadata, callback) {
let TokenImplementation = _LocalToken.LocalToken;
let IdentityProviderImplementation = _LocalIdentityProvider.LocalIdentityProvider;
if (!this._localBackend) {
TokenImplementation = _Token.Token;
IdentityProviderImplementation = _IdentityProvider.IdentityProvider;
}
let identityProvider = new IdentityProviderImplementation(this._identityProviders, providerName, identityMetadata);
this._token = TokenImplementation.createFromIdentityProvider(this._identityPoolId, identityProvider);
this._token.roleResolver = this.roleResolver;
this._token.userProvider = this.userProvider;
this._token.cacheService = this._cacheService;
this._token.logService = this.kernel.get('log');
let event = {
eventName: 'login',
eventId: Security.customEventId(this.identityPoolId),
payload: { providerName: providerName, identityMetadata: identityMetadata },
time: new Date().getTime()
};
this._token.loadCredentials((error, credentials) => {
this._logRumEvent(event);
event = _util2.default._extend({}, event);
event.payload = { credentials: credentials };
this._logRumEvent(event);
callback(error, this._token);
});
return this._token;
}
/**
* @param {Function} callback
* @returns {Token}
*/
}, {
key: 'anonymousLogin',
value: function anonymousLogin(callback) {
let TokenImplementation = this._localBackend ? _LocalToken.LocalToken : _Token.Token;
this._token = TokenImplementation.create(this.identityPoolId);
this._token.userProvider = this.userProvider;
this._token.roleResolver = this.roleResolver;
this._token.cacheService = this._cacheService;
this._token.logService = this.kernel.get('log');
let event = {
eventName: 'anonymousLogin',
eventId: Security.customEventId(this.identityPoolId),
time: new Date().getTime()
};
this._token.loadCredentials((error, credentials) => {
this._logRumEvent(event);
event = _util2.default._extend({}, event);
event.payload = { credentials: credentials };
this._logRumEvent(event);
callback(error, this._token);
});
return this._token;
}
/**
* @param {Object} lambdaContext
* @returns {Promise}
*/
}, {
key: 'warmupBackendLogin',
value: function warmupBackendLogin(lambdaContext) {
if (this.kernel.isFrontend) {
throw new _Exception.Exception('Call to warmupBackendLogin method is not allowed from frontend context.');
}
return this._setupValidEnvCredentials().then(envCredentials => {
let TokenImplementation = this._localBackend ? _LocalToken.LocalToken : _Token.Token;
this._token = TokenImplementation.createFromLambdaContext(this._identityPoolId, lambdaContext);
this._token.userProvider = this.userProvider;
this._token.logService = this.kernel.get('log');
this._token.roleResolver = this.roleResolver;
this._token.cacheService = this._cacheService;
return this.kernel.config.forceUserIdentity && this.kernel.accountMicroservice ? this._token.loadLambdaCredentials() : Promise.resolve(envCredentials);
});
}
/**
* Store lambda default credentials, in order to be able to switch from an account to another
*
* @returns {Promise}
* @private
*/
}, {
key: '_setupValidEnvCredentials',
value: function _setupValidEnvCredentials() {
return new Promise((resolve, reject) => {
if (_awsSdk2.default.config.credentials instanceof _awsSdk2.default.EnvironmentCredentials) {
_deepCore2.default.AWS.ENV_CREDENTIALS = _awsSdk2.default.config.credentials;
}
if (_deepCore2.default.AWS.ENV_CREDENTIALS && _deepCore2.default.AWS.ENV_CREDENTIALS.needsRefresh()) {
_deepCore2.default.AWS.ENV_CREDENTIALS.refresh(error => {
if (error) {
return reject(new Error(`Error refreshing lambda environmental credentials. ${error}`));
}
return resolve(_deepCore2.default.AWS.ENV_CREDENTIALS);
});
} else {
return resolve(_deepCore2.default.AWS.ENV_CREDENTIALS);
}
});
}
/**
* Destroys user session
*
* @returns {Promise}
*/
}, {
key: 'logout',
value: function logout() {
this._logRumEvent({
eventName: 'logout'
});
if (this._token) {
return this._token.destroy().then(() => {
this._roleProvider.invalidateCache();
this._token = null;
return this;
});
}
return Promise.resolve(this);
}
/**
* @param {Object} customData
* @returns {Boolean}
* @private
*/
}, {
key: '_logRumEvent',
value: function _logRumEvent(customData) {
if (this.kernel && !this.kernel.isRumEnabled) {
return false;
}
let logService = this.kernel.get('log');
let event = _util2.default._extend(customData, {
service: 'deep-security',
resourceType: 'Cognito',
resourceId: this.identityPoolId
});
logService.rumLog(event);
return true;
}
/**
* @param {String} identityPoolId
* @returns {String}
*/
}, {
key: 'identityPoolId',
get: function get() {
return this._identityPoolId;
}
/**
* @returns {*}
*/
}, {
key: 'userProvider',
get: function get() {
if (!this._userProvider) {
if (this.kernel.isFrontend) {
this._userProvider = new _FrontendUserProvider.FrontendUserProvider(this._userProviderEndpoint, this._resourceService);
} else {
this._userProvider = new _BackendUserProvider.BackendUserProvider(this._userModelName, this.container.get('db'));
}
}
return this._userProvider;
}
/**
* @returns {RoleResolver}
*/
}, {
key: 'roleResolver',
get: function get() {
if (!this._roleResolver) {
this._roleResolver = new _RoleResolver.RoleResolver(this.roleProvider);
}
return this._roleResolver;
}
/**
* @returns {RoleProvider}
*/
}, {
key: 'roleProvider',
get: function get() {
if (!this._roleProvider) {
this._roleProvider = new _RoleProvider.RoleProvider(this._resourceService, this._roleProviderEndpoint);
}
return this._roleProvider;
}
}, {
key: 'token',
get: function get() {
return this._token;
}
}, {
key: '_resourceService',
/**
* @returns {Object}
*/
get: function get() {
return this.container.get('resource');
}
/**
* @returns {Cache|LocalStorageDriver}
* @private
*/
}, {
key: '_cacheService',
get: function get() {
return this.container.get('cache');
}
}], [{
key: 'customEventId',
value: function customEventId(identityPoolId) {
return Security._md5(identityPoolId + new Date().getTime());
}
/**
* @todo - move all this utils methods into separate class somewhere in deep-core or deep-kernel
*
* @param {String} str
* @returns {String}
*/
}, {
key: '_md5',
value: function _md5(str) {
var md5sum = _crypto2.default.createHash('md5');
md5sum.update(str);
return md5sum.digest('hex');
}
}]);
return Security;
}(_deepKernel2.default.ContainerAware);