UNPKG

openhim-core

Version:

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

506 lines (472 loc) 19.8 kB
should = require "should" request = require "supertest" testUtils = require "../testUtils" auth = require("../testUtils").auth server = require "../../lib/server" Keystore = require('../../lib/model/keystore').Keystore sinon = require "sinon" fs = require 'fs' path = require 'path' config = require "../../lib/config/config" config.certificateManagement = config.get('certificateManagement') describe 'API Integration Tests', -> describe 'Keystore API Tests', -> authDetails = {} before (done) -> auth.setupTestUsers (err) -> server.start apiPort: 8080, -> done() after (done) -> auth.cleanupTestUsers (err) -> server.stop -> done() beforeEach (done) -> authDetails = auth.getAuthDetails() done() afterEach (done) -> testUtils.cleanupTestKeystore -> done() it "Should fetch the current HIM server certificate", (done) -> testUtils.setupTestKeystore (keystore) -> request("https://localhost:8080") .get("/keystore/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(200) .end (err, res) -> if err done err else res.body.data.should.be.exactly keystore.cert.data res.body.commonName.should.be.exactly 'localhost' done() it "Should not allow a non-admin user to fetch the current HIM server certificate", (done) -> testUtils.setupTestKeystore -> request("https://localhost:8080") .get("/keystore/cert") .set("auth-username", testUtils.nonRootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(403) .end (err, res) -> if err done err else done() it "Should fetch the current trusted ca certificates", (done) -> testUtils.setupTestKeystore (keystore) -> request("https://localhost:8080") .get("/keystore/ca") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(200) .end (err, res) -> if err done err else res.body.should.be.instanceof(Array).and.have.lengthOf(2) res.body[0].should.have.property 'commonName', keystore.ca[0].commonName res.body[1].should.have.property 'commonName', keystore.ca[1].commonName done() it "Should not allow a non-admin user to fetch the current trusted ca certificates", (done) -> testUtils.setupTestKeystore -> request("https://localhost:8080") .get("/keystore/ca") .set("auth-username", testUtils.nonRootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(403) .end (err, res) -> if err done err else done() it "Should fetch a ca certificate by id", (done) -> testUtils.setupTestKeystore (keystore) -> request("https://localhost:8080") .get("/keystore/ca/#{keystore.ca[0]._id}") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(200) .end (err, res) -> if err done err else res.body.should.have.property 'commonName', keystore.ca[0].commonName res.body.should.have.property 'data', keystore.ca[0].data done() it "Should not allow a non-admin user to fetch a ca certificate by id", (done) -> testUtils.setupTestKeystore -> request("https://localhost:8080") .get("/keystore/ca/1234") .set("auth-username", testUtils.nonRootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(403) .end (err, res) -> if err done err else done() it "Should add a new server certificate", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: fs.readFileSync('test/resources/server-tls/cert.pem').toString() } request("https://localhost:8080") .post("/keystore/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(201) .end (err, res) -> if err done err else Keystore.findOne {}, (err, keystore) -> done(err) if err keystore.cert.data.should.be.exactly postData.cert keystore.cert.commonName.should.be.exactly 'localhost' keystore.cert.organization.should.be.exactly 'Jembi Health Systems NPC' done() it "Should calculate and store the correct certificate fingerprint", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: fs.readFileSync('test/resources/server-tls/cert.pem').toString() } request("https://localhost:8080") .post("/keystore/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(201) .end (err, res) -> if err done err else Keystore.findOne {}, (err, keystore) -> done(err) if err keystore.cert.fingerprint.should.be.exactly '35:B1:95:80:45:F6:39:A8:1E:75:E1:B1:16:16:32:EB:12:EA:1A:24' done() it "Should return a 400 if the server certificate isn't valid", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: 'junkjunkjunk' } request("https://localhost:8080") .post("/keystore/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(400) .end (err, res) -> if err done err else done() it "Should not allow a non-admin user to add a new server certificate", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: fs.readFileSync('test/resources/server-tls/cert.pem').toString() } request("https://localhost:8080") .post("/keystore/cert") .set("auth-username", testUtils.nonRootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(403) .end (err, res) -> if err done err else done() it "Should return 400 if watchFSForCert option is true when adding a cert.", (done) -> testUtils.setupTestKeystore (keystore) -> config.certificateManagement.watchFSForCert = true postData = { cert: fs.readFileSync('test/resources/server-tls/cert.pem').toString() } request("https://localhost:8080") .post("/keystore/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(400) .end (err, res) -> if err config.certificateManagement.watchFSForCert = false done err else config.certificateManagement.watchFSForCert = false done() it "Should add a new server key", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { key: fs.readFileSync('test/resources/server-tls/key.pem').toString() } request("https://localhost:8080") .post("/keystore/key") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(201) .end (err, res) -> if err done err else Keystore.findOne {}, (err, keystore) -> done(err) if err keystore.key.should.be.exactly postData.key done() it "Should not allow a non-admin user to add a new server key", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { key: fs.readFileSync('test/resources/server-tls/key.pem').toString() } request("https://localhost:8080") .post("/keystore/key") .set("auth-username", testUtils.nonRootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(403) .end (err, res) -> if err done err else done() it "Should add a new trusted certificate", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: fs.readFileSync('test/resources/trust-tls/cert1.pem').toString() } request("https://localhost:8080") .post("/keystore/ca/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(201) .end (err, res) -> if err done err else Keystore.findOne {}, (err, keystore) -> done(err) if err keystore.ca.should.be.instanceOf(Array).and.have.lengthOf 3 keystore.ca[2].data.should.be.exactly postData.cert keystore.ca[2].commonName.should.be.exactly 'trust1.org' keystore.ca[2].organization.should.be.exactly 'Trusted Inc.' done() it "Should calculate fingerprint for new trusted certificate", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: fs.readFileSync('test/resources/trust-tls/cert1.pem').toString() } request("https://localhost:8080") .post("/keystore/ca/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(201) .end (err, res) -> if err done err else Keystore.findOne {}, (err, keystore) -> done(err) if err keystore.ca[2].fingerprint.should.be.exactly '23:1D:0B:AA:70:06:A5:D4:DC:E9:B9:C3:BD:2C:56:7F:29:D2:3E:54' done() it "Should respond with a 400 if one or more certs are invalid", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: 'junkjunkjunk' } request("https://localhost:8080") .post("/keystore/ca/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(400) .end (err, res) -> if err done err else done() it "Should not allow a non-admin user to add a new trusted certificate", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: fs.readFileSync('test/resources/trust-tls/cert1.pem').toString() } request("https://localhost:8080") .post("/keystore/ca/cert") .set("auth-username", testUtils.nonRootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(403) .end (err, res) -> if err done err else done() it "Should add each certificate in a certificate chain", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: fs.readFileSync('test/resources/chain.pem').toString() } request("https://localhost:8080") .post("/keystore/ca/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(201) .end (err, res) -> if err done err else Keystore.findOne {}, (err, keystore) -> done(err) if err keystore.ca.should.be.instanceOf(Array).and.have.lengthOf 4 keystore.ca[2].commonName.should.be.exactly 'domain.com' keystore.ca[3].commonName.should.be.exactly 'ca.marc-hi.ca' done() it "Should return 400 with there is an invlaid cert in the chain", (done) -> testUtils.setupTestKeystore (keystore) -> postData = { cert: fs.readFileSync('test/resources/invalid-chain.pem').toString() } request("https://localhost:8080") .post("/keystore/ca/cert") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .send(postData) .expect(400) .end (err, res) -> if err done err else done() it "Should remove a ca certificate by id", (done) -> testUtils.setupTestKeystore (keystore) -> request("https://localhost:8080") .del("/keystore/ca/#{keystore.ca[0]._id}") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(200) .end (err, res) -> if err done err else Keystore.findOne {}, (err, keystore) -> done(err) if err keystore.ca.should.be.instanceOf(Array).and.have.lengthOf 1 done() it "Should not allow a non-admin user to remove a ca certificate by id", (done) -> testUtils.setupTestKeystore -> request("https://localhost:8080") .del("/keystore/ca/1234") .set("auth-username", testUtils.nonRootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(403) .end (err, res) -> if err done err else done() it "Should verify that a valid server cert and key match", (done) -> testUtils.setupTestKeystore (keystore) -> request("https://localhost:8080") .get("/keystore/validity") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(200) .end (err, res) -> if err done err else res.body.valid.should.be.exactly true done() it "Should verify that an server cert and key DO NOT match if they are invalid", (done) -> testUtils.setupTestKeystore (keystore) -> keystore.key = fs.readFileSync 'test/resources/trust-tls/key1.pem' keystore.save -> request("https://localhost:8080") .get("/keystore/validity") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(200) .end (err, res) -> if err done err else res.body.valid.should.be.exactly false done() it "Should respond with a 400 if one or more certs are invalid when checking validity", (done) -> testUtils.setupTestKeystore (keystore) -> keystore.key = 'junkjunkjunk' keystore.save -> request("https://localhost:8080") .get("/keystore/validity") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(400) .end (err, res) -> if err done err else done() it "Should find the compare the modulus of a certificate with its corresponding protected key", (done) -> testUtils.setupTestKeystore (keystore) -> keystore.key = fs.readFileSync 'test/resources/protected/test.key' keystore.cert.data = fs.readFileSync 'test/resources/protected/test.crt' keystore.passphrase = 'password' keystore.save -> request("https://localhost:8080") .get("/keystore/validity") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(200) .end (err, res) -> if err done err else res.body.valid.should.be.exactly true done() it "Should return false for when validating a protected key without a passphrase", (done) -> testUtils.setupTestKeystore (keystore) -> keystore.key = fs.readFileSync 'test/resources/protected/test.key' keystore.cert.data = fs.readFileSync 'test/resources/protected/test.crt' keystore.passphrase = undefined keystore.save -> request("https://localhost:8080") .get("/keystore/validity") .set("auth-username", testUtils.rootUser.email) .set("auth-ts", authDetails.authTS) .set("auth-salt", authDetails.authSalt) .set("auth-token", authDetails.authToken) .expect(200) .end (err, res) -> if err done err else res.body.valid.should.be.exactly false done()