UNPKG

openhim-core

Version:

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

342 lines (303 loc) 10.5 kB
var Channel, Channels, ObjectId, Q, Transaction, authorisation, config, isPathValid, logger, polling, processPostAddTriggers, processPostDeleteTriggers, processPostUpdateTriggers, request, routerMiddleware, server, tcpAdapter, utils; Channels = require('../model/channels'); Channel = Channels.Channel; Transaction = require('../model/transactions').Transaction; ObjectId = require('mongoose').Types.ObjectId; Q = require('q'); logger = require('winston'); authorisation = require('./authorisation'); tcpAdapter = require('../tcpAdapter'); server = require("../server"); polling = require("../polling"); routerMiddleware = require('../middleware/router'); utils = require("../utils"); config = require('../config/config'); config.polling = config.get('polling'); request = require('request'); isPathValid = function(channel) { var i, len, ref, route; if (channel.routes != null) { ref = channel.routes; for (i = 0, len = ref.length; i < len; i++) { route = ref[i]; if ((route.path && route.pathTransform) || (route.pathTransform && !/s\/.*\/.*/.test(route.pathTransform))) { return false; } } } return true; }; /* * Retrieves the list of active channels */ exports.getChannels = function*() { var err, error; try { return this.body = (yield authorisation.getUserViewableChannels(this.authenticated)); } catch (error) { err = error; return utils.logAndSetResponse(this, 500, "Could not fetch all channels via the API: " + err, 'error'); } }; processPostAddTriggers = function(channel) { if (channel.type && Channels.isChannelEnabled(channel)) { if ((channel.type === 'tcp' || channel.type === 'tls') && server.isTcpHttpReceiverRunning()) { return tcpAdapter.notifyMasterToStartTCPServer(channel._id, function(err) { if (err) { return logger.error(err); } }); } else if (channel.type === 'polling') { return polling.registerPollingChannel(channel, function(err) { if (err) { return logger.error(err); } }); } } }; /* * Creates a new channel */ exports.addChannel = function*() { var channel, channelData, err, error, numPrimaries, result; if (authorisation.inGroup('admin', this.authenticated) === false) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to addChannel denied.", 'info'); return; } channelData = this.request.body; try { channel = new Channel(channelData); if (!isPathValid(channel)) { this.body = 'Channel cannot have both path and pathTransform. pathTransform must be of the form s/from/to[/g]'; this.status = 400; return; } if ((channel.priority != null) && channel.priority < 1) { this.body = 'Channel priority cannot be below 1 (= Highest priority)'; this.status = 400; return; } numPrimaries = routerMiddleware.numberOfPrimaryRoutes(channel.routes); if (numPrimaries === 0) { this.body = 'Channel must have a primary route'; this.status = 400; return; } if (numPrimaries > 1) { this.body = 'Channel cannot have a multiple primary routes'; this.status = 400; return; } result = (yield Q.ninvoke(channel, 'save')); this.body = 'Channel successfully created'; this.status = 201; logger.info('User %s created channel with id %s', this.authenticated.email, channel.id); channelData._id = channel._id; return processPostAddTriggers(channelData); } catch (error) { err = error; return utils.logAndSetResponse(this, 400, "Could not add channel via the API: " + err, 'error'); } }; /* * Retrieves the details for a specific channel */ exports.getChannel = function*(channelId) { var accessDenied, adminResult, err, error, id, result; id = unescape(channelId); try { result = null; accessDenied = false; if (authorisation.inGroup('admin', this.authenticated) === false) { result = (yield Channel.findOne({ _id: id, txViewAcl: { $in: this.authenticated.groups } }).exec()); adminResult = (yield Channel.findById(id).exec()); if (adminResult != null) { accessDenied = true; } } else { result = (yield Channel.findById(id).exec()); } if (result === null) { if (accessDenied) { this.body = "Access denied to channel with Id: '" + id + "'."; return this.status = 403; } else { this.body = "We could not find a channel with Id:'" + id + "'."; return this.status = 404; } } else { return this.body = result; } } catch (error) { err = error; return utils.logAndSetResponse(this, 500, "Could not fetch channel by Id '" + id + "' via the API: " + err, 'error'); } }; processPostUpdateTriggers = function(channel) { if (channel.type) { if ((channel.type === 'tcp' || channel.type === 'tls') && server.isTcpHttpReceiverRunning()) { if (Channels.isChannelEnabled(channel)) { return tcpAdapter.notifyMasterToStartTCPServer(channel._id, function(err) { if (err) { return logger.error(err); } }); } else { return tcpAdapter.notifyMasterToStopTCPServer(channel._id, function(err) { if (err) { return logger.error(err); } }); } } else if (channel.type === 'polling') { if (Channels.isChannelEnabled(channel)) { return polling.registerPollingChannel(channel, function(err) { if (err) { return logger.error(err); } }); } else { return polling.removePollingChannel(channel, function(err) { if (err) { return logger.error(err); } }); } } } }; /* * Updates the details for a specific channel */ exports.updateChannel = function*(channelId) { var channel, channelData, err, error, id, numPrimaries; if (authorisation.inGroup('admin', this.authenticated) === false) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to updateChannel denied.", 'info'); return; } id = unescape(channelId); channelData = this.request.body; if (typeof channelData._id !== 'undefined') { delete channelData._id; } if (!isPathValid(channelData)) { utils.logAndSetResponse(this, 400, 'Channel cannot have both path and pathTransform. pathTransform must be of the form s/from/to[/g]', 'info'); return; } if ((channelData.priority != null) && channelData.priority < 1) { this.body = 'Channel priority cannot be below 1 (= Highest priority)'; this.status = 400; return; } if (channelData.routes != null) { numPrimaries = routerMiddleware.numberOfPrimaryRoutes(channelData.routes); if (numPrimaries === 0) { this.body = 'Channel must have a primary route'; this.status = 400; return; } if (numPrimaries > 1) { this.body = 'Channel cannot have a multiple primary routes'; this.status = 400; return; } } try { channel = (yield Channel.findByIdAndUpdate(id, channelData).exec()); this.body = 'The channel was successfully updated'; logger.info('User %s updated channel with id %s', this.authenticated.email, id); channelData._id = ObjectId(id); return processPostUpdateTriggers(channelData); } catch (error) { err = error; return utils.logAndSetResponse(this, 500, "Could not update channel by id: " + id + " via the API: " + e, 'error'); } }; processPostDeleteTriggers = function(channel) { if (channel.type) { if ((channel.type === 'tcp' || channel.type === 'tls') && server.isTcpHttpReceiverRunning()) { return tcpAdapter.notifyMasterToStopTCPServer(channel._id, function(err) { if (err) { return logger.error(err); } }); } else if (channel.type === 'polling') { return polling.removePollingChannel(channel, function(err) { if (err) { return logger.error(err); } }); } } }; /* * Deletes a specific channels details */ exports.removeChannel = function*(channelId) { var channel, err, error, id, numExistingTransactions; if (authorisation.inGroup('admin', this.authenticated) === false) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to removeChannel denied.", 'info'); return; } id = unescape(channelId); try { numExistingTransactions = (yield Transaction.count({ channelID: id }).exec()); if (numExistingTransactions === 0) { channel = (yield Channel.findByIdAndRemove(id).exec()); } else { channel = (yield Channel.findByIdAndUpdate(id, { status: 'deleted' }).exec()); } this.body = 'The channel was successfully deleted'; logger.info("User " + this.authenticated.email + " removed channel with id " + id); return processPostDeleteTriggers(channel); } catch (error) { err = error; return utils.logAndSetResponse(this, 500, "Could not remove channel by id: " + id + " via the API: " + e, 'error'); } }; /* * Manually Triggers Polling Channel */ exports.triggerChannel = function*(channelId) { var channel, err, error, id, options; if (authorisation.inGroup('admin', this.authenticated) === false) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to removeChannel denied.", 'info'); return; } id = unescape(channelId); this.status = 200; try { channel = (yield Channel.findById(id).exec()); if (channel === null) { this.body = "We could not find a channel with Id:'" + id + "'."; return this.status = 404; } else { logger.info("Manually Polling channel " + channel._id); options = { url: "http://" + config.polling.host + ":" + config.polling.pollingPort + "/trigger", headers: { 'channel-id': channel._id, 'X-OpenHIM-LastRunAt': new Date } }; return request(options, function() { logger.info("Channel Successfully polled " + channel._id); return this.status = 200; }); } } catch (error) { err = error; return utils.logAndSetResponse(this, 500, "Could not fetch channel by Id '" + id + "' via the API: " + err, 'error'); } }; //# sourceMappingURL=channels.js.map