Skip to content

Commit

Permalink
scope comparison bug. Closes #1875
Browse files Browse the repository at this point in the history
  • Loading branch information
Eran Hammer committed Aug 21, 2014
1 parent 2ba9778 commit dcf6a1d
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 9 deletions.
7 changes: 4 additions & 3 deletions lib/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,10 @@ internals.Auth.prototype._authenticate = function (request, next) {
// Check scope

if (config.scope) {
if (!credentials.scope || // Credentials missing scope
(typeof config.scope === 'string' && credentials.scope.indexOf(config.scope) === -1) || // String scope isn't in credentials
(Array.isArray(config.scope) && !Hoek.intersect(config.scope, credentials.scope).length)) { // Array scope doesn't intersect credentials
if (!credentials.scope ||
(typeof config.scope === 'string' ?
(typeof credentials.scope === 'string' ? config.scope !== credentials.scope : credentials.scope.indexOf(config.scope) === -1) :
(typeof credentials.scope === 'string' ? config.scope.indexOf(credentials.scope) === -1 : !Hoek.intersect(config.scope, credentials.scope).length))) {

request.log(['hapi', 'auth', 'scope', 'error'], { got: credentials.scope, need: config.scope });
return next(Boom.forbidden('Insufficient scope - ' + config.scope + ' expected'));
Expand Down
81 changes: 75 additions & 6 deletions test/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,18 +362,18 @@ describe('Auth', function () {
});
});

it('matches scope', function (done) {
it('matches scope (array to single)', function (done) {

var server = new Hapi.Server();
server.auth.scheme('custom', internals.implementation);
server.auth.strategy('default', 'custom', true, { users: { steve: { scope: ['a'] } } });
server.auth.strategy('default', 'custom', true, { users: { steve: { scope: ['one'] } } });
server.route({
method: 'GET',
path: '/',
config: {
handler: function (request, reply) { reply(request.auth.credentials.user); },
auth: {
scope: 'a'
scope: 'one'
}
}
});
Expand All @@ -385,18 +385,64 @@ describe('Auth', function () {
});
});

it('matches array scope', function (done) {
it('matches scope (array to array)', function (done) {

var server = new Hapi.Server();
server.auth.scheme('custom', internals.implementation);
server.auth.strategy('default', 'custom', true, { users: { steve: { scope: ['a', 'b'] } } });
server.auth.strategy('default', 'custom', true, { users: { steve: { scope: ['one', 'two'] } } });
server.route({
method: 'GET',
path: '/',
config: {
handler: function (request, reply) { reply(request.auth.credentials.user); },
auth: {
scope: ['one', 'three']
}
}
});

server.inject({ url: '/', headers: { authorization: 'Custom steve' } }, function (res) {

expect(res.statusCode).to.equal(200);
done();
});
});

it('matches scope (single to array)', function (done) {

var server = new Hapi.Server();
server.auth.scheme('custom', internals.implementation);
server.auth.strategy('default', 'custom', true, { users: { steve: { scope: 'one' } } });
server.route({
method: 'GET',
path: '/',
config: {
handler: function (request, reply) { reply(request.auth.credentials.user); },
auth: {
scope: ['one', 'three']
}
}
});

server.inject({ url: '/', headers: { authorization: 'Custom steve' } }, function (res) {

expect(res.statusCode).to.equal(200);
done();
});
});

it('matches scope (single to single)', function (done) {

var server = new Hapi.Server();
server.auth.scheme('custom', internals.implementation);
server.auth.strategy('default', 'custom', true, { users: { steve: { scope: 'one' } } });
server.route({
method: 'GET',
path: '/',
config: {
handler: function (request, reply) { reply(request.auth.credentials.user); },
auth: {
scope: ['a', 'c']
scope: 'one'
}
}
});
Expand All @@ -408,6 +454,29 @@ describe('Auth', function () {
});
});

it('does not match scope (single to single)', function (done) {

var server = new Hapi.Server();
server.auth.scheme('custom', internals.implementation);
server.auth.strategy('default', 'custom', true, { users: { steve: { scope: 'one' } } });
server.route({
method: 'GET',
path: '/',
config: {
handler: function (request, reply) { reply(request.auth.credentials.user); },
auth: {
scope: 'onex'
}
}
});

server.inject({ url: '/', headers: { authorization: 'Custom steve' } }, function (res) {

expect(res.statusCode).to.equal(403);
done();
});
});

it('errors on missing scope', function (done) {

var server = new Hapi.Server();
Expand Down

0 comments on commit dcf6a1d

Please sign in to comment.