UNPKG

deep-security

Version:
434 lines (330 loc) 12.4 kB
/** * 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);