UNPKG

openhim-core

Version:

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

105 lines (90 loc) 3.6 kB
var User, atna, auditing, auditingExemptPaths, config, crypto, himSourceID, isUndefOrEmpty, logger, os; User = require('../model/users').User; crypto = require('crypto'); logger = require('winston'); config = require("../config/config"); config.api = config.get('api'); config.auditing = config.get('auditing'); atna = require('atna-audit'); auditing = require('../auditing'); os = require('os'); himSourceID = config.auditing.auditEvents.auditSourceID; auditingExemptPaths = [/\/tasks/, /\/events.*/, /\/metrics.*/, /\/mediators\/.*\/heartbeat/, /\/audits/, /\/logs/]; isUndefOrEmpty = function(string) { return (string == null) || string === ''; }; exports.authenticate = function*(next) { var audit, auditAuthFailure, authSalt, authTS, authToken, authWindowSeconds, email, from, hash, header, i, len, pathTest, ref, requestDate, to, user; header = this.request.header; email = header['auth-username']; authTS = header['auth-ts']; authSalt = header['auth-salt']; authToken = header['auth-token']; auditAuthFailure = function() { var audit; audit = atna.userLoginAudit(atna.OUTCOME_SERIOUS_FAILURE, himSourceID, os.hostname(), email); audit = atna.wrapInSyslog(audit); return auditing.sendAuditEvent(audit, function() { return logger.debug('Processed internal audit'); }); }; if (isUndefOrEmpty(email) || isUndefOrEmpty(authTS) || isUndefOrEmpty(authSalt) || isUndefOrEmpty(authToken)) { logger.info("API request made by " + email + " from " + this.request.host + " is missing required API authentication headers, denying access"); this.status = 401; auditAuthFailure(); return; } requestDate = new Date(Date.parse(authTS)); authWindowSeconds = (ref = config.api.authWindowSeconds) != null ? ref : 10; to = new Date(); to.setSeconds(to.getSeconds() + authWindowSeconds); from = new Date(); from.setSeconds(from.getSeconds() - authWindowSeconds); if (requestDate < from || requestDate > to) { logger.info("API request made by " + email + " from " + this.request.host + " has expired, denying access"); this.status = 401; auditAuthFailure(); return; } user = (yield User.findOne({ email: email }).exec()); this.authenticated = user; if (!user) { logger.info("No user exists for " + email + ", denying access to API, request originated from " + this.request.host); this.status = 401; auditAuthFailure(); return; } hash = crypto.createHash('sha512'); hash.update(user.passwordHash); hash.update(authSalt); hash.update(authTS); if (authToken === hash.digest('hex')) { if (this.path === '/transactions') { if (!this.query.filterRepresentation || this.query.filterRepresentation !== 'full') { (yield next); return; } } else { for (i = 0, len = auditingExemptPaths.length; i < len; i++) { pathTest = auditingExemptPaths[i]; if (pathTest.test(this.path)) { (yield next); return; } } } audit = atna.userLoginAudit(atna.OUTCOME_SUCCESS, himSourceID, os.hostname(), email, user.groups.join(','), user.groups.join(',')); audit = atna.wrapInSyslog(audit); auditing.sendAuditEvent(audit, function() { return logger.debug('Processed internal audit'); }); return (yield next); } else { logger.info("API token did not match expected value, denying access to API, the request was made by " + email + " from " + this.request.host); this.status = 401; return auditAuthFailure(); } }; //# sourceMappingURL=authentication.js.map