mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Auth tests
- added tests for authentication middleware - changed use of auth strategies
This commit is contained in:
parent
c1a2601514
commit
a993f80a51
3 changed files with 176 additions and 84 deletions
|
@ -1,66 +1,70 @@
|
|||
var passport = require('passport'),
|
||||
BearerStrategy = require('passport-http-bearer').Strategy,
|
||||
ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy,
|
||||
models = require('../models');
|
||||
var BearerStrategy = require('passport-http-bearer').Strategy,
|
||||
ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy,
|
||||
models = require('../models'),
|
||||
strategies;
|
||||
|
||||
/**
|
||||
* ClientPasswordStrategy
|
||||
*
|
||||
* This strategy is used to authenticate registered OAuth clients. It is
|
||||
* employed to protect the `token` endpoint, which consumers use to obtain
|
||||
* access tokens. The OAuth 2.0 specification suggests that clients use the
|
||||
* HTTP Basic scheme to authenticate (not implemented yet).
|
||||
strategies = {
|
||||
|
||||
* Use of the client password strategy is implemented to support ember-simple-auth.
|
||||
*/
|
||||
passport.use(new ClientPasswordStrategy(
|
||||
function strategy(clientId, clientSecret, done) {
|
||||
models.Client.forge({slug: clientId})
|
||||
.fetch()
|
||||
.then(function then(model) {
|
||||
if (model) {
|
||||
var client = model.toJSON();
|
||||
if (client.secret === clientSecret) {
|
||||
return done(null, client);
|
||||
/**
|
||||
* ClientPasswordStrategy
|
||||
*
|
||||
* This strategy is used to authenticate registered OAuth clients. It is
|
||||
* employed to protect the `token` endpoint, which consumers use to obtain
|
||||
* access tokens. The OAuth 2.0 specification suggests that clients use the
|
||||
* HTTP Basic scheme to authenticate (not implemented yet).
|
||||
* Use of the client password strategy is implemented to support ember-simple-auth.
|
||||
*/
|
||||
clientPasswordStrategy: new ClientPasswordStrategy(
|
||||
function strategy(clientId, clientSecret, done) {
|
||||
models.Client.forge({slug: clientId})
|
||||
.fetch()
|
||||
.then(function then(model) {
|
||||
if (model) {
|
||||
var client = model.toJSON();
|
||||
if (client.secret === clientSecret) {
|
||||
return done(null, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
return done(null, false);
|
||||
});
|
||||
}
|
||||
));
|
||||
return done(null, false);
|
||||
});
|
||||
}
|
||||
),
|
||||
|
||||
/**
|
||||
* BearerStrategy
|
||||
*
|
||||
* This strategy is used to authenticate users based on an access token (aka a
|
||||
* bearer token). The user must have previously authorized a client
|
||||
* application, which is issued an access token to make requests on behalf of
|
||||
* the authorizing user.
|
||||
*/
|
||||
passport.use(new BearerStrategy(
|
||||
function strategy(accessToken, done) {
|
||||
models.Accesstoken.forge({token: accessToken})
|
||||
.fetch()
|
||||
.then(function then(model) {
|
||||
if (model) {
|
||||
var token = model.toJSON();
|
||||
if (token.expires > Date.now()) {
|
||||
models.User.forge({id: token.user_id})
|
||||
.fetch()
|
||||
.then(function then(model) {
|
||||
if (model) {
|
||||
var user = model.toJSON(),
|
||||
info = {scope: '*'};
|
||||
return done(null, {id: user.id}, info);
|
||||
}
|
||||
/**
|
||||
* BearerStrategy
|
||||
*
|
||||
* This strategy is used to authenticate users based on an access token (aka a
|
||||
* bearer token). The user must have previously authorized a client
|
||||
* application, which is issued an access token to make requests on behalf of
|
||||
* the authorizing user.
|
||||
*/
|
||||
bearerStrategy: new BearerStrategy(
|
||||
function strategy(accessToken, done) {
|
||||
models.Accesstoken.forge({token: accessToken})
|
||||
.fetch()
|
||||
.then(function then(model) {
|
||||
if (model) {
|
||||
var token = model.toJSON();
|
||||
if (token.expires > Date.now()) {
|
||||
models.User.forge({id: token.user_id})
|
||||
.fetch()
|
||||
.then(function then(model) {
|
||||
if (model) {
|
||||
var user = model.toJSON(),
|
||||
info = {scope: '*'};
|
||||
return done(null, {id: user.id}, info);
|
||||
}
|
||||
return done(null, false);
|
||||
});
|
||||
} else {
|
||||
return done(null, false);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return done(null, false);
|
||||
}
|
||||
} else {
|
||||
return done(null, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
));
|
||||
});
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
module.exports = strategies;
|
||||
|
|
|
@ -45,7 +45,6 @@ middleware = {
|
|||
cacheOauthServer: clientAuth.cacheOauthServer,
|
||||
authenticateClient: clientAuth.authenticateClient,
|
||||
generateAccessToken: clientAuth.generateAccessToken,
|
||||
methodNotAllowed: apiErrorHandlers.methodNotAllowed,
|
||||
errorHandler: apiErrorHandlers.errorHandler
|
||||
}
|
||||
};
|
||||
|
@ -56,7 +55,8 @@ setupMiddleware = function setupMiddleware(blogAppInstance, adminApp) {
|
|||
oauthServer = oauth2orize.createServer();
|
||||
|
||||
// silence JSHint without disabling unused check for the whole file
|
||||
authStrategies = authStrategies;
|
||||
passport.use(authStrategies.clientPasswordStrategy);
|
||||
passport.use(authStrategies.bearerStrategy);
|
||||
|
||||
// Cache express server instance
|
||||
blogApp = blogAppInstance;
|
||||
|
|
|
@ -1,57 +1,145 @@
|
|||
/*globals describe, it, beforeEach, afterEach */
|
||||
/*jshint expr:true*/
|
||||
var sinon = require('sinon'),
|
||||
should = require('should'),
|
||||
passport = require('passport'),
|
||||
authenticate = require('../../../server/middleware/authenticate');
|
||||
var sinon = require('sinon'),
|
||||
should = require('should'),
|
||||
passport = require('passport'),
|
||||
authenticate = require('../../../server/middleware/authenticate'),
|
||||
BearerStrategy = require('passport-http-bearer').Strategy,
|
||||
user = {id: 1},
|
||||
info = {scope: '*'},
|
||||
token = 'test_token';
|
||||
|
||||
should.equal(true, true);
|
||||
|
||||
function registerSuccessfulBearerStrategy() {
|
||||
// register fake BearerStrategy which always authenticates
|
||||
passport.use(new BearerStrategy(
|
||||
function strategy(accessToken, done) {
|
||||
accessToken.should.eql(token);
|
||||
return done(null, user, info);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
function registerUnsuccessfulBearerStrategy() {
|
||||
// register fake BearerStrategy which always authenticates
|
||||
passport.use(new BearerStrategy(
|
||||
function strategy(accessToken, done) {
|
||||
accessToken.should.eql(token);
|
||||
return done(null, false);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
function registerSuccessfulBearerStrategy() {
|
||||
// register fake BearerStrategy which always authenticates
|
||||
passport.use(new BearerStrategy(
|
||||
function strategy(accessToken, done) {
|
||||
accessToken.should.eql(token);
|
||||
return done(null, user, info);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
describe('authenticate', function () {
|
||||
var res, req, next, sandbox;
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
res = sinon.spy();
|
||||
req = sinon.spy();
|
||||
next = sinon.spy();
|
||||
req = {};
|
||||
res = {};
|
||||
next = sandbox.spy();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('should skip authentication if not hitting /ghost', function () {
|
||||
req.path = '/tag/foo';
|
||||
it('should skip authentication if not hitting /ghost', function (done) {
|
||||
req.path = '/tag/foo/';
|
||||
req.method = 'GET';
|
||||
|
||||
registerSuccessfulBearerStrategy();
|
||||
authenticate(req, res, next);
|
||||
|
||||
next.called.should.be.true;
|
||||
next.calledWith().should.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
it('should authenticate if hitting /ghost/ auth endpoint', function (done) {
|
||||
it('should skip authentication if hitting /ghost/api/v0.1/authenticaton/', function (done) {
|
||||
req.path = '/ghost/api/v0.1/authentication/';
|
||||
req.method = 'GET';
|
||||
|
||||
registerSuccessfulBearerStrategy();
|
||||
authenticate(req, res, next);
|
||||
|
||||
next.called.should.be.true;
|
||||
next.calledWith().should.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
it('should skip authentication if hitting GET /ghost/api/v0.1/authenticaton/setup/', function (done) {
|
||||
req.path = '/ghost/api/v0.1/authentication/setup/';
|
||||
req.method = 'GET';
|
||||
|
||||
registerSuccessfulBearerStrategy();
|
||||
authenticate(req, res, next);
|
||||
|
||||
next.called.should.be.true;
|
||||
next.calledWith().should.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
it('should authentication if hitting PUT /ghost/api/v0.1/authenticaton/setup/', function (done) {
|
||||
req.path = '/ghost/api/v0.1/authentication/setup/';
|
||||
req.method = 'PUT';
|
||||
req.headers = {};
|
||||
req.headers.authorization = 'Bearer ' + token;
|
||||
|
||||
sandbox.stub(passport, 'authenticate', function (method, options, cb) {
|
||||
var user = {slug: 'user'},
|
||||
info = {info: 'some'};
|
||||
registerSuccessfulBearerStrategy();
|
||||
authenticate(req, res, next);
|
||||
|
||||
method.should.equal('bearer');
|
||||
options.session.should.be.false;
|
||||
options.failWithError.should.be.true;
|
||||
next.called.should.be.true;
|
||||
next.calledWith(null, user, info).should.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
return function (req, res, next) {
|
||||
cb(null, user, info);
|
||||
next.called.should.be.true;
|
||||
next.calledWith(null, user, info).should.be.true;
|
||||
req.authInfo.should.equal(info);
|
||||
req.user.should.equal(user);
|
||||
done();
|
||||
it('should authenticate if hitting /ghost/api/ endpoint', function (done) {
|
||||
req.path = '/ghost/api/v0.1/test/';
|
||||
req.method = 'PUT';
|
||||
req.headers = {};
|
||||
req.headers.authorization = 'Bearer ' + token;
|
||||
|
||||
registerSuccessfulBearerStrategy();
|
||||
authenticate(req, res, next);
|
||||
|
||||
next.called.should.be.true;
|
||||
next.calledWith(null, user, info).should.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
it('shouldn\'t authenticate if hitting /ghost/ auth endpoint with invalid credentials', function (done) {
|
||||
res.status = {};
|
||||
req.path = '/ghost/api/v0.1/test/';
|
||||
req.method = 'PUT';
|
||||
req.headers = {};
|
||||
req.headers.authorization = 'Bearer ' + token;
|
||||
|
||||
registerUnsuccessfulBearerStrategy();
|
||||
|
||||
// stub res.status for error handling
|
||||
sandbox.stub(res, 'status', function (statusCode) {
|
||||
statusCode.should.eql(401);
|
||||
return {
|
||||
json: function (err) {
|
||||
err.errors[0].errorType.should.eql('NoPermissionError');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
authenticate(req, res, next);
|
||||
next.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue