UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

231 lines (196 loc) 7.23 kB
'use strict'; 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