Skip to content

Commit

Permalink
Merge branch 'master' into add-support-for-okta
Browse files Browse the repository at this point in the history
  • Loading branch information
ldesplat authored Mar 24, 2017
2 parents 4522d41 + 8ba1d6b commit 39a80f6
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 59 deletions.
24 changes: 23 additions & 1 deletion Providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ The default response would look like this in the `profile` object obtained
credentials.profile = {
id: profile.oid,
displayName: profile.name,
email: profile.upn,
email: profile.upn || profile.email,
raw: profile
};
```
Expand Down Expand Up @@ -527,6 +527,28 @@ credentials.profile = {
// credentials.profile.raw will contain all of the keys sent by Slack for the `auth.test` method
```

### Spotify

[Provider Documentation](https://developer.spotify.com/web-api/)

- `scope`: Defaults to `-` allowing to read the public information only. [Spotify Scopes](https://developer.spotify.com/web-api/using-scopes/)
- `auth`: https://accounts.spotify.com/authorize
- `token`: https://accounts.spotify.com/api/token

Read more about the Spotify Web API's Authorization Flow here: [https://developer.spotify.com/web-api/authorization-guide/](https://developer.spotify.com/web-api/authorization-guide/)

The default profile response will look like this:

```javascript
credentials.profile = {
id: profile.id,
username: profile.id,
displayName: profile.display_name,
email: profile.email,
raw: profile
}
```

### Twitter

[Provider Documentation](https://dev.twitter.com/oauth)
Expand Down
4 changes: 2 additions & 2 deletions lib/oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ exports.v2 = function (settings) {
};

if (!settings.provider.profile || settings.skipProfile) {
return reply.continue({ credentials });
return reply.continue({ credentials, artifacts: payload });
}

// Obtain user profile
Expand Down Expand Up @@ -303,7 +303,7 @@ exports.v2 = function (settings) {

settings.provider.profile.call(settings, credentials, payload, get, () => {

return reply.continue({ credentials });
return reply.continue({ credentials, artifacts: payload });
});
});
};
Expand Down
2 changes: 1 addition & 1 deletion lib/providers/azuread.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ exports = module.exports = function (options) {
credentials.profile = {
id: profile.oid,
displayName: profile.name,
email: profile.upn,
email: profile.upn || profile.email,
raw: profile
};
return reply();
Expand Down
1 change: 1 addition & 0 deletions lib/providers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ exports = module.exports = {
reddit: require('./reddit'),
salesforce: require('./salesforce'),
slack: require('./slack'),
spotify: require('./spotify'),
tumblr: require('./tumblr'),
twitch: require('./twitch'),
twitter: require('./twitter'),
Expand Down
34 changes: 34 additions & 0 deletions lib/providers/spotify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

exports = module.exports = function (options) {

options = options || {};

const uri = options.uri || 'https://accounts.spotify.com';
const user = options.uri ? options.uri + '/v1/me' : 'https://api.spotify.com/v1/me';

return {
protocol: 'oauth2',
useParamsAuth: true,
auth: uri + '/authorize',
token: uri + '/api/token',
scope: ['user-read-email'],
scopeSeparator: ',',
headers: { 'User-Agent': 'hapi-bell-spotify' },
profile: function (credentials, params, get, callback) {

get(user, null, (profile) => {

credentials.profile = {
id: profile.id,
username: profile.id,
displayName: profile.display_name,
email: profile.email,
raw: profile
};

return callback();
});
}
};
};
9 changes: 6 additions & 3 deletions test/providers/auth0.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('auth0', () => {
auth: 'custom',
handler: function (request, reply) {

reply(request.auth.credentials);
reply(request.auth);
}
}
});
Expand All @@ -93,7 +93,7 @@ describe('auth0', () => {
server.inject({ url: mockRes.headers.location, headers: { cookie } }, (response) => {

Mock.clear();
expect(response.result).to.equal({
expect(response.result.credentials).to.equal({
provider: 'custom',
token: '456',
expiresIn: 3600,
Expand All @@ -110,7 +110,10 @@ describe('auth0', () => {
raw: profile
}
});

expect(response.result.artifacts).to.equal({
'access_token': '456',
'expires_in': 3600
});
mock.stop(done);
});
});
Expand Down
144 changes: 92 additions & 52 deletions test/providers/azuread.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,79 +17,119 @@ const describe = lab.describe;
const it = lab.it;
const expect = Code.expect;

describe('azuread', () => {

it('authenticates with mock Azure AD', { parallel: false }, (done) => {
// Test helpers

const mock = new Mock.V2();
mock.start((provider) => {
const testProfile = function (opts) {

const server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80 });
server.register(Bell, (err) => {
const profile = opts.profile;
const expectedResult = opts.expectedResult;
const done = opts.done;
const mock = new Mock.V2();
mock.start((provider) => {

expect(err).to.not.exist();
const server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80 });
server.register(Bell, (err) => {

const custom = Bell.providers.azuread();
Hoek.merge(custom, provider);
expect(err).to.not.exist();

const profile = {
oid: '1234567890',
name: 'Sample AD User',
upn: 'sample@microsoft.com'
};
const custom = Bell.providers.azuread();
Hoek.merge(custom, provider);

Mock.override('https://login.microsoftonline.com/common/openid/userinfo', profile);
Mock.override('https://login.microsoftonline.com/common/openid/userinfo', profile);

server.auth.strategy('custom', 'bell', {
password: 'cookie_encryption_password_secure',
isSecure: false,
clientId: 'azuread',
clientSecret: 'secret',
provider: custom
});
server.auth.strategy('custom', 'bell', {
password: 'cookie_encryption_password_secure',
isSecure: false,
clientId: 'azuread',
clientSecret: 'secret',
provider: custom
});

server.route({
method: '*',
path: '/login',
config: {
auth: 'custom',
handler: function (request, reply) {
server.route({
method: '*',
path: '/login',
config: {
auth: 'custom',
handler: function (request, reply) {

reply(request.auth.credentials);
}
reply(request.auth.credentials);
}
});
}
});

server.inject('/login', (res) => {
server.inject('/login', (res) => {

const cookie = res.headers['set-cookie'][0].split(';')[0] + ';';
mock.server.inject(res.headers.location, (mockRes) => {
const cookie = res.headers['set-cookie'][0].split(';')[0] + ';';
mock.server.inject(res.headers.location, (mockRes) => {

server.inject({ url: mockRes.headers.location, headers: { cookie } }, (response) => {
server.inject({ url: mockRes.headers.location, headers: { cookie } }, (response) => {

Mock.clear();
expect(response.result).to.equal({
provider: 'custom',
token: '456',
expiresIn: 3600,
refreshToken: undefined,
query: {},
profile: {
id: '1234567890',
displayName: 'Sample AD User',
email: 'sample@microsoft.com',
raw: profile
}
});
Mock.clear();
expect(response.result).to.equal(expectedResult);

mock.stop(done);
});
mock.stop(done);
});
});
});
});
});
};

describe('azuread', () => {

it('authenticates with mock Azure AD', { parallel: false }, (done) => {

const profile = {
oid: '1234567890',
name: 'Sample AD User',
upn: 'sample@microsoft.com'
};
testProfile({
profile,
expectedResult: {
provider: 'custom',
token: '456',
expiresIn: 3600,
refreshToken: undefined,
query: {},
profile: {
id: '1234567890',
displayName: 'Sample AD User',
email: 'sample@microsoft.com',
raw: profile
}
},
done
});
});

it('authenticates with mock Azure AD email', { parallel: false }, (done) => {

const profile = {
oid: '1234567890',
name: 'Sample AD User',
email: 'sample@microsoft.com'
};
testProfile({
profile,
expectedResult: {
provider: 'custom',
token: '456',
expiresIn: 3600,
refreshToken: undefined,
query: {},
profile: {
id: '1234567890',
displayName: 'Sample AD User',
email: 'sample@microsoft.com',
raw: profile
}
},
done
});
});

it('authenticates with mock azure AD and custom tenant', { parallel: false }, (done) => {

Expand Down
Loading

0 comments on commit 39a80f6

Please sign in to comment.