Skip to content
This repository has been archived by the owner on Jan 5, 2019. It is now read-only.

Commit

Permalink
Bug 1392307 - use auth0 profile only to authenticte the user
Browse files Browse the repository at this point in the history
Translate the auth0 profile to the existing user identity (email/..,
mozilla-ldap/.., or a new github/<nick>).  Continue to use the existing
authorizers to add scopes based on those identities.

We can improve on this when richer profiles are available from auth0.
  • Loading branch information
djmitche committed Aug 24, 2017
1 parent 44981d5 commit 743ce96
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 21 deletions.
48 changes: 43 additions & 5 deletions src/handlers/mozilla-auth0.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,54 @@ class Handler {
let profile = await new Promise((resolve, reject) =>
a0.getUser(req.user.sub, (err, prof) => err ? reject(err) : resolve(prof)));

if (!profile.email_verified) {
debug('profile.email is not verified; ignoring profile');
if ('active' in profile && !profile.active) {
debug('user is not active; rejecting');
return;
}

let user = new User();
user.identity = 'mozilla-auth0/' + profile.email;
let user = userFromProfile(profile);
user.expires = new Date(req.user.exp * 1000);
return user;
}

userFromProfile(profile) {
let user = new User();

// TODO: add scopes based on profile; waiting on profile rollout and documentation
// we recognize a few different kinds of 'identities' that auth0 can send
// our way. Each of these translates into a different identityProviderId,
// which authorizers will later use to figure out what scopes this user
// has. We do not ever expect to have more than one identity in this array,
// in a practical sense.
for (let {provider, connection} of profile.identities) {
// The 'Mozilla-LDAP' connection corresponds to an LDAP login. For this
// login, emails are a unique identifier
if (provider === 'ad' && connection === 'Mozilla-LDAP') {
if (profile.email_verified) {
user.identity = 'mozilla-ldap/' + profile.email;
break;
}
// The 'email' connection corresponds to a passwordless login.
} else if (provider === 'email' && connection === 'email') {
if (profile.email_verified) {
user.identity = 'email/' + profile.email;
break;
}
// Login with google really only gives us an email, too.
} else if (provider === 'google-oauth2' && connection === 'google-oauth2') {
if (profile.email_verified) {
user.identity = 'email/' + profile.email;
break;
}
// Github logins take the nickname from the profile; we don't get a reliable
// email
} else if (provider === 'github' && connection === 'github') {
user.identity = 'github/' + profile.nickname;
}
}
if (!user.identity) {
debug('No recognized identity providers');
return;
}

return user;
}
Expand Down
17 changes: 3 additions & 14 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,6 @@ let load = loader({
setup: ({cfg}) => {
let handlers = {};

// carry out the authorization process, either with a done callback
// or returning a promise
let authorize = (user, done) => {
let promise = authorizer.authorize(user);
if (done) {
promise.then(() => done(null, user), (err) => done(err, null));
} else {
return promise;
}
};

Object.keys(cfg.handlers).forEach((name) => {
let Handler = require('./handlers/' + name).default;
handlers[name] = new Handler({name, cfg});
Expand Down Expand Up @@ -110,8 +99,8 @@ let load = loader({
},

router: {
requires: ['cfg', 'validator', 'monitor', 'handlers'],
setup: ({cfg, validator, monitor, handlers}) => {
requires: ['cfg', 'validator', 'monitor', 'handlers', 'authorizer'],
setup: ({cfg, validator, monitor, handlers, authorizer}) => {
return v1.setup({
context: {},
validator,
Expand All @@ -121,7 +110,7 @@ let load = loader({
referencePrefix: 'login/v1/api.json',
aws: cfg.aws,
monitor: monitor.prefix('api'),
context: {cfg, handlers},
context: {cfg, handlers, authorizer},
});
},
},
Expand Down
7 changes: 5 additions & 2 deletions src/v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var api = new API({
'systems and TaskCluster credentials.',
].join('\n'),
schemaPrefix: 'http://schemas.taskcluster.net/login/v1/',
context: ['cfg', 'handlers'],
context: ['cfg', 'handlers', 'authorizer'],
});

// Export api
Expand Down Expand Up @@ -61,10 +61,13 @@ api.declare({
// don't report much to the user, to avoid revealing sensitive information, although
// it is likely in the service logs.
return res.reportError('InputError',
'Could not validate access token',
'Could not generate credentials for this access token',
{});
}

// add scopes for this user based on matching authorizers
this.authorizer.authorize(user);

// create and return temporary credentials, limiting expires to a max of 15 minutes
let {credentials: issuer, startOffset} = this.cfg.app.temporaryCredentials;
let {credentials, expires} = user.createCredentials({credentials: issuer, startOffset, expiry: '15 min'});
Expand Down
59 changes: 59 additions & 0 deletions test/handlers_mozilla_auth0_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require('mocha');
import assume from 'assume';
import helper from './helper';
import Handler from '../lib/handlers/mozilla-auth0';

suite('handlers/mozilla-auth0', function() {
suite('userFromProfile', function() {
let handler = new Handler({
name: 'mozilla-auth0',
cfg: {
handlers: {
'mozilla-auth0': {
domain:'login-test.taskcluster.net',
apiAudience: 'login-test.taskcluster.net',
clientId: 'abcd',
clientSecret: 'defg',
},
},
},
});

test('user for ldap profile', function() {
let user = handler.userFromProfile({
email: 'foo@mozilla.com',
email_verified: true,
identities: [{provider: 'ad', connection: 'Mozilla-LDAP'}],
});
assume(user.identity).to.equal('mozilla-ldap/foo@mozilla.com');
});

test('user for email profile', function() {
let user = handler.userFromProfile({
email: 'foo@bar.com',
email_verified: true,
identities: [{provider: 'email', connection: 'email'}],
});
assume(user.identity).to.equal('email/foo@bar.com');
});

test('user for google profile', function() {
let user = handler.userFromProfile({
email: 'foo@bar.com',
email_verified: true,
identities: [{
provider: 'google-oauth2',
connection: 'google-oauth2'}],
});
assume(user.identity).to.equal('email/foo@bar.com');
});

test('user for github profile', function() {
let user = handler.userFromProfile({
nickname: 'octocat',
identities: [{provider: 'github', connection: 'github'}],
});
assume(user.identity).to.equal('github/octocat');
});
});
});

0 comments on commit 743ce96

Please sign in to comment.