mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Improve Middleware Code Coverage
refs #5286 - finished tests for check-ssl.js
This commit is contained in:
parent
c8dd095c36
commit
762824690a
2 changed files with 151 additions and 79 deletions
|
@ -1,5 +1,6 @@
|
||||||
var config = require('../config'),
|
var config = require('../config'),
|
||||||
url = require('url');
|
url = require('url'),
|
||||||
|
checkSSL;
|
||||||
|
|
||||||
function isSSLrequired(isAdmin, configUrl, forceAdminSSL) {
|
function isSSLrequired(isAdmin, configUrl, forceAdminSSL) {
|
||||||
var forceSSL = url.parse(configUrl).protocol === 'https:' ? true : false;
|
var forceSSL = url.parse(configUrl).protocol === 'https:' ? true : false;
|
||||||
|
@ -46,7 +47,7 @@ function sslForbiddenOrRedirect(opt) {
|
||||||
|
|
||||||
// Check to see if we should use SSL
|
// Check to see if we should use SSL
|
||||||
// and redirect if needed
|
// and redirect if needed
|
||||||
function checkSSL(req, res, next) {
|
checkSSL = function checkSSL(req, res, next) {
|
||||||
if (isSSLrequired(res.isAdmin, config.url, config.forceAdminSSL)) {
|
if (isSSLrequired(res.isAdmin, config.url, config.forceAdminSSL)) {
|
||||||
if (!req.secure) {
|
if (!req.secure) {
|
||||||
var response = sslForbiddenOrRedirect({
|
var response = sslForbiddenOrRedirect({
|
||||||
|
@ -64,9 +65,6 @@ function checkSSL(req, res, next) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = checkSSL;
|
module.exports = checkSSL;
|
||||||
// SSL helper functions are exported primarily for unit testing.
|
|
||||||
module.exports.isSSLrequired = isSSLrequired;
|
|
||||||
module.exports.sslForbiddenOrRedirect = sslForbiddenOrRedirect;
|
|
||||||
|
|
|
@ -1,92 +1,166 @@
|
||||||
/*globals describe, it, beforeEach, afterEach */
|
/*globals describe, it, beforeEach, afterEach */
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var sinon = require('sinon'),
|
var sinon = require('sinon'),
|
||||||
|
should = require('should'),
|
||||||
|
config = require('../../../server/config'),
|
||||||
checkSSL = require('../../../server/middleware/check-ssl');
|
checkSSL = require('../../../server/middleware/check-ssl');
|
||||||
|
|
||||||
|
should.equal(true, true);
|
||||||
|
|
||||||
describe('checkSSL', function () {
|
describe('checkSSL', function () {
|
||||||
var sandbox, res, req, next;
|
var res, req, next, sandbox;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
sandbox = sinon.sandbox.create();
|
sandbox = sinon.sandbox.create();
|
||||||
req = sinon.spy();
|
req = {};
|
||||||
res = sinon.spy();
|
res = {};
|
||||||
next = sinon.spy();
|
next = sandbox.spy();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('skips if already on SSL', function () {
|
it('should not require SSL (frontend)', function (done) {
|
||||||
res.isAdmin = true;
|
req.url = '/';
|
||||||
req.isSecure = true;
|
config.set({
|
||||||
|
url: 'http://default.com:2368/'
|
||||||
|
});
|
||||||
checkSSL(req, res, next);
|
checkSSL(req, res, next);
|
||||||
next.called.should.be.true;
|
next.called.should.be.true;
|
||||||
});
|
next.calledWith().should.be.true;
|
||||||
});
|
done();
|
||||||
|
});
|
||||||
describe('isSSLRequired', function () {
|
|
||||||
var isSSLrequired = checkSSL.isSSLrequired;
|
it('should require SSL (frontend)', function (done) {
|
||||||
|
req.url = '/';
|
||||||
it('SSL is required if config.url starts with https', function () {
|
req.secure = true;
|
||||||
isSSLrequired(undefined, 'https://example.com', undefined).should.be.true;
|
config.set({
|
||||||
});
|
url: 'https://default.com:2368/'
|
||||||
|
});
|
||||||
it('SSL is required if isAdmin and config.forceAdminSSL is set', function () {
|
checkSSL(req, res, next);
|
||||||
isSSLrequired(true, 'http://example.com', true).should.be.true;
|
next.called.should.be.true;
|
||||||
});
|
next.calledWith().should.be.true;
|
||||||
|
done();
|
||||||
it('SSL is not required if config.url starts with "http:/" and forceAdminSSL is not set', function () {
|
});
|
||||||
isSSLrequired(false, 'http://example.com', false).should.be.false;
|
|
||||||
});
|
it('should not require SSL (admin)', function (done) {
|
||||||
});
|
req.url = '/ghost';
|
||||||
|
res.isAdmin = true;
|
||||||
describe('sslForbiddenOrRedirect', function () {
|
config.set({
|
||||||
var sslForbiddenOrRedirect = checkSSL.sslForbiddenOrRedirect;
|
url: 'http://default.com:2368/'
|
||||||
it('Return forbidden if config forces admin SSL for AdminSSL redirect is false.', function () {
|
});
|
||||||
var response = sslForbiddenOrRedirect({
|
checkSSL(req, res, next);
|
||||||
forceAdminSSL: {redirect: false},
|
next.called.should.be.true;
|
||||||
configUrl: 'http://example.com'
|
next.calledWith().should.be.true;
|
||||||
});
|
done();
|
||||||
response.isForbidden.should.be.true;
|
});
|
||||||
});
|
|
||||||
|
it('should not redirect with SSL (admin)', function (done) {
|
||||||
it('If not forbidden, should produce SSL to redirect to when config.url ends with no slash', function () {
|
req.url = '/ghost';
|
||||||
var response = sslForbiddenOrRedirect({
|
res.isAdmin = true;
|
||||||
forceAdminSSL: {redirect: true},
|
res.secure = true;
|
||||||
configUrl: 'http://example.com/config/path',
|
config.set({
|
||||||
reqUrl: '/req/path'
|
url: 'http://default.com:2368/'
|
||||||
});
|
});
|
||||||
response.isForbidden.should.be.false;
|
checkSSL(req, res, next);
|
||||||
response.redirectUrl({}).should.equal('https://example.com/config/path/req/path');
|
next.called.should.be.true;
|
||||||
});
|
next.calledWith().should.be.true;
|
||||||
|
done();
|
||||||
it('If config ends is slash, potential double-slash in resulting URL is removed', function () {
|
});
|
||||||
var response = sslForbiddenOrRedirect({
|
|
||||||
forceAdminSSL: {redirect: true},
|
it('should not redirect with force admin SSL (admin)', function (done) {
|
||||||
configUrl: 'http://example.com/config/path/',
|
req.url = '/ghost';
|
||||||
reqUrl: '/req/path'
|
res.isAdmin = true;
|
||||||
});
|
req.secure = true;
|
||||||
response.redirectUrl({}).should.equal('https://example.com/config/path/req/path');
|
config.set({
|
||||||
});
|
url: 'http://default.com:2368/',
|
||||||
|
forceAdminSSL: true
|
||||||
it('If config.urlSSL is provided it is preferred over config.url', function () {
|
});
|
||||||
var response = sslForbiddenOrRedirect({
|
checkSSL(req, res, next);
|
||||||
forceAdminSSL: {redirect: true},
|
next.called.should.be.true;
|
||||||
configUrl: 'http://example.com/config/path/',
|
next.calledWith().should.be.true;
|
||||||
configUrlSSL: 'https://example.com/ssl/config/path/',
|
done();
|
||||||
reqUrl: '/req/path'
|
});
|
||||||
});
|
|
||||||
response.redirectUrl({}).should.equal('https://example.com/ssl/config/path/req/path');
|
it('should redirect with force admin SSL (admin)', function (done) {
|
||||||
});
|
req.url = '/ghost/';
|
||||||
|
res.isAdmin = true;
|
||||||
it('query string in request is preserved in redirect URL', function () {
|
res.redirect = {};
|
||||||
var response = sslForbiddenOrRedirect({
|
req.secure = false;
|
||||||
forceAdminSSL: {redirect: true},
|
config.set({
|
||||||
configUrl: 'http://example.com/config/path/',
|
url: 'http://default.com:2368/',
|
||||||
configUrlSSL: 'https://example.com/ssl/config/path/',
|
urlSSL: '',
|
||||||
reqUrl: '/req/path'
|
forceAdminSSL: true
|
||||||
});
|
});
|
||||||
response.redirectUrl({a: 'b'}).should.equal('https://example.com/ssl/config/path/req/path?a=b');
|
sandbox.stub(res, 'redirect', function (statusCode, url) {
|
||||||
|
statusCode.should.eql(301);
|
||||||
|
url.should.not.be.empty;
|
||||||
|
url.should.eql('https://default.com:2368/ghost/');
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
checkSSL(req, res, next);
|
||||||
|
next.called.should.be.false;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect with with config.url being SSL (frontend)', function (done) {
|
||||||
|
req.url = '';
|
||||||
|
req.secure = false;
|
||||||
|
res.redirect = {};
|
||||||
|
config.set({
|
||||||
|
url: 'https://default.com:2368',
|
||||||
|
urlSSL: '',
|
||||||
|
forceAdminSSL: true
|
||||||
|
});
|
||||||
|
sandbox.stub(res, 'redirect', function (statusCode, url) {
|
||||||
|
statusCode.should.eql(301);
|
||||||
|
url.should.not.be.empty;
|
||||||
|
url.should.eql('https://default.com:2368/');
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
checkSSL(req, res, next);
|
||||||
|
next.called.should.be.false;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect to urlSSL (admin)', function (done) {
|
||||||
|
req.url = '/ghost/';
|
||||||
|
res.isAdmin = true;
|
||||||
|
res.redirect = {};
|
||||||
|
req.secure = false;
|
||||||
|
config.set({
|
||||||
|
url: 'http://default.com:2368/',
|
||||||
|
urlSSL: 'https://ssl-domain.com:2368/'
|
||||||
|
});
|
||||||
|
sandbox.stub(res, 'redirect', function (statusCode, url) {
|
||||||
|
statusCode.should.eql(301);
|
||||||
|
url.should.not.be.empty;
|
||||||
|
url.should.eql('https://ssl-domain.com:2368/ghost/');
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
checkSSL(req, res, next);
|
||||||
|
next.called.should.be.false;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not redirect if redirect:false (admin)', function (done) {
|
||||||
|
req.url = '/ghost/';
|
||||||
|
res.isAdmin = true;
|
||||||
|
res.sendStatus = {};
|
||||||
|
req.secure = false;
|
||||||
|
config.set({
|
||||||
|
url: 'http://default.com:2368/',
|
||||||
|
forceAdminSSL: {
|
||||||
|
redirect: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sandbox.stub(res, 'sendStatus', function (statusCode) {
|
||||||
|
statusCode.should.eql(403);
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
checkSSL(req, res, next);
|
||||||
|
next.called.should.be.false;
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue