From 91364e19b6b7d9ec9941212d3d9f2b0cef58ebaf Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Thu, 15 Nov 2012 00:47:58 -0500 Subject: [PATCH] gut custom everyauth code & replace with derby-auth --- lib/app/index.js | 6 +-- lib/server/auth.js | 114 ---------------------------------------- lib/server/index.js | 34 ++++++++---- package.json | 7 +-- src/app/index.coffee | 5 +- src/server/auth.coffee | 103 ------------------------------------ src/server/index.coffee | 25 ++++++--- views/app/index.html | 4 +- 8 files changed, 51 insertions(+), 247 deletions(-) delete mode 100644 lib/server/auth.js delete mode 100644 src/server/auth.coffee diff --git a/lib/app/index.js b/lib/app/index.js index 39456aabc2..27d3efb7cc 100644 --- a/lib/app/index.js +++ b/lib/app/index.js @@ -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) { diff --git a/lib/server/auth.js b/lib/server/auth.js deleted file mode 100644 index 7c99f61e24..0000000000 --- a/lib/server/auth.js +++ /dev/null @@ -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); - }); -}; diff --git a/lib/server/index.js b/lib/server/index.js index f7817fc893..a824ab706d 100644 --- a/lib/server/index.js +++ b/lib/server/index.js @@ -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); diff --git a/package.json b/package.json index 48e12954ac..21b8cb1860 100644 --- a/package.json +++ b/package.json @@ -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": "*", diff --git a/src/app/index.coffee b/src/app/index.coffee index 2b02192bc2..5de48db597 100644 --- a/src/app/index.coffee +++ b/src/app/index.coffee @@ -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 diff --git a/src/server/auth.coffee b/src/server/auth.coffee deleted file mode 100644 index 2523d5f51d..0000000000 --- a/src/server/auth.coffee +++ /dev/null @@ -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) \ No newline at end of file diff --git a/src/server/index.coffee b/src/server/index.coffee index f018e2d0fa..8c6436abd7 100644 --- a/src/server/index.coffee +++ b/src/server/index.coffee @@ -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) diff --git a/views/app/index.html b/views/app/index.html index 0e2e465810..7eaded910d 100644 --- a/views/app/index.html +++ b/views/app/index.html @@ -12,11 +12,11 @@