Skip to content

Commit

Permalink
Merge pull request #1103 from nlf/master
Browse files Browse the repository at this point in the history
allow arrays of scopes on routes
  • Loading branch information
Eran Hammer committed Oct 28, 2013
2 parents 433442b + b2beafa commit 1c30cba
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 8 deletions.
5 changes: 3 additions & 2 deletions docs/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,9 @@ The following options are available when adding a route:
`hash` attribute in Hawk).
- `tos` - minimum terms-of-service version required (uses the [semver](https://npmjs.org/package/semver) module). If defined, the
authentication credentials object must include a `tos` key which satisfies this requirement. Defaults to `false` which means no validation.
- `scope` - required application scope. A scope string which must be included in the authentication credentials object in `scope` which is
a string array. Defaults to no scope required.
- `scope` - required application scope. A string which must be included in the authentication credentials object in `scope` which is
a string array. Can also be specified as an array of strings, in which case at least one of the strings must exist in the authentication
credentials object `scope` property. Defaults to no scope required.
- `entity` - the required authenticated entity type. If set, must match the `entity` value of the authentication credentials. Available
values:
- `any` - the authentication can be on behalf of a user or application. This is the default value.
Expand Down
19 changes: 15 additions & 4 deletions lib/auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,22 @@ internals.Auth.prototype.authenticate = function (request, next) {

// Check scope

if (config.scope &&
(!credentials || !credentials.scope || credentials.scope.indexOf(config.scope) === -1)) {
if (config.scope) {

request.log(['hapi', 'auth', 'scope', 'error'], { got: credentials && credentials.scope, need: config.scope });
return next(Boom.forbidden('Insufficient scope - ' + config.scope + ' expected'));
var failed = (!credentials || !credentials.scope);

if (!failed) {
if (Array.isArray(config.scope)) {
failed = Utils.intersect(config.scope, credentials.scope).length === 0;
} else {
failed = credentials.scope.indexOf(config.scope) === -1;
}
}

if (failed) {
request.log(['hapi', 'auth', 'scope', 'error'], { got: credentials && credentials.scope, need: config.scope });
return next(Boom.forbidden('Insufficient scope - ' + config.scope + ' expected'));
}
}

// Check TOS
Expand Down
2 changes: 1 addition & 1 deletion lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ internals.routeConfigSchema = {
auth: [
T.Object({
mode: T.String().valid(['required', 'optional', 'try']),
scope: T.String(),
scope: [T.String(), T.Array()],
tos: T.String().allow(false),
entity: T.String(),
strategy: T.String(),
Expand Down
15 changes: 14 additions & 1 deletion test/integration/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ describe('Auth', function () {
{ method: 'POST', path: '/basic', handler: basicHandler, config: { auth: true } },
{ method: 'POST', path: '/basicOptional', handler: basicHandler, config: { auth: { mode: 'optional' } } },
{ method: 'POST', path: '/basicScope', handler: basicHandler, config: { auth: { scope: 'x' } } },
{ method: 'POST', path: '/basicArrayScope', handler: basicHandler, config: { auth: { scope: ['x', 'y'] } } },
{ method: 'POST', path: '/basicTos', handler: basicHandler, config: { auth: { tos: '1.1.x' } } },
{ method: 'POST', path: '/double', handler: doubleHandler }
]);
Expand Down Expand Up @@ -252,6 +253,18 @@ describe('Auth', function () {
});
});

it('returns an error on insufficient scope specified as an array', function (done) {

var request = { method: 'POST', url: '/basicArrayScope', headers: { authorization: basicHeader('john', '12345') } };

server.inject(request, function (res) {

expect(res.result).to.exist;
expect(res.result.code).to.equal(403);
done();
});
});

it('should not ask for credentials if no server auth configured', function (done) {

var config = {};
Expand Down Expand Up @@ -1542,4 +1555,4 @@ describe('Auth', function () {
});
});
});
});
});

0 comments on commit 1c30cba

Please sign in to comment.