globalstorage
Version:
Global Storage is a Global Distributed Data Warehouse
402 lines (346 loc) • 15.1 kB
JavaScript
;
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
};