Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add support for scope factories
  • Loading branch information
Luka Skukan committed Nov 25, 2016
commit 150658d9da4ae846c67e13d6eb6749afa54953b1
5 changes: 5 additions & 0 deletions lib/controllers/get-token.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ module.exports = function (req, res) {
case 'client_credentials':
var authenticator = new stormpath.OAuthAuthenticator(application);

if (config.web.scopeFactory) {
authenticator.setScopeFactory(config.web.scopeFactory);
authenticator.setScopeFactorySigningKey(config.client.apiKey.secret);
}

if (grantType === 'client_credentials') {
resolveClientCredentialsAuthFields(req);
}
Expand Down
76 changes: 73 additions & 3 deletions test/controllers/test-get-token.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
var assert = require('assert');
var request = require('supertest');
var uuid = require('uuid');
var nJwt = require('njwt');

var DefaultExpressApplicationFixture = require('../fixtures/default-express-application');
var helpers = require('../helpers');
var Oauth2DisabledFixture = require('../fixtures/oauth2-disabled');
var ScopeFactoryFixture = require('../fixtures/scope-factory');

describe('getToken (OAuth2 token exchange endpoint)', function () {
var username = uuid.v4() + '@stormpath.com';
Expand All @@ -22,21 +24,36 @@ describe('getToken (OAuth2 token exchange endpoint)', function () {
var stormpathApplication;
var enabledFixture;
var disabledFixture;
var scopeFactoryFixture;
var refreshToken;
var scopeFactory;
var requestScope;
var createScope;

before(function (done) {

/**
* Epic hack to observe two ready events and know when they are both done
* Epic hack to observe all ready events and know when they are both done
*/
var readyCount = 0;
function ready() {
readyCount++;
if (readyCount === 2) {
setTimeout(done, 1000);
if (readyCount === 3) {
setTimeout(done, 1500); // HACK see what's up with this!
}
}

requestScope = 'admin';

createScope = function (scope) {
return scope + '-' + username;
};

scopeFactory = function (authenticationResult, requestedScope, callback) {
assert.equal(requestScope, requestedScope);
callback(null, createScope(requestedScope));
};

helpers.createApplication(helpers.createClient(), function (err, app) {
if (err) {
return done(err);
Expand All @@ -46,6 +63,7 @@ describe('getToken (OAuth2 token exchange endpoint)', function () {

enabledFixture = new DefaultExpressApplicationFixture(stormpathApplication);
disabledFixture = new Oauth2DisabledFixture(stormpathApplication);
scopeFactoryFixture = new ScopeFactoryFixture(stormpathApplication, scopeFactory);

app.createAccount(accountData, function (err, account) {
if (err) {
Expand All @@ -62,6 +80,7 @@ describe('getToken (OAuth2 token exchange endpoint)', function () {

enabledFixture.expressApp.on('stormpath.ready', ready);
disabledFixture.expressApp.on('stormpath.ready', ready);
scopeFactoryFixture.expressApp.on('stormpath.ready', ready);
});
});
});
Expand Down Expand Up @@ -228,4 +247,55 @@ describe('getToken (OAuth2 token exchange endpoint)', function () {
});

});

describe('scope factories', function () {
var secret;

before(function () {
var config = scopeFactoryFixture.expressApp.get('stormpathConfig');
secret = config.client.apiKey.secret;
});

it('should utilize the scope factory if defined for password grant type', function (done) {
request(scopeFactoryFixture.expressApp)
.post('/oauth/token')
.send('grant_type=password')
.send('username=' + accountData.email)
.send('password=' + accountData.password)
.send('scope=' + requestScope)
.expect(200)
.end(function (err, res) {
assert(res.body && res.body.access_token);
nJwt.verify(res.body.access_token, secret, function (err, token) {
if (err) {
return done(err);
}

assert.equal(token.body.scope, createScope(requestScope));
done();
});
});
});

it('should utilize the scope factory if defined for client_credentials grant type', function (done) {
request(scopeFactoryFixture.expressApp)
.post('/oauth/token')
.send('client_id=' + stormpathAccountApiKey.id)
.send('client_secret=' + stormpathAccountApiKey.secret)
.send('grant_type=client_credentials')
.send('scope=' + requestScope)
.expect(200)
.end(function (err, res) {
assert(res.body && res.body.access_token);
nJwt.verify(res.body.access_token, secret, function (err, token) {
if (err) {
return done(err);
}

assert.equal(token.body.scope, createScope(requestScope));
done();
});
});
});
});
});
24 changes: 24 additions & 0 deletions test/fixtures/scope-factory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

var helpers = require('../helpers');

/**
* This fixture creates an Express application which has express-stormpath
* integrated and uses a scope factory.
*
* It takes the Stormpath application reference and the requisite scope factory
* as its fixture constructor arguments. It is assumed that API Keys for
* Stormpath are already in the environment.
*
* @param {object} stormpathApplication
*/
function DefaultExpressApplicationFixtureFixture(stormpathApplication, scopeFactory) {
this.expressApp = helpers.createStormpathExpressApp({
application: stormpathApplication,
web: {
scopeFactory: scopeFactory
}
});
}

module.exports = DefaultExpressApplicationFixtureFixture;