UNPKG

openhim-core

Version:

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

243 lines (186 loc) 7.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMetadata = getMetadata; exports.importMetadata = importMetadata; exports.validateMetadata = validateMetadata; var _winston = _interopRequireDefault(require("winston")); var authorisation = _interopRequireWildcard(require("./authorisation")); var utils = _interopRequireWildcard(require("../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 _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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: _winston.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'; } } _winston.default.info(`User ${ctx.authenticated.email} performed ${action} action on ${key}, got ${status}`); returnObject.push(buildResponseObject(key, doc, status, '', uid)); } catch (err) { _winston.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