diff --git a/lib/auth.js b/lib/auth.js index 7ff3157d8..4ef98eac3 100755 --- a/lib/auth.js +++ b/lib/auth.js @@ -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')); diff --git a/test/auth.js b/test/auth.js index 32881292b..0322ea914 100755 --- a/test/auth.js +++ b/test/auth.js @@ -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' } } }); @@ -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' } } }); @@ -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();