openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
155 lines (126 loc) • 5.24 kB
text/coffeescript
Channel = require('../model/channels').Channel
Client = require('../model/clients').Client
Mediator = require('../model/mediators').Mediator
User = require('../model/users').User
ContactGroup = require('../model/contactGroups').ContactGroup
Keystore = require('../model/keystore').Keystore
Q = require 'q'
logger = require 'winston'
authorisation = require './authorisation'
utils = require "../utils"
# Map string parameters to collections
collections =
Channels: Channel
Clients: Client
Mediators: Mediator
Users: User
ContactGroups: ContactGroup
Keystore: Keystore
#Function to remove properties from export object
removeProperties = (obj) ->
propertyID = '_id'
propertyV = '__v'
for prop of 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
getUniqueIdentifierForCollection = (collection, doc) ->
switch collection
when 'Channels' then uidKey = 'name'; uid = doc.name
when 'Clients' then uidKey = 'clientID'; uid = doc.clientID
when 'Mediators' then uidKey = 'urn'; uid = doc.urn
when 'Users' then uidKey = 'email'; uid = doc.email
when 'ContactGroups' then uidKey = 'groups'; uid = doc.groups
returnObj = {}
returnObj[uidKey] = uid
return returnObj
# Build response object
buildResponseObject = (model, doc, status, message, uid) ->
return {
model: model
record: doc
status: status
message: message
uid: uid
}
# API endpoint that returns metadata for export
exports.getMetadata = () ->
# Test if the user is authorised
if not authorisation.inGroup 'admin', this.authenticated
return utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to getMetadata denied.", 'info'
try
exportObject = {}
params = this.request.query
# Return all documents from all collections for export
for col of collections
exportObject[col] = yield collections[col].find().lean().exec()
for doc in exportObject[col]
if doc._id
doc = removeProperties doc
this.body = [exportObject]
this.status = 200
catch e
this.body = e.message
utils.logAndSetResponse this, 500, "Could not fetch specified metadata via the API #{e}", 'error'
handleMetadataPost = (action, that) ->
# Test if the user is authorised
if not authorisation.inGroup 'admin', that.authenticated
return utils.logAndSetResponse that, 403, "User #{that.authenticated.email} is not an admin, API access to importMetadata denied.", 'info'
try
returnObject = []
insertObject = that.request.body
for key of insertObject
insertDocuments = insertObject[key]
for doc in insertDocuments
try
if key not of 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 is 'Keystore'
result = yield collections[key].find().exec()
uid = ''
else
uidObj = getUniqueIdentifierForCollection key, doc
uid = uidObj[Object.keys(uidObj)[0]]
result = yield collections[key].find(uidObj).exec()
if action is 'import'
if result and result.length > 0 and result[0]._id
delete doc._id if doc._id
yield collections[key].findByIdAndUpdate(result[0]._id, doc).exec()
status = 'Updated'
else
doc = new collections[key] doc
result = yield Q.ninvoke doc, 'save'
status = 'Inserted'
if action is 'validate'
if result and result.length > 0 and result[0]._id
status = 'Conflict'
else
doc = new collections[key] doc
error = doc.validateSync()
if error
throw new Error "Document Validation failed: #{error}"
status = 'Valid'
logger.info "User #{that.authenticated.email} performed #{action} action on #{key}, got #{status}"
returnObject.push buildResponseObject key, doc, status, '', uid
catch e
logger.error "Failed to #{action} #{key} with unique identifier #{uid}. #{e.message}"
returnObject.push buildResponseObject key, doc, 'Error', e.message, uid
that.body = returnObject
that.status = 201
catch e
that.body = e.message
utils.logAndSetResponse that, 500, "Could not import metadata via the API #{e}", 'error'
# API endpoint that upserts metadata
exports.importMetadata = () ->
handleMetadataPost 'import', this
# API endpoint that checks for conflicts between import object and database
exports.validateMetadata = () ->
handleMetadataPost 'validate', this
if process.env.NODE_ENV == "test"
exports.buildResponseObject = buildResponseObject
exports.getUniqueIdentifierForCollection = getUniqueIdentifierForCollection
exports.removeProperties = removeProperties