Skip to content

Commit

Permalink
A commit so massive I would need to write a novel than just a message…
Browse files Browse the repository at this point in the history
…. But it closes #1.
  • Loading branch information
sizzlemctwizzle committed Nov 14, 2013
1 parent c3b6596 commit 390b095
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 70 deletions.
2 changes: 0 additions & 2 deletions .npmignore

This file was deleted.

9 changes: 5 additions & 4 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var mongoose = require('mongoose');
var passport = require('passport');
var app = express();
var controllers = require('./controllers');
//var authentication = require('./controllers/auth');
var authentication = require('./controllers/auth');
var admin = require('./controllers/admin');
var settings = require('./models/settings.json');

Expand All @@ -26,8 +26,9 @@ app.configure(function(){
});

if (process.env.NODE_ENV === 'production') {
mongoose.connect(require('./prodDB').connectString);
mongoose.connect(process.env.CONNECT_STRING);
} else {
// Throwaway database for development
mongoose.connect('mongodb://nodejitsu_sizzlemctwizzle:b6vrl5hvkv2a3vvbaq1nor7fdl@ds045978.mongolab.com:45978/nodejitsu_sizzlemctwizzle_nodejitsudb8203815757');
}

Expand All @@ -38,7 +39,7 @@ db.once('open', function callback () {
});

app.get('/', controllers.home);
/*app.get('/auth/:strategy?', authentication.auth);
app.get('/auth/:strategy?', authentication.auth);
app.post('/auth/', function(req, res) {
req.session.username = req.body.username;
res.redirect('/auth/' + req.body.auth);
Expand All @@ -47,7 +48,7 @@ app.get('/auth/:strategy/callback/', authentication.callback);
app.get('/logout', function(req, res) {
delete req.session.user;
res.redirect('/');
});*/
});

app.get('/admin/user', admin.userAdmin);
app.get('/admin/api', admin.apiAdmin);
Expand Down
Empty file removed controllers/.npmignore
Empty file.
77 changes: 64 additions & 13 deletions controllers/admin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
var Strategy = require('../models/strategies.js').Strategy;
var Strategy = require('../models/strategy.js').Strategy;
var User = require('../models/user.js').User;
var strategies = require('./strategies.json');
var userRoles = require('../models/userRoles.json');
var loadPassport = require('../libs/passportLoader').loadPassport;
var strategyInstances = require('../libs/passportLoader').strategyInstances;
var Wait = require('../libs/wait').Wait;

function userIsAdmin(req) {
return req.session.user && req.session.user.role < 3;
Expand All @@ -21,16 +25,32 @@ function getOAuthStrategies(stored) {
exports.userAdmin = function(req, res) {
if (!userIsAdmin(req)) res.redirect('/');

res.render('index', options, res);
var options = {};
User.find({}, function(req, users) {
options.users = [];

var i = 0;
users.forEach(function(user) {
var roles = [];
userRoles.forEach(function(role, index) {
roles.push({ 'val' : index, 'display' : role,
'selected' : index === user.role });
});
roles.reverse();

options.users.push({ 'name' : user.name, 'roles' : roles });
});

res.render('userAdmin', options, res);
});
};

exports.apiAdmin = function(req, res) {
//if (!userIsAdmin(req)) res.redirect('/');
if (!userIsAdmin(req)) res.redirect('/');

Strategy.find({}, function(err, strats) {
var stored = {};
strats.forEach(function(strat) {
//strat.remove(function (err, product) {});
stored[strat.name] = { 'strat' : strat.name,
'id' : strat.id, 'key' : strat.key };
});
Expand All @@ -43,11 +63,14 @@ exports.apiAdmin = function(req, res) {
};

exports.apiAdminUpdate = function(req, res) {
if (!userIsAdmin(req)) res.redirect('/');

var postStrats = req.body;
var doneCount = 0;
function done() {
if (!(--doneCount)) res.redirect('/admin/api');
}

// Setup a function to call once everything is done
var wait = new Wait(function() {
res.redirect('/admin/api');
});

Strategy.find({}, function(err, strats) {
var stored = {};
Expand All @@ -58,7 +81,14 @@ exports.apiAdminUpdate = function(req, res) {
for (var i in postStrats) {
var postStrat = postStrats[i];
var strategy = null;
if (postStrat[0] && postStrat[1]) {

if (stored[i] && !postStrat[0] && !postStrat[1]) {
stored[i].remove(wait.add(function() {
delete strategyInstances[i];
}));
continue;
}
else if (postStrat[0] && postStrat[1]) {
if (stored[i]) {
strategy = stored[i];
strategy.id = postStrat[0]
Expand All @@ -72,15 +102,36 @@ exports.apiAdminUpdate = function(req, res) {
});
}

++doneCount;
strategy.save(function() { return done(); });
strategy.save(wait.add(function(err, strategy) {
loadPassport(strategy);
}));
}
}

++doneCount;
done();
wait.done();
});
};

exports.userAdminUpdate = function(req, res) {
if (!userIsAdmin(req)) res.redirect('/');

// Setup a function to call once everything is done
var wait = new Wait(function() {
res.redirect('/admin/user');
});

var users = req.body.user;
for (var name in users) {
var role = users[name];
User.findOneAndUpdate({ 'name' : name }, {'role' : Number(role)},
wait.add(function(err, user) {}));
}

var remove = req.body.remove || {};
for (var name in remove) {
User.findOneAndRemove({ 'name' : name },
wait.add(function(err, user) {}));
}

wait.done();
};
61 changes: 18 additions & 43 deletions controllers/auth.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
var passport = require('passport');
var crypto = require('crypto');
var authKeys = require('./authKeys.json');
var strategies = require('./strategies');
var allStrategies = require('./strategies.json');
var loadPassport = require('../libs/passportLoader').loadPassport;
var strategyInstances = require('../libs/passportLoader').strategyInstances;
var Strategy = require('../models/strategy.js').Strategy;
var User = require('../models/user').User;

var URL = process.env.NODE_ENV === 'production' ?
'openuserjs.org' : 'localhost:8080';
var userRoles = require('../models/userRoles.json');

passport.serializeUser(function(user, done) {
done(null, user._id);
Expand All @@ -17,44 +17,19 @@ passport.deserializeUser(function(id, done) {
});
});

var strategyInstances = {};
function dummyVerify(id, done) { console.error('A strategy called dummy.'); }

// Setup all our auth strategies
strategies.forEach(function(strategy) {
var requireStr = 'passport-' + strategy;
var PassportStrategy = require(requireStr).Strategy;
var instance = null;

switch (strategy) {
case 'yahoo':
case 'paypal':
case 'google':
case 'aol':
case 'openid':
instance = new PassportStrategy(
{
returnURL: 'http://' + URL + '/auth/' + strategy + '/callback/',
realm: 'http://' + URL + '/'
},
dummyVerify
);
break;
default:
instance = new PassportStrategy(
{
consumerKey: authKeys[strategy].id,
consumerSecret: authKeys[strategy].key,
clientID: authKeys[strategy].id,
clientSecret: authKeys[strategy].key,
callbackURL: 'http://' + URL + '/auth/' + strategy + '/callback/'
},
dummyVerify
);
Strategy.find({}, function(err, strategies) {

// Get OpenId strategies
for (var name in allStrategies) {
if (!allStrategies[name].oauth) {
strategies.push({ 'name' : name, 'openid' : true });
}
}

strategyInstances[strategy] = instance;
passport.use(instance);

strategies.forEach(function(strategy) {
loadPassport(strategy);
});
});

exports.auth = function(req, res, next) {
Expand All @@ -65,7 +40,7 @@ exports.auth = function(req, res, next) {
var authenticate = passport.authenticate(strategy);

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

authenticate(req, res);
}
Expand Down Expand Up @@ -127,7 +102,7 @@ exports.callback = function(req, res, next) {
'name' : username,
'auths' : [digest],
'strategies' : [strategy],
'role' : 4,
'role' : userRoles.length - 1,
'about': ''
});
user.save(function(err, user) {
Expand Down
29 changes: 22 additions & 7 deletions controllers/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var Strategy = require('../models/strategy.js').Strategy;
var User = require('../models/user').User;
var strategies = require('./strategies.json');

Expand All @@ -6,14 +7,28 @@ exports.home = function(req, res) {
var user = req.session.user;

if (!user) {
/*options.strategies = [{'strat' : '', 'pretty' : ''}];
strategies.forEach(function(strat, index) {
options.strategies.push({
'strat' : strat, 'pretty' : prettystrategies[index]});
});*/
Strategy.find({}, function(err, strats) {
options.strategies = [];

// Get the strategies we have OAuth keys for
strats.forEach(function(strat) {
options.strategies.push({ 'strat' : strat.name,
'display' : strat.display });
});

// Get OpenId strategies
for (var name in strategies) {
var strategy = strategies[name];
if (!strategy.oauth) {
options.strategies.push({ 'strat' : name,
'display' : strategy.name });
}
}

res.render('index', options, res);
});
} else {
options.username = user.name;
res.render('index', options, res);
}

res.render('index', options, res);
}
37 changes: 37 additions & 0 deletions libs/passportLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
var passport = require('passport');
var URL = process.env.NODE_ENV === 'production' ?
'openuserjs.org' : 'localhost:8080';

exports.strategyInstances = {};

// This will load a single passport
exports.loadPassport = function(strategy) {
//console.log(strategy);
var requireStr = 'passport-' + strategy.name;
var PassportStrategy = require(requireStr).Strategy;
var instance = null;

if(strategy.openid) {
instance = new PassportStrategy(
{
returnURL: 'http://' + URL + '/auth/' + strategy.name + '/callback/',
realm: 'http://' + URL + '/'
},
function() {}
);
} else {
instance = new PassportStrategy(
{
consumerKey: strategy.id,
consumerSecret: strategy.key,
clientID: strategy.id,
clientSecret: strategy.key,
callbackURL: 'http://' + URL + '/auth/' + strategy.name + '/callback/'
},
function() {}
);
}

exports.strategyInstances[strategy.name] = instance;
passport.use(instance);
};
32 changes: 32 additions & 0 deletions libs/wait.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// A simple way of waiting for a bunch of async calls to finish
// Call the constructor with the function you want run when everything is done
// Add functions that you want to wait to get called
// Basically callbacks to async functions

// So instead of:
// asyncFunction(callback);

// Do:
// var wait = new Wait(function() { console.log('done'); });
// asyncFunction(wait.add(callback));

function Wait(last) {
this.counter = 0;
this.done = function() {
if (this.counter) return;
last();
};
}

Wait.prototype.add = function(task) {
++this.counter;

var wait = this;
return (function() {
task.apply(null, Array.prototype.slice.apply(arguments));
--wait.counter;
wait.done();
});
}

exports.Wait = Wait;
File renamed without changes.
2 changes: 1 addition & 1 deletion views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ <h3>Login (or Register)</h3>
<p>You can leave it blank if you're logging in.</p>
<select name="auth">
{{#strategies}}
<option value="{{strat}}">{{pretty}}</option>
<option value="{{strat}}">{{display}}</option>
{{/strategies}}
</select>
<input type="submit" value="Go!" />
Expand Down
21 changes: 21 additions & 0 deletions views/userAdmin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<html>
<head>
<title>User Administration</title>
</head>
<body>
<form method="post" action="/admin/user/update">
{{#users}}
<strong>{{name}}</strong> | Role:
<select name="user[{{name}}]">
{{#roles}}
<option value="{{val}}" {{#selected}}selected="{{selected}}"{{/selected}}>
{{display}}</option>
{{/roles}}
</select> | Remove:
<input type="checkbox" name="remove[{{name}}]" value="{{user}}"><br />
{{/users}}
<input type="submit" value="Update" />
</form>
</body>
</html>
<html>

0 comments on commit 390b095

Please sign in to comment.