Skip to content

Commit

Permalink
Manage your authentication strategies on your profile edit page (/use…
Browse files Browse the repository at this point in the history
…r/edit), including adding new authenticators and setting your default authentication strategy. Closes #67
  • Loading branch information
sizzlemctwizzle committed Apr 10, 2014
1 parent 9a62cf1 commit 95b59e2
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 24 deletions.
35 changes: 24 additions & 11 deletions controllers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,27 @@ Strategy.find({}, function (err, strategies) {
});

exports.auth = function (req, res, next) {
var user = req.session.user;
var strategy = req.body.auth || req.route.params.strategy;
var username = req.body.username || req.session.username;

function auth() {
var authenticate = passport.authenticate(strategy);

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

authenticate(req, res);
}

// Allow a logged in user to add a new strategy
if (strategy && user) {
req.session.username = user.name;
return auth();
} else if (user) {
return next();
}

if (!username) { return res.redirect('/register?noname'); }
// Clean the username of leading and trailing whitespace,
// and other stuff that is unsafe in a url
Expand All @@ -58,15 +76,6 @@ exports.auth = function (req, res, next) {
req.session.username = username;
}

function auth() {
var authenticate = passport.authenticate(strategy);

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

authenticate(req, res);
}

User.findOne({ name : { $regex : new RegExp('^' + username + '$', 'i') } },
function (err, user) {
var strategies = null;
Expand Down Expand Up @@ -100,6 +109,7 @@ exports.callback = function (req, res, next) {
var username = req.session.username;
var newstrategy = req.session.newstrategy;
var strategyInstance = null;
var doneUrl = req.session.user ? '/user/edit' : '/';

// The callback was called improperly
if (!strategy || !username) { return next(); }
Expand All @@ -125,7 +135,10 @@ exports.callback = function (req, res, next) {
var authenticate = passport.authenticate(strategy,
function (err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/register?authfail'); }
if (!user) {
return res.redirect(doneUrl + (doneUrl === '/' ? 'register' : '')
+ '?authfail');
}

req.logIn(user, function(err) {
if (err) { return next(err); }
Expand All @@ -138,7 +151,7 @@ exports.callback = function (req, res, next) {
} else {
// Delete the username that was temporarily stored
delete req.session.username;
return res.redirect('/');
return res.redirect(doneUrl);
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ exports.register = function (req, res) {
// Get the strategies we have OAuth keys for
strats.forEach(function (strat) {
options.strategies.push({ 'strat' : strat.name,
'display' : strat.display });
'display' : strat.display });
});

// Get OpenId strategies
Expand Down
67 changes: 56 additions & 11 deletions controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ var formidable = require('formidable');
var scriptStorage = require('./scriptStorage');
var User = require('../models/user').User;
var Script = require('../models/script').Script;
var Strategy = require('../models/strategy.js').Strategy;
var RepoManager = require('../libs/repoManager');
var scriptsList = require('../libs/modelsList');
var Flag = require('../models/flag').Flag;
var flagLib = require('../libs/flag');
var removeLib = require('../libs/remove');
var strategies = require('./strategies.json');
var async = require('async');
var renderMd = require('../libs/markdown').renderMd;
var nil = require('../libs/helpers').nil;
Expand Down Expand Up @@ -69,22 +71,65 @@ exports.view = function (req, res, next) {

exports.edit = function (req, res) {
var user = req.session.user;
var userStrats = req.session.user.strategies.slice(0);
var options = {
title: 'Edit Yourself',
name: user.name,
about: user.about,
username: user ? user.name : null
};

if (!user) { return res.redirect('/login'); }

req.route.params.push('author');

scriptsList.listScripts({ _authorId: user._id, isLib: null },
{ size: -1 }, '/user/edit',
function (scriptsList) {
scriptsList.edit = true;
res.render('userEdit', {
title: 'Edit Yourself',
name: user.name,
about: user.about,
scriptsList: scriptsList,
username: user ? user.name : null
});
Strategy.find({}, function (err, strats) {
var defaultStrategy = userStrats[userStrats.length - 1];
var strategy = null;
var name = null;
options.openStrategies = [];
options.usedStrategies = [];

// Get the strategies we have OAuth keys for
strats.forEach(function (strat) {
if (strat.name === defaultStrategy) { return; }

if (userStrats.indexOf(strat.name) > -1) {
options.usedStrategies.push({ 'strat' : strat.name,
'display' : strat.display });
} else {
options.openStrategies.push({ 'strat' : strat.name,
'display' : strat.display });
}
});

// Get OpenId strategies
if (process.env.NODE_ENV === 'production') {
for (name in strategies) {
strategy = strategies[name];

if (!strategy.oauth && name !== defaultStrategy) {
if (userStrats.indexOf(name) > -1) {
options.usedStrategies.push({ 'strat' : name,
'display' : strategy.name });
} else {
options.openStrategies.push({ 'strat' : name,
'display' : strategy.name });
}
}
}
}

options.defaultStrategy = strategies[defaultStrategy].name;
options.haveOtherStrategies = options.usedStrategies.length > 0;

scriptsList.listScripts({ _authorId: user._id, isLib: null },
{ size: -1 }, '/user/edit',
function (scriptsList) {
scriptsList.edit = true;
options.scriptsList = scriptsList;
res.render('userEdit', options);
});
});
};

Expand Down
9 changes: 9 additions & 0 deletions libs/passportVerify.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ exports.verify = function (id, strategy, username, loggedIn, done) {

findDeadorAlive(User, { 'auths' : digest }, true,
function (alive, user, removed) {
var pos = user ? user.auths.indexOf(digest) : -1;
if (removed) { done(null, false, 'user was removed'); }

if (!user) {
Expand Down Expand Up @@ -51,6 +52,14 @@ exports.verify = function (id, strategy, username, loggedIn, done) {
});
}
});
} else if (pos > -1 && pos < user.auths.length - 1) {
user.strategies.splice(pos, 1);
user.auths.splice(pos, 1);
user.strategies.push(strategy);
user.auths.push(digest);
user.save(function (err, user) {
return done(err, user);
});
} else {
// The user was authenticated
return done(null, user);
Expand Down
22 changes: 21 additions & 1 deletion views/userEdit.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,27 @@ <h1>About You</h1>
<strong><a href="/user/add/lib">Add Library</a></strong>
</form>
</div>
<br />
<br /><br />
<div class="content-box">
<h2>Authentication</h2>
<p><strong>{{defaultStrategy}}</strong> is your current form of authentication.</p>
{{#haveOtherStrategies}}
<p>Other verified forms of authentication:</p>
{{#usedStrategies}}
<strong>{{display}}</strong> - <a href="/auth/{{strat}}">Make default</a><br />
{{/usedStrategies}}
{{/haveOtherStrategies}}
<form id="register" method="post" action="/auth/">
<p>Add another form of authentication:</p>
<select name="auth">
{{#openStrategies}}
<option value="{{strat}}">{{display}}</option>
{{/openStrategies}}
</select>
<input type="submit" value="Authenticate" />
</form>
</div>
<br /><br />
<div class="centered-content">
{{> scriptsList.html}}
</div>
Expand Down

0 comments on commit 95b59e2

Please sign in to comment.