UNPKG

openhim-core

Version:

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

288 lines (239 loc) 9.69 kB
http = require "http" https = require "https" net = require "net" tls = require "tls" fs = require "fs" User = require('../lib/model/users').User Keystore = require('../lib/model/keystore').Keystore crypto = require "crypto" zlib = require "zlib" pem = require "pem" logger = require "winston" Q = require "q" finalhandler = require('finalhandler') serveStatic = require('serve-static') exports.createMockServer = (resStatusCode, resBody, port, callback, requestCallback) -> requestCallback = requestCallback || -> # Create mock endpoint to forward requests to mockServer = http.createServer (req, res) -> res.writeHead resStatusCode, {"Content-Type": "text/plain"} res.end resBody mockServer.listen port, callback mockServer.on "request", requestCallback exports.createMockServerForPost = (successStatusCode, errStatusCode, bodyToMatch) -> return http.createServer (req, res) -> req.on "data", (chunk) -> if chunk.toString() == bodyToMatch res.writeHead successStatusCode, {"Content-Type": "text/plain"} res.end() else res.writeHead errStatusCode, {"Content-Type": "text/plain"} res.end() exports.createStaticServer = (path, port, callback) -> # Serve up public/ftp folder serve = serveStatic(path, 'index': [ 'index.html' 'index.htm' ]) # Create server server = http.createServer((req, res) -> done = finalhandler(req, res) serve req, res, done return ) # Listen server.listen port, 'localhost', -> callback server exports.createMockHTTPSServerWithMutualAuth = (resStatusCode, resBody, port, useClientCert, callback, requestCallback) -> if typeof useClientCert is 'function' requestCallback = callback callback = useClientCert useClientCert = true options = key: fs.readFileSync 'test/resources/server-tls/key.pem' cert: fs.readFileSync 'test/resources/server-tls/cert.pem' requestCert: true rejectUnauthorized: true secureProtocol: 'TLSv1_method' if useClientCert options.ca = fs.readFileSync 'test/resources/server-tls/cert.pem' requestCallback = requestCallback || -> # Create mock endpoint to forward requests to mockServer = https.createServer options, (req, res) -> res.writeHead resStatusCode, {"Content-Type": "text/plain"} res.end "Secured " + resBody mockServer.listen port, -> callback mockServer mockServer.on "request", requestCallback exports.createMockTCPServer = (port, expected, matchResponse, nonMatchResponse, callback) -> server = net.createServer (sock) -> sock.on 'data', (data) -> response = if "#{data}" is expected then matchResponse else nonMatchResponse sock.write response server.listen port, 'localhost', -> callback server exports.createMockTLSServerWithMutualAuth = (port, expected, matchResponse, nonMatchResponse, useClientCert, callback) -> if typeof useClientCert is 'function' callback = useClientCert useClientCert = true options = key: fs.readFileSync 'test/resources/server-tls/key.pem' cert: fs.readFileSync 'test/resources/server-tls/cert.pem' requestCert: true rejectUnauthorized: true secureProtocol: 'TLSv1_method' if useClientCert options.ca = fs.readFileSync 'test/resources/server-tls/cert.pem' server = tls.createServer options, (sock) -> sock.on 'data', (data) -> response = if "#{data}" is expected then matchResponse else nonMatchResponse sock.write response server.listen port, 'localhost', -> callback server exports.createMockHTTPRespondingPostServer = (port, expected, matchResponse, nonMatchResponse, callback) -> server = http.createServer (req, res) -> req.on 'data', (data) -> if "#{data}" is expected res.writeHead 200, {"Content-Type": "text/plain"} res.write matchResponse else res.writeHead 500, {"Content-Type": "text/plain"} res.write nonMatchResponse res.end() server.listen port, 'localhost', -> callback server exports.createMockMediatorServer = (resStatusCode, mediatorResponse, port, callback) -> requestCallback = requestCallback || -> # Create mock endpoint to forward requests to mockServer = http.createServer (req, res) -> res.writeHead resStatusCode, {"Content-Type": "application/json+openhim; charset=utf-8"} res.end JSON.stringify mediatorResponse mockServer.listen port, -> callback mockServer exports.rootUser = firstname: 'Admin' surname: 'User' email: 'root@jembi.org' passwordAlgorithm: 'sha512' passwordHash: '669c981d4edccb5ed61f4d77f9fcc4bf594443e2740feb1a23f133bdaf80aae41804d10aa2ce254cfb6aca7c497d1a717f2dd9a794134217219d8755a84b6b4e' passwordSalt: '22a61686-66f6-483c-a524-185aac251fb0' groups: [ 'HISP', 'admin' ] # password is 'password' exports.nonRootUser = firstname: 'Non' surname: 'Root' email: 'nonroot@jembi.org' passwordAlgorithm: 'sha512' passwordHash: '669c981d4edccb5ed61f4d77f9fcc4bf594443e2740feb1a23f133bdaf80aae41804d10aa2ce254cfb6aca7c497d1a717f2dd9a794134217219d8755a84b6b4e' passwordSalt: '22a61686-66f6-483c-a524-185aac251fb0' groups: [ "group1", "group2" ] # password is 'password' exports.auth = {} exports.auth.setupTestUsers = (done) -> (new User exports.rootUser).save (err) -> return done err if err (new User exports.nonRootUser).save (err) -> if err done err else done() # auth detail are the same between the to users exports.auth.getAuthDetails = () -> # create tokenhash authTS = new Date().toISOString() requestsalt = '842cd4a0-1a91-45a7-bf76-c292cb36b2e8' tokenhash = crypto.createHash 'sha512' tokenhash.update exports.rootUser.passwordHash tokenhash.update requestsalt tokenhash.update authTS auth = authTS: authTS authSalt: requestsalt authToken: tokenhash.digest('hex') return auth exports.auth.cleanupTestUsers = (done) -> User.remove { email: 'root@jembi.org' }, (err) -> return done err if err User.remove { email: 'nonroot@jembi.org' }, (err) -> if err done err else done() exports.createMockServerForPostWithReturn = (successStatusCode, errStatusCode, bodyToMatch) -> return http.createServer (req, res) -> acceptEncoding = req.headers['accept-encoding'] if (!acceptEncoding) acceptEncoding = '' req.on "data", (chunk) -> if chunk.toString() == bodyToMatch if acceptEncoding.match /gzip/g #the him always sets the accept-encoding headers to accept gzip it then decompresses the response and sends it to the client buf = new Buffer(bodyToMatch, 'utf-8') zlib.gzip bodyToMatch, (_, result) -> headers = "date": (new Date()).toString() "vary": "Accept-Encoding" "server": "Apache" "allow": "GET,HEAD,POST,PUT,OPTIONS" "content-type": "text/html" "content-encoding": "gzip" "content-length": result.length "connection": "close" res.writeHead successStatusCode, headers res.end result else res.writeHead successStatusCode, {"Content-Type": "text/plain"} res.end bodyToMatch else res.writeHead errStatusCode, {"Content-Type": "text/plain"} res.end() ### # Sets up a keystore of testing. serverCert, serverKey, ca are optional, however if # you provide a serverCert you must provide the serverKey or null one out and vice # versa. ### exports.setupTestKeystore = (serverCert, serverKey, ca, callback) -> if typeof serverCert is 'function' callback = serverCert serverCert = null if serverCert instanceof Array and typeof serverKey is 'function' ca = serverCert callback = serverKey serverCert = null serverKey = null serverCert = fs.readFileSync 'test/resources/server-tls/cert.pem' if not serverCert? serverKey = fs.readFileSync 'test/resources/server-tls/key.pem' if not serverKey? if not ca? ca = [] ca.push fs.readFileSync 'test/resources/trust-tls/cert1.pem' ca.push fs.readFileSync 'test/resources/trust-tls/cert2.pem' # remove any existing keystore Keystore.remove {}, -> pem.readCertificateInfo serverCert, (err, serverCertInfo) -> if err? logger.error "Failed to get certificate info in test utils: #{err}" return callback null serverCertInfo.data = serverCert pem.getFingerprint serverCert, (err, serverCertFingerprint) -> if err? logger.error "Failed to get certificate fingerprint in test utils: #{err}" return callback null serverCertInfo.fingerprint = serverCertFingerprint.fingerprint keystore = new Keystore key: serverKey cert: serverCertInfo ca: [] if ca.length > 0 readCertInfo = Q.denodeify pem.readCertificateInfo getFingerprint = Q.denodeify pem.getFingerprint infoPromises = [] fingerprintPromises = [] for cert in ca infoPromises.push(readCertInfo cert) fingerprintPromises.push(getFingerprint cert) Q.all(infoPromises).then (caCertsInfo) -> Q.all(fingerprintPromises).then (caFingerprints) -> keystore.ca = caCertsInfo # Add in the cert data for cert, i in ca keystore.ca[i].data = cert keystore.ca[i].fingerprint = caFingerprints[i].fingerprint keystore.save -> callback keystore else keystore.save -> callback keystore exports.cleanupTestKeystore = (callback) -> Keystore.remove {}, -> callback()