UNPKG

globalstorage

Version:

Global Storage is a Global Distributed Data Warehouse

402 lines (346 loc) 15.1 kB
'use strict'; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } var common = require('@metarhia/common'); var jstp = require('@metarhia/jstp'); var metasync = require('metasync'); var _require = require('./errors'), GSError = _require.GSError, errorCodes = _require.codes; var _require2 = require('./permission'), checkPermission = _require2.checkPermission, checkPermissionComplex = _require2.checkPermissionComplex, checkExecutePermission = _require2.checkExecutePermission, filterCategories = _require2.filterCategories, filterCategoriesWithPermissions = _require2.filterCategoriesWithPermissions, filterActions = _require2.filterActions, filterApplications = _require2.filterApplications; var validate = { string: function string(value) { return typeof value === 'string'; }, object: function object(value) { return _typeof(value) === 'object' && !Array.isArray(value); }, objectArray: function objectArray(value) { return Array.isArray(value) && value.every(validate.object); }, stringArray: function stringArray(value) { return Array.isArray(value) && value.every(validate.string); } }; var createPermissionChecker = function createPermissionChecker(provider, accessType, userId) { return function (category, options, callback) { if (!options) options = {}; if (options.accessType) { accessType = options.accessType; } var categorySchema = provider.schema.categories.get(category); var cb = function cb(err, ok) { if (err) { callback(new GSError(errorCodes.INTERNAL_PROVIDER_ERROR, err)); } else if (!ok) { callback(new GSError(errorCodes.INSUFFICIENT_PERMISSIONS)); } else { callback(); } }; if (!categorySchema.catalog && !categorySchema.subsystem) { checkPermission(provider, accessType, category, userId, cb); } else { checkPermissionComplex(provider, accessType, category, userId, options, cb); } }; }; var createEntityFilterer = function createEntityFilterer(provider, userId, filterEntities) { return function (entities, callback) { filterEntities(provider, entities, userId, function (err, entities) { if (err) { callback(new GSError(errorCodes.INTERNAL_PROVIDER_ERROR, err)); } else { callback(null, entities); } }); }; }; var constructLogContext = function constructLogContext(connection, userId) { return { SystemUser: userId, IP: connection.remoteAddress, ProcessToken: common.generateGUID(), ConnectionId: connection.session.id }; }; // Create JSTP API that can be passed to JSTP application // gsProvider <StorageProvider> JSTP calls will be passed to this provider, // it must be already in an `open` state // cursorFactory <Function> factory to be used to create new cursors // gsProvider <StorageProvider> provider instance to create the cursor from // category <string> category name to be passed to the cursor // jsql <Object[]> jsql to be passed to the cursor // Returns: <Cursor> created cursor // Returns: <Object> JSTP API var createRemoteProviderJstpApi = function createRemoteProviderJstpApi(gsProvider, cursorFactory) { return { provider: { get: function get(connection, id, callback) { if (!validate.string(id)) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.enableLogging(constructLogContext(connection, userId)).get(id, function (err, record) { callback(err && err.code, record); }, createPermissionChecker(gsProvider, 'read', userId)); }, getDetails: function getDetails(connection, category, id, fieldName, callback) { if (!validate.string(category) || !validate.string(id) || !validate.string(fieldName)) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.enableLogging(constructLogContext(connection, userId)).getDetails(category, id, fieldName, function (err, res) { callback(err && err.code, res); }, createPermissionChecker(gsProvider, 'read', userId)); }, set: function set(connection, record, callback) { if (!validate.object(record)) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.enableLogging(constructLogContext(connection, userId)).set(record, function (err) { callback(err && err.code); }, createPermissionChecker(gsProvider, 'update', userId)); }, create: function create(connection, category, record, callback) { if (!validate.string(category) || !validate.object(record)) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.enableLogging(constructLogContext(connection, userId)).create(category, record, function (err, id) { callback(err && err.code, id && id.toString()); }, createPermissionChecker(gsProvider, 'insert', userId)); }, update: function update(connection, category, query, patch, callback) { if (!validate.string(category) || !validate.object(query) || !validate.object(patch)) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.enableLogging(constructLogContext(connection, userId)).update(category, query, patch, function (err, count) { callback(err && err.code, count); }, createPermissionChecker(gsProvider, 'update', userId)); }, linkDetails: function linkDetails(connection, category, field, fromId, toIds, callback) { if (!validate.string(category) || !validate.string(field) || !validate.string(fromId) || !(validate.string(toIds) || validate.stringArray(toIds))) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.enableLogging(constructLogContext(connection, userId)).linkDetails(category, field, fromId, toIds, function (err) { callback(err && err.code); }, createPermissionChecker(gsProvider, 'update', userId)); }, unlinkDetails: function unlinkDetails(connection, category, field, fromId, toIds, callback) { if (!validate.string(category) || !validate.string(field) || !validate.string(fromId) || !(validate.string(toIds) || validate.stringArray(toIds))) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.enableLogging(constructLogContext(connection, userId)).unlinkDetails(category, field, fromId, toIds, function (err) { callback(err && err.code); }, createPermissionChecker(gsProvider, 'update', userId)); }, delete: function _delete(connection, category, query, callback) { if (!validate.string(category) || !validate.object(query)) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.enableLogging(constructLogContext(connection, userId)).delete(category, query, function (err, count) { callback(err && err.code, count); }, createPermissionChecker(gsProvider, 'delete', userId)); }, select: function select(connection, category, jsql, callback) { if (!validate.string(category) || !validate.objectArray(jsql)) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } var cursor = cursorFactory(gsProvider, category, jsql).enableLogging(gsProvider, constructLogContext(connection, userId), [category, jsql]); cursor.fetch(function (err, records) { callback(err && err.code, records); }, createPermissionChecker(gsProvider, 'read', userId)); }, execute: function execute(connection, category, action, args, callback) { if (category !== null && !validate.string(category) || !validate.string(action) || !validate.object(args)) { callback(jstp.ERR_INVALID_SIGNATURE); return; } var session = connection.session; var userId = session.get('userId'); gsProvider.enableLogging(constructLogContext(connection, userId)).execute(category, action, [session, args], function (err) { for (var _len = arguments.length, res = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { res[_key - 1] = arguments[_key]; } callback.apply(void 0, [err && (err.code || err)].concat(res)); }, function (category, action, callback) { checkExecutePermission(gsProvider, category, action, userId, function (err, ok) { if (err) { callback(new GSError(errorCodes.INTERNAL_PROVIDER_ERROR, err)); } else if (!ok) { callback(new GSError(errorCodes.INSUFFICIENT_PERMISSIONS)); } else { callback(); } }); }); }, getSchemaSources: function getSchemaSources(connection, callback) { var userId = connection.session.get('userId'); var ops; if (!userId) { ops = [function (ctx, callback) { gsProvider.listActions(function (err, actions) { ctx.actionLists = { public: actions.public, private: {} }; callback(err); }); }]; } else { ops = [function (ctx, callback) { gsProvider.listActions(function (err, actions) { ctx.actionLists = actions; callback(err); }, createEntityFilterer(gsProvider, userId, filterActions)); }, function (ctx, callback) { gsProvider.listCategories(function (err, categories) { ctx.categoryList = categories; callback(err); }, createEntityFilterer(gsProvider, userId, filterCategories)); }, function (ctx, callback) { gsProvider.listApplications(function (err, applications) { ctx.appList = applications; callback(err); }, createEntityFilterer(gsProvider, userId, filterApplications)); }]; } metasync.parallel(ops, function (err, options) { if (err) { callback(err.code); } else { if (!options.categoryList) options.categoryList = []; if (!options.appList) options.appList = []; gsProvider.getSchemaSources(callback, options); } }); }, listCategories: function listCategories(connection, callback) { var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.listCategories(function (err, categories) { callback(err && err.code, categories); }, createEntityFilterer(gsProvider, userId, filterCategories)); }, listCategoriesPermissions: function listCategoriesPermissions(connection, callback) { var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.listCategories(function (err, categories) { callback(err && err.code, categories); }, createEntityFilterer(gsProvider, userId, filterCategoriesWithPermissions)); }, listActions: function listActions(connection, callback) { var userId = connection.session.get('userId'); if (!userId) { gsProvider.listActions(function (err, actions) { if (err) { callback(err.code); return; } callback(null, { public: actions.public }); }); } else { gsProvider.listActions(function (err, actions) { callback(err && err.code, actions); }, createEntityFilterer(gsProvider, userId, filterActions)); } }, listApplications: function listApplications(connection, callback) { var userId = connection.session.get('userId'); if (!userId) { callback(errorCodes.INSUFFICIENT_PERMISSIONS); return; } gsProvider.listApplications(function (err, applications) { callback(err && err.code, applications); }, createEntityFilterer(gsProvider, userId, filterApplications)); } }, l10n: { getCategory: function getCategory(connection, langTag, category, callback) { gsProvider.getCategoryL10n(langTag, category, callback); }, getDomains: function getDomains(connection, langTag, callback) { gsProvider.getDomainsL10n(langTag, callback); }, getCommon: function getCommon(connection, langTag, callback) { gsProvider.getCommonL10n(langTag, callback); }, getForm: function getForm(connection, langTag, category, form, callback) { gsProvider.getFormL10n(langTag, category, form, callback); }, getAction: function getAction(connection, langTag, category, action, callback) { gsProvider.getActionL10n(langTag, category, action, callback); } } }; }; module.exports = { createRemoteProviderJstpApi: createRemoteProviderJstpApi };