Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
198 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
node_modules | ||
*.iml | ||
/tmp | ||
/coverage | ||
/coverage | ||
/test-tmp |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
const pify = require('pify') | ||
const crypt = require('crypt3') | ||
const cpr = pify(require('cpr')) | ||
|
||
// Constant salt used for hashes in these test cases | ||
const SALT = '$6$V5oMyA+u8Q2U/g==' | ||
|
||
// Original contents of the fixture "postfix-accounts.cf" | ||
const fixture = { | ||
'mailtest@test.knappi.org': hashFor('abc', '$6$UeXF8rxTS/a7bHrp'), | ||
'railtest@test.knappi.org': hashFor('abcd', '$6$y628bqC.aK2m.ncq') | ||
} | ||
|
||
/** | ||
* Compute expected hash for a password | ||
* @param {string} password the password | ||
* @param {string=} salt the salt. Default is the mock SALT used in most tests | ||
*/ | ||
function hashFor (password, salt) { | ||
return `{SHA512-CRYPT}${crypt(password, salt || SALT)}` | ||
} | ||
|
||
/** | ||
* Setup beforeEach and afterEach hooks that are generally needed. | ||
* | ||
* These do the following things: | ||
* | ||
* * Setup the mock salt to ensure deterministic hashes | ||
* * Restore the original salt function after each test | ||
* * Setup the tmp-directory before each test | ||
*/ | ||
function mochaSetup () { | ||
/* eslint-env mocha */ | ||
let originalSHA512Salter | ||
|
||
beforeEach(async function () { | ||
await cpr('test/fixtures', 'test-tmp/fixtures', {deleteFirst: true}) | ||
|
||
// mock "createSalt" to get deterministic hashes | ||
originalSHA512Salter = crypt.createSalt.salters['sha512'] | ||
crypt.createSalt.salters['sha512'] = () => SALT | ||
}) | ||
|
||
afterEach(function () { | ||
crypt.createSalt.salters['sha512'] = originalSHA512Salter | ||
}) | ||
} | ||
|
||
module.exports = { | ||
fixture, | ||
hashFor, | ||
mochaSetup | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
railtest@test.knappi.org|{SHA512-CRYPT}$6$y628bqC.aK2m.ncq$/f9ARypMSviNXMD1ZqdFO6B9Vl8O6X.7ZIauNm34bpUCWnDg91C9OgcnQ/7XZh7rCt1JPQfc/g/vpRdWTqbp0/ | ||
mailtest@test.knappi.org|{SHA512-CRYPT}$6$UeXF8rxTS/a7bHrp$yQaj.9fgyDckIP3pgspd6YKUsyN8K54Am3n5kSpYwFG3C1gHKAM4MlfCcBkJsd5vB/UNAPfUlA6ShOIQa4Vmr/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/*! | ||
* docker-mailserver-management <https://github.com/nknapp/docker-mailserver-management> | ||
* | ||
* Copyright (c) 2017 Nils Knappmeier. | ||
* Released under the MIT license. | ||
*/ | ||
|
||
/* eslint-env mocha */ | ||
|
||
const {PostfixAccounts} = require('../src/postfix-accounts') | ||
|
||
const express = require('express') | ||
const {createRouter} = require('../src/router') | ||
const http = require('http') | ||
const popsicle = require('popsicle') | ||
|
||
const chai = require('chai') | ||
chai.use(require('dirty-chai')) | ||
chai.use(require('chai-as-promised')) | ||
const expect = chai.expect | ||
const {mochaSetup, hashFor, fixture} = require('./_utils') | ||
|
||
describe('the router:', function () { | ||
|
||
var server | ||
var baseUrl | ||
var postfixAccounts | ||
before(async () => { | ||
postfixAccounts = await PostfixAccounts.load('test-tmp/fixtures/postfix-accounts.cf') | ||
|
||
var app = express() | ||
app.use(createRouter(postfixAccounts)) | ||
server = http.createServer(app) | ||
return new Promise((resolve, reject) => { | ||
server.listen(function (err) { | ||
baseUrl = `http://localhost:${server.address().port}` | ||
return err ? reject(err) : resolve() | ||
}) | ||
}) | ||
}) | ||
|
||
after(() => { | ||
return new Promise((resolve, reject) => { | ||
server.close((err) => err ? reject(err) : resolve()) | ||
}) | ||
}) | ||
|
||
// Setup tmp directory and salt | ||
mochaSetup() | ||
|
||
beforeEach(() => postfixAccounts.reload()) | ||
|
||
// invoke the rest-resource | ||
function verifyAndUpdate (username, oldPassword, newPassword) { | ||
return popsicle | ||
.post({url: `${baseUrl}/user/${encodeURIComponent(username)}`, body: {oldPassword, newPassword}}) | ||
.use(popsicle.plugins.parse(['json'])) | ||
} | ||
|
||
describe('The /user/:username resource', function () { | ||
it('should write the new password if the old password is correct', async function () { | ||
const response = await verifyAndUpdate('mailtest@test.knappi.org', 'abc', 'ab') | ||
|
||
// Checking response | ||
expect(response.status).to.equal(200) | ||
expect(response.body).to.deep.equal({'success': true, 'username': 'mailtest@test.knappi.org'}) | ||
// Checking modification of accounts object | ||
expect(postfixAccounts.accounts).to.deep.equal({ | ||
'mailtest@test.knappi.org': hashFor('ab'), | ||
'railtest@test.knappi.org': fixture['railtest@test.knappi.org'] | ||
}) | ||
}) | ||
|
||
it('should return 403 if the old password is incorrect', async function () { | ||
const response = await verifyAndUpdate('mailtest@test.knappi.org', 'badPassword', 'ab') | ||
|
||
// Checking response | ||
expect(response.status).to.equal(403) | ||
expect(response.body).to.deep.equal({ | ||
'success': false, | ||
'code': 403, | ||
'message': 'Bad username or password' | ||
}) | ||
// Checking non-modification of accounts object | ||
expect(postfixAccounts.accounts).to.deep.equal(fixture) | ||
}) | ||
|
||
it('should return 400 if now old password is specified', async function () { | ||
const response = await verifyAndUpdate('mailtest@test.knappi.org') | ||
|
||
// Checking response | ||
expect(response.status).to.equal(400) | ||
expect(response.body).to.deep.equal({ | ||
'success': false, | ||
'code': 400, | ||
'message': 'Request must contain username, oldPassword and newPassword' | ||
}) | ||
// Checking non-modification of accounts object | ||
expect(postfixAccounts.accounts).to.deep.equal(fixture) | ||
}) | ||
}) | ||
}) |