commit
bf3d0c76d2
|
@ -5,3 +5,4 @@ coverage/
|
||||||
|
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
|
*.sh
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
language: node_js
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
- ntp
|
||||||
|
before_install: npm install -g npm@'>=2.13.5'
|
||||||
|
script:
|
||||||
|
- npm test
|
||||||
|
- docker-compose build
|
||||||
|
- docker-compose up -d
|
||||||
|
- sleep 5
|
||||||
|
- npm run-script integration-test
|
||||||
|
deploy:
|
||||||
|
provider: npm
|
||||||
|
email: clement.michaud34@gmail.com
|
||||||
|
api_key:
|
||||||
|
secure: hf7z+5j/3M+NkE3qcTdpKKa6P9CsrzbvoNp0FcuLzwYQlMyAW0BP+5Tktz39gqcIn3MYAYUQYOSjoTE1D9Ji5ImPREYR7qdU/V02NdkhLh19+/Be1t7a+uPi/NZ0dlqN3tnRsCpfuneHU1gH9K6KQjrP8fDgy6ehaunKY/vh2F5uk8Ip1lMdUA2Um7mwANzapEnjwyCELmuNwKMx0zqD8V+cjF7B0MZO/T4UTOx5+KG6yWrdmTSz2+IoCwtz5Ca6LtS+xovv8eEVkNbYFwojFQiYq63FXX2EY18A6tNkiBYRVCg9VC4yjtP+OfYK5ueN4gvsVH8IK70cEm6k3IVaI9AhxHC75tF5fW3/6oT3VikUZv7sPpWYQz4jlDCoJoXwNPA4gJh+Y8g+x+5SvG6CSgPpfTWL9y9XGb5+NCZIoRbVHBQp9z/xJPOO4RIJvhWTaZ3houL07KUYyVVqk7GxgNrfgpam1rX1ze1ajhJ7Cmv6TKCg0Av9aaSQ9g0kLYUfmG0pU+vzkckwok26u6+2nMsp6mZZctnhYaBzsai0T5CGSbQrouT+YSOexHw3HS3O0rm10ZLir3tK5QC7GytOKuzV0Nal7e3U6xXlYwBxvUXMZCNyOJM5+II7ucdvM6Jzhbro1i1zt7hwP6+lXdH7sFpaszP3dbkwotGs8OlswrM=
|
||||||
|
on:
|
||||||
|
tags: true
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
recipients:
|
||||||
|
- clement.michaud34@gmail.com
|
||||||
|
on_success: change
|
||||||
|
on_failure: always
|
||||||
|
|
|
@ -7,5 +7,4 @@ RUN npm install
|
||||||
|
|
||||||
COPY src /usr/src
|
COPY src /usr/src
|
||||||
|
|
||||||
|
|
||||||
CMD ["node", "index.js"]
|
CMD ["node", "index.js"]
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "ldap-totp-nginx-auth",
|
"name": "ldap-totp-nginx-auth",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "./node_modules/.bin/mocha",
|
"test": "./node_modules/.bin/mocha --recursive test/unitary",
|
||||||
|
"integration-test": "./node_modules/.bin/mocha --recursive test/integration",
|
||||||
"coverage": "./node_modules/.bin/istanbul cover _mocha -- -R spec"
|
"coverage": "./node_modules/.bin/istanbul cover _mocha -- -R spec"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -13,8 +13,8 @@ var config = {
|
||||||
}
|
}
|
||||||
|
|
||||||
var ldap_client = ldap.createClient({
|
var ldap_client = ldap.createClient({
|
||||||
url: config.ldap_url
|
url: config.ldap_url,
|
||||||
|
reconnect: true
|
||||||
});
|
});
|
||||||
|
|
||||||
server.run(config, ldap_client);
|
server.run(config, ldap_client);
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ function authenticate(req, res) {
|
||||||
|
|
||||||
function verify_authentication(req, res) {
|
function verify_authentication(req, res) {
|
||||||
console.log('Verify authentication');
|
console.log('Verify authentication');
|
||||||
console.log(req.cookies);
|
|
||||||
|
|
||||||
if(!objectPath.has(req, 'cookies.access_token')) {
|
if(!objectPath.has(req, 'cookies.access_token')) {
|
||||||
return utils.reject('No access token provided');
|
return utils.reject('No access token provided');
|
||||||
|
|
|
@ -33,7 +33,6 @@ function serveAuthPost(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function serveLogin(req, res) {
|
function serveLogin(req, res) {
|
||||||
console.log(req.headers);
|
|
||||||
res.render('login');
|
res.render('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
|
||||||
|
var request_ = require('request');
|
||||||
|
var assert = require('assert');
|
||||||
|
var speakeasy = require('speakeasy');
|
||||||
|
var j = request_.jar();
|
||||||
|
var request = request_.defaults({jar: j});
|
||||||
|
var Q = require('q');
|
||||||
|
|
||||||
|
var BASE_URL = 'http://localhost:8080';
|
||||||
|
|
||||||
|
describe('test the server', function() {
|
||||||
|
var home_page;
|
||||||
|
var login_page;
|
||||||
|
var config = {
|
||||||
|
port: 8090,
|
||||||
|
totp_secret: 'totp_secret',
|
||||||
|
ldap_url: 'ldap://127.0.0.1:389',
|
||||||
|
ldap_users_dn: 'ou=users,dc=example,dc=com',
|
||||||
|
jwt_secret: 'jwt_secret',
|
||||||
|
jwt_expiration_time: '1h'
|
||||||
|
};
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
var home_page_promise = getHomePage()
|
||||||
|
.then(function(data) {
|
||||||
|
home_page = data.body;
|
||||||
|
});
|
||||||
|
var login_page_promise = getLoginPage()
|
||||||
|
.then(function(data) {
|
||||||
|
login_page = data.body;
|
||||||
|
});
|
||||||
|
return Q.all([home_page_promise,
|
||||||
|
login_page_promise]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should serve the login page', function(done) {
|
||||||
|
getPromised(BASE_URL + '/auth/login?redirect=/')
|
||||||
|
.then(function(data) {
|
||||||
|
assert.equal(data.response.statusCode, 200);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should serve the homepage', function(done) {
|
||||||
|
getPromised(BASE_URL + '/')
|
||||||
|
.then(function(data) {
|
||||||
|
assert.equal(data.response.statusCode, 200);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect when logout', function(done) {
|
||||||
|
getPromised(BASE_URL + '/auth/logout?redirect=/')
|
||||||
|
.then(function(data) {
|
||||||
|
assert.equal(data.response.statusCode, 200);
|
||||||
|
assert.equal(data.body, home_page);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be redirected to the login page when accessing secret while not authenticated', function(done) {
|
||||||
|
getPromised(BASE_URL + '/secret.html')
|
||||||
|
.then(function(data) {
|
||||||
|
assert.equal(data.response.statusCode, 200);
|
||||||
|
assert.equal(data.body, login_page);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail the login', function(done) {
|
||||||
|
postPromised(BASE_URL + '/_auth', {
|
||||||
|
form: {
|
||||||
|
username: 'admin',
|
||||||
|
password: 'password',
|
||||||
|
token: 'abc'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
assert.equal(data.body, 'Authentication failed');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should login and access the secret', function(done) {
|
||||||
|
var token = speakeasy.totp({
|
||||||
|
secret: 'GRWGIJS6IRHVEODVNRCXCOBMJ5AGC6ZE',
|
||||||
|
encoding: 'base32'
|
||||||
|
});
|
||||||
|
|
||||||
|
postPromised(BASE_URL + '/_auth', {
|
||||||
|
form: {
|
||||||
|
username: 'admin',
|
||||||
|
password: 'password',
|
||||||
|
token: token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
assert.equal(data.response.statusCode, 200);
|
||||||
|
assert.equal(data.body.length, 148);
|
||||||
|
var cookie = request.cookie('access_token=' + data.body);
|
||||||
|
j.setCookie(cookie, BASE_URL + '/_auth');
|
||||||
|
return getPromised(BASE_URL + '/secret.html');
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
var content = data.body;
|
||||||
|
var is_secret_page_content =
|
||||||
|
(content.indexOf('This is a very important secret!') > -1);
|
||||||
|
assert(is_secret_page_content);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.fail(function(err) {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should logoff and should not be able to access secret anymore', function(done) {
|
||||||
|
getPromised(BASE_URL + '/secret.html')
|
||||||
|
.then(function(data) {
|
||||||
|
var content = data.body;
|
||||||
|
var is_secret_page_content =
|
||||||
|
(content.indexOf('This is a very important secret!') > -1);
|
||||||
|
assert(is_secret_page_content);
|
||||||
|
return getPromised(BASE_URL + '/auth/logout')
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
assert.equal(data.response.statusCode, 200);
|
||||||
|
assert.equal(data.body, home_page);
|
||||||
|
return getPromised(BASE_URL + '/secret.html');
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
var content = data.body;
|
||||||
|
assert.equal(data.body, login_page);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.fail(function(err) {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function responsePromised(defer) {
|
||||||
|
return function(error, response, body) {
|
||||||
|
if(error) {
|
||||||
|
console.error(error);
|
||||||
|
defer.reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
defer.resolve({
|
||||||
|
response: response,
|
||||||
|
body: body
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPromised(url) {
|
||||||
|
var defer = Q.defer();
|
||||||
|
request.get(url, responsePromised(defer));
|
||||||
|
return defer.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function postPromised(url, body) {
|
||||||
|
var defer = Q.defer();
|
||||||
|
request.post(url, body, responsePromised(defer));
|
||||||
|
return defer.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHomePage() {
|
||||||
|
return getPromised(BASE_URL + '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLoginPage() {
|
||||||
|
return getPromised(BASE_URL + '/auth/login');
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var authentication = require('../src/lib/authentication');
|
var authentication = require('../../src/lib/authentication');
|
||||||
var create_res_mock = require('./res_mock');
|
var create_res_mock = require('./res_mock');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var Jwt = require('../src/lib/jwt');
|
var Jwt = require('../../src/lib/jwt');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
||||||
sinonPromise(sinon);
|
sinonPromise(sinon);
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var ldap_checker = require('../src/lib/ldap_checker');
|
var ldap_checker = require('../../src/lib/ldap_checker');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var replies = require('../src/lib/replies');
|
var replies = require('../../src/lib/replies');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
|
@ -1,11 +1,14 @@
|
||||||
|
|
||||||
|
var server = require('../../src/lib/server');
|
||||||
|
var Jwt = require('../../src/lib/jwt');
|
||||||
|
|
||||||
var request = require('request');
|
var request = require('request');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var server = require('../src/lib/server');
|
|
||||||
var Jwt = require('../src/lib/jwt');
|
|
||||||
var speakeasy = require('speakeasy');
|
var speakeasy = require('speakeasy');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
|
|
||||||
|
var BASE_URL = 'http://localhost:8090';
|
||||||
|
|
||||||
describe('test the server', function() {
|
describe('test the server', function() {
|
||||||
var jwt = new Jwt('jwt_secret');
|
var jwt = new Jwt('jwt_secret');
|
||||||
var ldap_client = {
|
var ldap_client = {
|
||||||
|
@ -14,7 +17,7 @@ describe('test the server', function() {
|
||||||
|
|
||||||
before(function() {
|
before(function() {
|
||||||
var config = {
|
var config = {
|
||||||
port: 8080,
|
port: 8090,
|
||||||
totp_secret: 'totp_secret',
|
totp_secret: 'totp_secret',
|
||||||
ldap_url: 'ldap://127.0.0.1:389',
|
ldap_url: 'ldap://127.0.0.1:389',
|
||||||
ldap_users_dn: 'ou=users,dc=example,dc=com',
|
ldap_users_dn: 'ou=users,dc=example,dc=com',
|
||||||
|
@ -50,7 +53,7 @@ describe('test the server', function() {
|
||||||
|
|
||||||
function test_login() {
|
function test_login() {
|
||||||
it('should serve the login page', function(done) {
|
it('should serve the login page', function(done) {
|
||||||
request.get('http://localhost:8080/login')
|
request.get(BASE_URL + '/login')
|
||||||
.on('response', function(response) {
|
.on('response', function(response) {
|
||||||
assert.equal(response.statusCode, 200);
|
assert.equal(response.statusCode, 200);
|
||||||
done();
|
done();
|
||||||
|
@ -60,7 +63,7 @@ function test_login() {
|
||||||
|
|
||||||
function test_logout() {
|
function test_logout() {
|
||||||
it('should logout and redirect to /', function(done) {
|
it('should logout and redirect to /', function(done) {
|
||||||
request.get('http://localhost:8080/logout')
|
request.get(BASE_URL + '/logout')
|
||||||
.on('response', function(response) {
|
.on('response', function(response) {
|
||||||
assert.equal(response.req.path, '/');
|
assert.equal(response.req.path, '/');
|
||||||
done();
|
done();
|
||||||
|
@ -70,7 +73,7 @@ function test_logout() {
|
||||||
|
|
||||||
function test_get_auth(jwt) {
|
function test_get_auth(jwt) {
|
||||||
it('should return status code 401 when user is not authenticated', function(done) {
|
it('should return status code 401 when user is not authenticated', function(done) {
|
||||||
request.get('http://localhost:8080/_auth')
|
request.get(BASE_URL + '/_auth')
|
||||||
.on('response', function(response) {
|
.on('response', function(response) {
|
||||||
assert.equal(response.statusCode, 401);
|
assert.equal(response.statusCode, 401);
|
||||||
done();
|
done();
|
||||||
|
@ -82,9 +85,9 @@ function test_get_auth(jwt) {
|
||||||
var r = request.defaults({jar: j});
|
var r = request.defaults({jar: j});
|
||||||
var token = jwt.sign({ user: 'test' }, '1h');
|
var token = jwt.sign({ user: 'test' }, '1h');
|
||||||
var cookie = r.cookie('access_token=' + token);
|
var cookie = r.cookie('access_token=' + token);
|
||||||
j.setCookie(cookie, 'http://localhost:8080/_auth');
|
j.setCookie(cookie, BASE_URL + '/_auth');
|
||||||
|
|
||||||
r.get('http://localhost:8080/_auth')
|
r.get(BASE_URL + '/_auth')
|
||||||
.on('response', function(response) {
|
.on('response', function(response) {
|
||||||
assert.equal(response.statusCode, 204);
|
assert.equal(response.statusCode, 204);
|
||||||
done();
|
done();
|
||||||
|
@ -101,7 +104,7 @@ function test_post_auth() {
|
||||||
});
|
});
|
||||||
var expectedJwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidGVzdF9vayIsImlhdCI6MCwiZXhwIjozNjAwfQ.ihvaljGjO5h3iSO_h3PkNNSCYeePyB8Hr5lfVZZYyrQ';
|
var expectedJwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidGVzdF9vayIsImlhdCI6MCwiZXhwIjozNjAwfQ.ihvaljGjO5h3iSO_h3PkNNSCYeePyB8Hr5lfVZZYyrQ';
|
||||||
|
|
||||||
request.post('http://localhost:8080/_auth', {
|
request.post(BASE_URL + '/_auth', {
|
||||||
form: {
|
form: {
|
||||||
username: 'test_ok',
|
username: 'test_ok',
|
||||||
password: 'password',
|
password: 'password',
|
||||||
|
@ -131,7 +134,7 @@ function test_post_auth() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
request.post('http://localhost:8080/_auth', data, function (error, response, body) {
|
request.post(BASE_URL + '/_auth', data, function (error, response, body) {
|
||||||
if(response.statusCode == 401) {
|
if(response.statusCode == 401) {
|
||||||
clock.restore();
|
clock.restore();
|
||||||
done();
|
done();
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var totp_checker = require('../src/lib/totp_checker');
|
var totp_checker = require('../../src/lib/totp_checker');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
||||||
sinonPromise(sinon);
|
sinonPromise(sinon);
|
Loading…
Reference in New Issue