Add mock request/response classes for testing
This commit is contained in:
parent
cae754672e
commit
5e21c52b95
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Cylon API - Basic Auth
|
||||
* cylonjs.com
|
||||
*
|
||||
* Copyright (c) 2013-2014 The Hybrid Group
|
||||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
var http = require('http');
|
||||
|
||||
module.exports = function(config) {
|
||||
var user = config.user,
|
||||
pass = config.pass;
|
||||
|
||||
return function auth(req, res, next) {
|
||||
var auth = req.headers.authorization;
|
||||
|
||||
if (!auth) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
// malformed
|
||||
var parts = auth.split(' ');
|
||||
|
||||
if ('basic' != parts[0].toLowerCase() || !parts[1]) {
|
||||
return next(error(400));
|
||||
}
|
||||
|
||||
auth = parts[1];
|
||||
|
||||
// credentials
|
||||
auth = new Buffer(auth, 'base64').toString();
|
||||
auth = auth.match(/^([^:]+):(.+)$/);
|
||||
|
||||
if (!auth) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
if (auth[1] === user && auth[2] === pass) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return unauthorized(res);
|
||||
};
|
||||
};
|
||||
|
||||
var unauthorized = function unauthorized(res) {
|
||||
res.statusCode = 401;
|
||||
res.setHeader('WWW-Authenticate', 'Basic realm="Authorization Required"');
|
||||
res.end('Unauthorized');
|
||||
};
|
||||
|
||||
var error = function error(code, msg){
|
||||
var err = new Error(msg || http.STATUS_CODES[code]);
|
||||
err.status = code;
|
||||
return err;
|
||||
};
|
|
@ -0,0 +1,129 @@
|
|||
'use strict'
|
||||
|
||||
var basic = source('api/auth/basic');
|
||||
|
||||
var MockRequest = require('../../../support/mock_request'),
|
||||
MockResponse = require('../../../support/mock_response');
|
||||
|
||||
describe("Basic Auth", function() {
|
||||
var opts = { user: 'user', pass: 'pass' },
|
||||
req,
|
||||
res,
|
||||
next;
|
||||
|
||||
basic = basic(opts);
|
||||
|
||||
beforeEach(function() {
|
||||
req = new MockRequest();
|
||||
res = new MockResponse();
|
||||
next = spy();
|
||||
|
||||
var auth = new Buffer("user:pass", "utf8").toString('base64');
|
||||
req.headers = { authorization: "Basic " + auth };
|
||||
});
|
||||
|
||||
var checkUnauthorized = function() {
|
||||
var result;
|
||||
|
||||
beforeEach(function() {
|
||||
result = basic(req, res, next);
|
||||
});
|
||||
|
||||
it("returns false", function() {
|
||||
expect(result).to.be.falsy;
|
||||
});
|
||||
|
||||
it("sends a 401 error", function() {
|
||||
expect(res.statusCode).to.be.eql(401);
|
||||
expect(res.end).to.be.calledWith("Unauthorized");
|
||||
});
|
||||
};
|
||||
|
||||
var checkError = function() {
|
||||
var result;
|
||||
|
||||
beforeEach(function() {
|
||||
result = basic(req, res, next);
|
||||
});
|
||||
|
||||
it("triggers next with an error", function() {
|
||||
expect(next).to.be.called;
|
||||
});
|
||||
};
|
||||
|
||||
context("with a valid request", function() {
|
||||
var result;
|
||||
|
||||
beforeEach(function() {
|
||||
result = basic(req, res, next);
|
||||
});
|
||||
|
||||
it("returns true", function() {
|
||||
expect(result).to.be.truthy;
|
||||
});
|
||||
|
||||
it("doesn't modify the response", function() {
|
||||
expect(res.end).to.not.be.called;
|
||||
})
|
||||
});
|
||||
|
||||
context("if the user/pass don't match", function() {
|
||||
beforeEach(function() {
|
||||
var auth = new Buffer("bad:wrong", "utf8").toString('base64');
|
||||
req.headers = { authorization: "Basic " + auth };
|
||||
});
|
||||
|
||||
checkUnauthorized();
|
||||
});
|
||||
|
||||
context("if there is already an authorized user", function() {
|
||||
var result;
|
||||
|
||||
beforeEach(function() {
|
||||
req.user = 'user';
|
||||
result = basic(req, res, next);
|
||||
});
|
||||
|
||||
it("returns true", function() {
|
||||
expect(result).to.be.truthy;
|
||||
});
|
||||
|
||||
it("doesn't modify the response", function() {
|
||||
expect(res.end).to.not.be.called;
|
||||
})
|
||||
});
|
||||
|
||||
context("if there are no authorization headers", function() {
|
||||
beforeEach(function() {
|
||||
delete req.headers.authorization;
|
||||
});
|
||||
|
||||
checkUnauthorized();
|
||||
});
|
||||
|
||||
context("the authorization type isn't Basic", function() {
|
||||
beforeEach(function() {
|
||||
var auth = new Buffer("user:pass", "utf8").toString('base64');
|
||||
req.headers = { authorization: "Digest " + auth };
|
||||
});
|
||||
|
||||
checkError();
|
||||
});
|
||||
|
||||
context("the authorization header is missing content", function() {
|
||||
beforeEach(function() {
|
||||
req.headers = { authorization: "Basic" };
|
||||
});
|
||||
|
||||
checkError();
|
||||
});
|
||||
|
||||
context("if the authorization header isn't formatted correctly", function() {
|
||||
beforeEach(function() {
|
||||
var auth = new Buffer("user-pass", "utf8").toString('base64');
|
||||
req.headers = { authorization: "Basic " + auth };
|
||||
});
|
||||
|
||||
checkUnauthorized();
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue