Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 17 additions & 2 deletions controllers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var User = require('../models/user').User;
var verifyPassport = require('../libs/passportVerify').verify;
var cleanFilename = require('../libs/helpers').cleanFilename;
var addSession = require('../libs/modifySessions').add;
var jwt = require('jwt-simple');

// Unused but removing it breaks passport
passport.serializeUser(function (aUser, aDone) {
Expand Down Expand Up @@ -43,16 +44,22 @@ exports.auth = function (aReq, aRes, aNext) {
var authedUser = aReq.session.user;
var strategy = aReq.body.auth || aReq.params.strategy;
var username = aReq.body.username || aReq.session.username;
var authOpts = { failureRedirect: '/register?stratfail' };

function auth() {
var authenticate = passport.authenticate(strategy, { failureRedirect: '/register?stratfail' });
var authenticate = null;

if (strategy === 'google') {
authOpts.scope = ['https://www.googleapis.com/auth/userinfo.profile'];
}
authenticate = passport.authenticate(strategy, authOpts);

// Just in case some dumbass tries a bad /auth/* url
if (!strategyInstances[strategy]) {
return aNext();
}

authenticate(aReq, aRes);
authenticate(aReq, aRes, aNext);
}

// Allow a logged in user to add a new strategy
Expand Down Expand Up @@ -128,6 +135,14 @@ exports.callback = function (aReq, aRes, aNext) {
strategyInstance._verify = function (aId, aDone) {
verifyPassport(aId, strategy, username, aReq.session.user, aDone);
};
} else if (strategy === 'google') { // OpenID to OAuth2 migration
strategyInstance._verify =
function(aAccessToken, aRefreshToken, aParams, aProfile, aDone) {
var openIdId = jwt.decode(aParams.id_token, null, true).openid_id;
var oAuthId = aProfile.id;

verifyPassport([openIdId, oAuthId], strategy, username, aReq.session.user, aDone);
};
} else {
strategyInstance._verify =
function (aToken, aRefreshOrSecretToken, aProfile, aDone) {
Expand Down
2 changes: 1 addition & 1 deletion controllers/strategies.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
},
"google": {
"name": "Google",
"oauth": false
"oauth": true
},
"imgur": {
"name": "Imgur",
Expand Down
16 changes: 14 additions & 2 deletions libs/passportLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ exports.strategyInstances = nil();
// This will load a single passport
// Notice it is general so it can load any passport strategy
exports.loadPassport = function (aStrategy) {
var requireStr = 'passport-' + aStrategy.name;
var PassportStrategy = require(requireStr).Strategy;
var requireStr = 'passport-' + aStrategy.name
+ (aStrategy.name === 'google' ? '-oauth' : '');
var PassportStrategy = require(requireStr)[
aStrategy.name === 'google' ? 'OAuth2Strategy' : 'Strategy'];
var instance = null;
var authParams = null;

if (aStrategy.openid) {
instance = new PassportStrategy(
Expand All @@ -50,6 +53,15 @@ exports.loadPassport = function (aStrategy) {
);
}

if (aStrategy.name === 'google') {
authParams = instance.authorizationParams;
instance.authorizationParams = function() {
var val = authParams.apply(this, arguments);
val['openid.realm'] = AUTH_CALLBACK_BASE_URL + '/';
return val;
};
}

exports.strategyInstances[aStrategy.name] = instance;
passport.use(instance);
};
35 changes: 32 additions & 3 deletions libs/passportVerify.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,18 @@ var userRoles = require('../models/userRoles.json');
exports.verify = function (aId, aStrategy, aUsername, aLoggedIn, aDone) {
var shasum = crypto.createHash('sha256');
var digest = null;
var query = {};
var ids = [];

// We only keep plaintext ids for GH since that's all we need
if (aStrategy === 'github') {
if (aId instanceof Array) {
ids = aId.map(function (aId) {
var shasum = crypto.createHash('sha256');
shasum.update(String(aId));
return shasum.digest('hex');
});
query.auths = { '$in': ids };
} else if (aStrategy === 'github') {
// We only keep plaintext ids for GH since that's all we need
digest = aId;
} else {
// Having these ids would allow us to do things with the user's
Expand All @@ -27,11 +36,25 @@ exports.verify = function (aId, aStrategy, aUsername, aLoggedIn, aDone) {
digest = shasum.digest('hex');
}

findDeadorAlive(User, { 'auths': digest }, true,
if (!query.auths) {
query.auths = digest;
}

findDeadorAlive(User, query, true,
function (aAlive, aUser, aRemoved) {
var pos = aUser ? aUser.auths.indexOf(digest) : -1;
var opendIdPos = -1;
if (aRemoved) { aDone(null, false, 'user was removed'); }

// Set up for OpenId to OAuth Migration
if (!digest && ids.length > 0) {
digest = ids[1];
if (aUser) {
pos = aUser.auths.indexOf(digest);
opendIdPos = aUser.auths.indexOf(ids[0]);
}
}

if (!aUser) {
User.findOne({ 'name': aUsername }, function (aErr, aUser) {
if (aUser && aLoggedIn) {
Expand Down Expand Up @@ -69,6 +92,12 @@ exports.verify = function (aId, aStrategy, aUsername, aLoggedIn, aDone) {
aUser.save(function (aErr, aUser) {
return aDone(aErr, aUser);
});
} else if (opendIdPos > 0) {
// Migrate from OpenID to OAuth
aUser.auths[opendIdPos] = digest;
aUser.save(function (aErr, aUser) {
return aDone(aErr, aUser);
});
} else {
// The user was authenticated
return aDone(null, aUser);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"github": "0.2.3",
"highlight.js": "8.4.0",
"jquery": "2.1.3",
"jwt-simple": "0.2.0",
"less-middleware": "1.0.4",
"marked": "0.3.3",
"method-override": "2.3.1",
Expand All @@ -36,7 +37,7 @@
"passport-flickr": "0.2.0",
"passport-foursquare": "1.0.0",
"passport-github": "0.1.5",
"passport-google": "0.3.0",
"passport-google-oauth": "0.1.5",
"passport-imgur": "0.0.2",
"passport-instagram": "0.1.2",
"passport-linkedin": "0.1.3",
Expand Down