openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
231 lines (196 loc) • 7.23 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getMetadata = getMetadata;
exports.importMetadata = importMetadata;
exports.validateMetadata = validateMetadata;
var _winston = require('winston');
var _winston2 = _interopRequireDefault(_winston);
var _authorisation = require('./authorisation');
var authorisation = _interopRequireWildcard(_authorisation);
var _utils = require('../utils');
var utils = _interopRequireWildcard(_utils);
var _channels = require('../model/channels');
var _clients = require('../model/clients');
var _mediators = require('../model/mediators');
var _users = require('../model/users');
var _contactGroups = require('../model/contactGroups');
var _keystore = require('../model/keystore');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Map string parameters to collections
const collections = {
Channels: _channels.ChannelModelAPI,
Clients: _clients.ClientModelAPI,
Mediators: _mediators.MediatorModelAPI,
Users: _users.UserModelAPI,
ContactGroups: _contactGroups.ContactGroupModelAPI,
KeystoreModelAPI: _keystore.KeystoreModelAPI
// Function to remove properties from export object
};function removeProperties(obj) {
const propertyID = '_id';
const propertyV = '__v';
for (const prop in obj) {
if (prop === propertyID || prop === propertyV) {
delete obj[prop];
} else if (typeof obj[prop] === 'object' || obj[prop] instanceof Array) {
removeProperties(obj[prop]);
}
}
return obj;
}
// Function to return unique identifier key and value for a collection
function getUniqueIdentifierForCollection(collection, doc) {
let uid;
let uidKey;
switch (collection) {
case 'Channels':
uidKey = 'name';
uid = doc.name;
break;
case 'Clients':
uidKey = 'clientID';
uid = doc.clientID;
break;
case 'Mediators':
uidKey = 'urn';
uid = doc.urn;
break;
case 'Users':
uidKey = 'email';
uid = doc.email;
break;
case 'ContactGroups':
uidKey = 'groups';
uid = doc.groups;
break;
default:
_winston2.default.debug(`Unhandeled case for ${collection} in getUniqueIdentifierForCollection`);
break;
}
const returnObj = {};
returnObj[uidKey] = uid;
return returnObj;
}
// Build response object
function buildResponseObject(model, doc, status, message, uid) {
return {
model,
record: doc,
status,
message,
uid
};
}
// API endpoint that returns metadata for export
async function getMetadata(ctx) {
// Test if the user is authorised
if (!authorisation.inGroup('admin', ctx.authenticated)) {
return utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to getMetadata denied.`, 'info');
}
try {
const exportObject = {};
// Return all documents from all collections for export
for (const col in collections) {
exportObject[col] = await collections[col].find().lean().exec();
for (let doc of Array.from(exportObject[col])) {
if (doc._id) {
doc = removeProperties(doc);
}
}
}
ctx.body = [exportObject];
ctx.status = 200;
} catch (e) {
ctx.body = e.message;
utils.logAndSetResponse(ctx, 500, `Could not fetch specified metadata via the API ${e}`, 'error');
}
}
async function handleMetadataPost(ctx, action) {
// Test if the user is authorised
if (!authorisation.inGroup('admin', ctx.authenticated)) {
return utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to importMetadata denied.`, 'info');
}
try {
let status;
const returnObject = [];
const insertObject = ctx.request.body;
for (const key in insertObject) {
const insertDocuments = insertObject[key];
for (let doc of Array.from(insertDocuments)) {
let error;
let uid;
try {
let result;
if (!(key in collections)) {
throw new Error('Invalid Collection in Import Object');
}
// Keystore model does not have a uid other than _id and may not contain more than one entry
if (key === 'Keystore') {
result = await collections[key].find().exec();
uid = '';
} else {
const uidObj = getUniqueIdentifierForCollection(key, doc);
uid = uidObj[Object.keys(uidObj)[0]];
result = await collections[key].find(uidObj).exec();
}
if (action === 'import') {
if (result && result.length > 0 && result[0]._id) {
if (doc._id) {
delete doc._id;
}
result = await collections[key].findById(result[0]._id).exec();
result.set(doc);
result.set('updatedBy', utils.selectAuditFields(ctx.authenticated));
await result.save();
status = 'Updated';
} else {
doc = new collections[key](doc);
doc.set('updatedBy', utils.selectAuditFields(ctx.authenticated));
result = await doc.save();
status = 'Inserted';
}
}
if (action === 'validate') {
if (result && result.length > 0 && result[0]._id) {
status = 'Conflict';
} else {
doc = new collections[key](doc);
doc.set('updatedBy', utils.selectAuditFields(ctx.authenticated));
error = doc.validateSync();
if (error) {
throw new Error(`Document Validation failed: ${error}`);
}
status = 'Valid';
}
}
_winston2.default.info(`User ${ctx.authenticated.email} performed ${action} action on ${key}, got ${status}`);
returnObject.push(buildResponseObject(key, doc, status, '', uid));
} catch (err) {
_winston2.default.error(`Failed to ${action} ${key} with unique identifier ${uid}. ${err.message}`);
returnObject.push(buildResponseObject(key, doc, 'Error', err.message, uid));
}
}
}
ctx.body = returnObject;
ctx.status = 201;
} catch (error2) {
ctx.body = error2.message;
utils.logAndSetResponse(ctx, 500, `Could not import metadata via the API ${error2}`, 'error');
}
}
// API endpoint that upserts metadata
async function importMetadata(ctx) {
return handleMetadataPost(ctx, 'import');
}
// API endpoint that checks for conflicts between import object and database
async function validateMetadata(ctx) {
return handleMetadataPost(ctx, 'validate');
}
if (process.env.NODE_ENV === 'test') {
exports.buildResponseObject = buildResponseObject;
exports.getUniqueIdentifierForCollection = getUniqueIdentifierForCollection;
exports.removeProperties = removeProperties;
}
//# sourceMappingURL=metadata.js.map