gut custom everyauth code & replace with derby-auth

This commit is contained in:
Tyler Renelle 2012-11-15 00:47:58 -05:00
parent b2d6596f92
commit 91364e19b6
8 changed files with 51 additions and 247 deletions

View file

@ -26,7 +26,7 @@ _ = require('underscore');
get('/:uid?', function(page, model, _arg, next) {
var req, sess, uid;
uid = _arg.uid;
if (uid && !(require('guid').isGuid(uid))) {
if (uid && !(require('derby-auth/node_modules/guid').isGuid(uid))) {
return next();
}
req = page._res.req;
@ -34,8 +34,8 @@ get('/:uid?', function(page, model, _arg, next) {
return page.redirect('https://' + req.headers.host + req.url);
}
sess = model.session;
if (sess.habitRpgAuth && sess.habitRpgAuth.facebook) {
model.set('_facebookAuthenticated', true);
if (sess.loggedIn) {
model.set('_loggedIn', true);
}
model.set('_userId', sess.userId);
return model.subscribe("users." + sess.userId, function(err, user) {

View file

@ -1,114 +0,0 @@
// Generated by CoffeeScript 1.4.0
var content, derby, req, schema, _;
derby = require('derby');
schema = require('../app/schema');
content = require('../app/content');
_ = require('underscore');
req = void 0;
module.exports.setRequest = function(r) {
return req = r;
};
module.exports.newUserAndPurl = function() {
var acceptableUid, model, sess, uidParam;
model = req.getModel();
sess = model.session;
uidParam = req.url.split('/')[1];
if (!sess.userId) {
sess.userId = derby.uuid();
model.set("users." + sess.userId, schema.newUserObject());
}
acceptableUid = require('guid').isGuid(uidParam);
if (acceptableUid && sess.userId !== uidParam && !(sess.habitRpgAuth && sess.habitRpgAuth.facebook)) {
return sess.userId = uidParam;
}
};
module.exports.setupEveryauth = function(everyauth) {
everyauth.debug = true;
everyauth.everymodule.findUserById(function(id, callback) {
return callback(null, null);
});
everyauth.facebook.appId(process.env.FACEBOOK_KEY).appSecret(process.env.FACEBOOK_SECRET).findOrCreateUser(function(session, accessToken, accessTokenExtra, fbUserMetadata) {
var model, q;
session.habitRpgAuth || (session.habitRpgAuth = {});
session.habitRpgAuth.facebook = fbUserMetadata.id;
model = req.getModel();
q = model.query('users').withEveryauth('facebook', fbUserMetadata.id);
model.fetch(q, function(err, user) {
var id;
id = user && !_.isEmpty(user.get()) && user.get()[0].id;
console.log({
err: err,
id: id,
fbUserMetadata: fbUserMetadata
});
if (id && id !== session.userId) {
return session.userId = id;
} else {
model.setNull("users." + session.userId + ".auth", {
'facebook': {}
});
return model.set("users." + session.userId + ".auth.facebook", fbUserMetadata);
}
});
return fbUserMetadata;
}).redirectPath("/");
return everyauth.everymodule.handleLogout(function(req, res) {
if (req.session.habitRpgAuth && req.session.habitRpgAuth.facebook) {
req.session.habitRpgAuth.facebook = void 0;
}
req.session.userId = void 0;
req.logout();
return this.redirect(res, this.logoutRedirectPath());
});
};
module.exports.setupQueries = function(store) {
store.query.expose('users', 'withId', function(id) {
return this.byId(id);
});
store.query.expose('users', 'withEveryauth', function(provider, id) {
console.log({
withEveryauth: {
provider: provider,
id: id
}
});
return this.where("auth." + provider + ".id").equals(id);
});
return store.queryAccess('users', 'withEveryauth', function(methodArgs) {
var accept;
accept = arguments[arguments.length - 1];
return accept(true);
});
};
module.exports.setupAccessControl = function(store) {
store.accessControl = true;
store.readPathAccess('users.*', function() {
var captures, next;
if (!(this.session && this.session.userId)) {
return;
}
captures = arguments[0];
next = arguments[arguments.length - 1];
return next(captures === this.session.userId);
});
return store.writeAccess('*', 'users.*', function() {
var captures, next, pathArray;
if (!(this.session && this.session.userId)) {
return;
}
captures = arguments[0];
next = arguments[arguments.length - 1];
pathArray = captures.split('.');
return next(pathArray[0] === this.session.userId);
});
};

View file

@ -1,5 +1,5 @@
// Generated by CoffeeScript 1.4.0
var MongoStore, ONE_YEAR, app, auth, derby, everyauth, express, expressApp, gzippo, habitrpgMiddleware, http, path, priv, publicPath, racer, root, server, serverError, store;
var MongoStore, ONE_YEAR, app, auth, derby, everyauth, express, expressApp, gzippo, habitrpgMiddleware, http, options, path, priv, publicPath, racer, root, server, serverError, store, strategies;
http = require('http');
@ -19,7 +19,7 @@ serverError = require('./serverError');
MongoStore = require('connect-mongo')(express);
auth = require('./auth');
auth = require('derby-auth');
priv = require('./private');
@ -48,12 +48,6 @@ store = derby.createStore({
listen: server
});
auth.setupQueries(store);
auth.setupEveryauth(everyauth);
auth.setupAccessControl(store);
ONE_YEAR = 1000 * 60 * 60 * 24 * 365;
root = path.dirname(path.dirname(__dirname));
@ -65,11 +59,27 @@ habitrpgMiddleware = function(req, res, next) {
model = req.getModel();
model.set('_mobileDevice', /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(req.header('User-Agent')));
model.set('_nodeEnv', process.env.NODE_ENV);
auth.setRequest(req);
auth.newUserAndPurl();
return next();
};
strategies = {
facebook: {
strategy: require("passport-facebook").Strategy,
conf: {
clientID: process.env.FACEBOOK_KEY,
clientSecret: process.env.FACEBOOK_SECRET
}
}
};
options = {
domain: "http://localhost:3000",
allowPurl: true,
schema: require('../app/schema').newUserObject()
};
auth.init(expressApp, store, strategies, options);
expressApp.use(express.favicon()).use(gzippo.staticGzip(publicPath, {
maxAge: ONE_YEAR
})).use(express.compress()).use(express.bodyParser()).use(express.methodOverride()).use(express.cookieParser()).use(store.sessionMiddleware({
@ -80,7 +90,9 @@ expressApp.use(express.favicon()).use(gzippo.staticGzip(publicPath, {
store: new MongoStore({
url: process.env.NODE_DB_URI
})
})).use(store.modelMiddleware()).use(priv.middleware).use(habitrpgMiddleware).use(everyauth.middleware()).use(app.router()).use(expressApp.router).use(serverError(root));
})).use(store.modelMiddleware()).use(priv.middleware).use(habitrpgMiddleware).use(auth.middleware()).use(app.router()).use(expressApp.router).use(serverError(root));
auth.routes();
priv.routes(expressApp);

View file

@ -5,12 +5,13 @@
"main": "./server.js",
"dependencies": {
"derby": "0.3.13",
"derby-ui-boot": "*",
"racer-db-mongo": "0.3.13",
"connect-mongo": ">=0.1.9",
"derby-auth": "*",
"passport-facebook": "*",
"express": "*",
"gzippo": "*",
"connect-mongo": ">=0.1.9",
"everyauth": "git://github.com/bnoguchi/everyauth#express3",
"derby-ui-boot": "*",
"guid": "*",
"moment": "*",
"stripe": "*",

View file

@ -17,7 +17,7 @@ _ = require 'underscore'
get '/:uid?', (page, model, {uid}, next) ->
# delegate to other routes. FIXME how to define express routes first?
if uid && !(require('guid').isGuid(uid))
if uid && !(require('derby-auth/node_modules/guid').isGuid(uid))
return next()
# Force SSL
@ -26,8 +26,7 @@ get '/:uid?', (page, model, {uid}, next) ->
return page.redirect 'https://' + req.headers.host + req.url
sess = model.session
if sess.habitRpgAuth && sess.habitRpgAuth.facebook
model.set('_facebookAuthenticated', true)
model.set('_loggedIn', true) if sess.loggedIn
model.set '_userId', sess.userId
model.subscribe "users.#{sess.userId}", (err, user) ->
# Set variables which are passed from the controller to the view

View file

@ -1,103 +0,0 @@
derby = require('derby')
schema = require('../app/schema')
content = require('../app/content')
_ = require('underscore')
# Need this for later use by EveryAuth in the MiddleWare
req = undefined
module.exports.setRequest = (r) ->
req = r
module.exports.newUserAndPurl = ->
model = req.getModel()
sess = model.session
uidParam = req.url.split('/')[1]
## -------- (1) New user --------
# They get to play around before creating a new account.
unless sess.userId
sess.userId = derby.uuid()
model.set "users.#{sess.userId}", schema.newUserObject()
## -------- (2) PURL --------
# eg, http://localhost/{guid}), legacy - will be removed eventually
# tests if UUID was used (bookmarked private url), and restores that session
acceptableUid = require('guid').isGuid(uidParam)
if acceptableUid && sess.userId!=uidParam && !(sess.habitRpgAuth && sess.habitRpgAuth.facebook)
# TODO check if in database - issue with accessControl which is on current uid?
sess.userId = uidParam
module.exports.setupEveryauth = (everyauth) ->
everyauth.debug = true
everyauth.everymodule.findUserById (id, callback) ->
# will never be called, can't fetch user from database at this point on the server
# see https://github.com/codeparty/racer/issues/39. Handled in app/auth.coffee for now
callback null, null
# Facebook Authentication Logic
everyauth
.facebook
.appId(process.env.FACEBOOK_KEY)
.appSecret(process.env.FACEBOOK_SECRET)
.findOrCreateUser( (session, accessToken, accessTokenExtra, fbUserMetadata) ->
# Put it in the session for later use
# FIXME shouldn't this be set by everyauth? (session.auth.facebook)
session.habitRpgAuth ||= {}
session.habitRpgAuth.facebook = fbUserMetadata.id
model = req.getModel()
q = model.query('users').withEveryauth('facebook', fbUserMetadata.id)
model.fetch q, (err, user) ->
id = user && !_.isEmpty(user.get()) && user.get()[0].id
console.log {err:err, id:id, fbUserMetadata:fbUserMetadata}
# Has user been tied to facebook account already?
if (id && id!=session.userId)
session.userId = id
# Else tie user to their facebook account
else
model.setNull "users.#{session.userId}.auth", {'facebook':{}}
model.set "users.#{session.userId}.auth.facebook", fbUserMetadata
fbUserMetadata
).redirectPath "/"
everyauth.everymodule.handleLogout (req, res) ->
if req.session.habitRpgAuth && req.session.habitRpgAuth.facebook
req.session.habitRpgAuth.facebook = undefined
req.session.userId = undefined
req.logout() # The logout method is added for you by everyauth, too
@redirect res, @logoutRedirectPath()
module.exports.setupQueries = (store) ->
## Setup Queries
store.query.expose 'users', 'withId', (id) ->
@byId(id)
store.query.expose 'users', 'withEveryauth', (provider, id) ->
console.log {withEveryauth:{provider:provider,id:id}}
@where("auth.#{provider}.id").equals(id)
store.queryAccess 'users', 'withEveryauth', (methodArgs) ->
accept = arguments[arguments.length-1]
accept(true) #for now
module.exports.setupAccessControl = (store) ->
store.accessControl = true
# Callback signatures here have variable length, eg `callback(captures..., next)`
# Is using arguments[n] the correct way to handle this?
store.readPathAccess 'users.*', () -> #captures, next) ->
return unless @session && @session.userId # https://github.com/codeparty/racer/issues/37
captures = arguments[0]
next = arguments[arguments.length-1]
# console.log { readPathAccess: {captures:captures, sessionUserId:@session.userId, next:next} }
next(captures == @session.userId)
store.writeAccess '*', 'users.*', () -> #captures, value, next) ->
return unless @session && @session.userId
captures = arguments[0]
next = arguments[arguments.length-1]
pathArray = captures.split('.')
# console.log { writeAccess: {captures:captures, next:next, pathArray:pathArray, arguments:arguments} }
next(pathArray[0] == @session.userId)

View file

@ -7,8 +7,8 @@ app = require '../app'
everyauth = require('everyauth')
serverError = require './serverError'
MongoStore = require('connect-mongo')(express)
auth = require('./auth')
priv = require('./private')
auth = require 'derby-auth'
priv = require './private'
## RACER CONFIGURATION ##
@ -28,9 +28,6 @@ derby.use(require 'racer-db-mongo')
store = derby.createStore
db: {type: 'Mongo', uri: process.env.NODE_DB_URI}
listen: server
auth.setupQueries(store)
auth.setupEveryauth(everyauth)
auth.setupAccessControl(store)
ONE_YEAR = 1000 * 60 * 60 * 24 * 365
root = path.dirname path.dirname __dirname
@ -41,9 +38,20 @@ habitrpgMiddleware = (req, res, next) ->
## Set _mobileDevice to true or false so view can exclude portions from mobile device
model.set '_mobileDevice', /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(req.header 'User-Agent')
model.set '_nodeEnv', process.env.NODE_ENV
auth.setRequest(req) # Need to pass into auth, so auth can save as private variable used later by EveryAuth
auth.newUserAndPurl()
next()
# Authentication setup
strategies =
facebook:
strategy: require("passport-facebook").Strategy
conf:
clientID: process.env.FACEBOOK_KEY
clientSecret: process.env.FACEBOOK_SECRET
options =
domain: "http://localhost:3000"
allowPurl: true
schema: require('../app/schema').newUserObject()
auth.init expressApp, store, strategies, options
expressApp
.use(express.favicon())
@ -71,12 +79,13 @@ expressApp
# the app router to pass server accessible data to a model
.use(priv.middleware)
.use(habitrpgMiddleware)
.use(everyauth.middleware())
.use(auth.middleware())
# Creates an express middleware from the app's routes
.use(app.router())
.use(expressApp.router)
.use(serverError root)
auth.routes()
priv.routes(expressApp)
require('./serverRoutes')(expressApp, root, derby)

View file

@ -12,11 +12,11 @@
<ui:connectionAlert>
<div id="head">
<div class='pull-right'>
{#unless _facebookAuthenticated}
{#unless _loggedIn}
<a href="/auth/facebook"><img src='/img/facebook-login-register.jpeg' alt="Login / Register With Facebook"/></a>
{else}
<div class="btn-group">
<button class="btn btn-small">{_user.auth.facebook.name}</button>
<button class="btn btn-small">{_user.auth.facebook.name.givenName} {_user.auth.facebook.name.familyName}</button>
<button class="btn btn-small dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
</button>