From 9c8fd2958e1f1bade4d7c8c7d5c2fe9ec1978135 Mon Sep 17 00:00:00 2001 From: Mike Bannister Date: Wed, 1 Aug 2012 06:09:41 -0400 Subject: [PATCH] nicer way of handling /_oauth/ routes --- .../accounts-oauth1-helper/oauth1_server.js | 22 ++++----- .../accounts-oauth1-helper/oauth1_tests.js | 2 +- .../accounts-oauth2-helper/oauth2_server.js | 48 +++++++------------ packages/accounts-twitter/twitter_client.js | 4 +- 4 files changed, 27 insertions(+), 49 deletions(-) diff --git a/packages/accounts-oauth1-helper/oauth1_server.js b/packages/accounts-oauth1-helper/oauth1_server.js index a71fe55f97..f58991f478 100644 --- a/packages/accounts-oauth1-helper/oauth1_server.js +++ b/packages/accounts-oauth1-helper/oauth1_server.js @@ -4,7 +4,7 @@ Meteor.accounts.oauth1._services = {}; // Register a handler for an OAuth1 service. The handler will be called - // when we get an incoming http request on /_oauth1/{serviceName}. This + // when we get an incoming http request on /_oauth/{serviceName}. This // handler should use that information to fetch data about the user // logging in. // @@ -49,16 +49,17 @@ // connect middleware Meteor.accounts.oauth1._handleRequest = function (req, res, next) { - // XXX Used _oauth1 so routing can differentiate between oauth1 and 2 - // XXX I think the solution is to use a regex that includes the - // applicable providers, e.g. oauth 1 regex would contain (twitter|flickr) - - // req.url will be "/_oauth1/?" + // req.url will be "/_oauth/?" var barePath = req.url.substring(0, req.url.indexOf('?')); var splitPath = barePath.split('/'); + // Find service based on url + var serviceName = splitPath[2]; + var service = Meteor.accounts.oauth1._services[serviceName]; + // Any non-oauth request will continue down the default middlewares - if (splitPath[1] !== '_oauth1') { + // Same goes for service that hasn't been registered + if (splitPath[1] !== '_oauth' || !service) { next(); return; } @@ -67,19 +68,12 @@ // This way the subsequent call to the `login` method will be // immediate. - var serviceName = splitPath[2]; - - // XXX check against a list of installed services too - if (!serviceName) - throw new Meteor.accounts.ConfigError("Service could not be found"); - // Make sure we're configured if (!Meteor.accounts[serviceName]._appId || !Meteor.accounts[serviceName]._appUrl) throw new Meteor.accounts.ConfigError("Need to call Meteor.accounts." + serviceName + ".config first"); if (!Meteor.accounts[serviceName]._secret) throw new Meteor.accounts.ConfigError("Need to call Meteor.accounts." + serviceName + ".setSecret first"); - var service = Meteor.accounts.oauth1._services[serviceName]; var config = Meteor.accounts[serviceName]; var oauth = new OAuth(config); diff --git a/packages/accounts-oauth1-helper/oauth1_tests.js b/packages/accounts-oauth1-helper/oauth1_tests.js index 826793bb60..afa341dcb4 100644 --- a/packages/accounts-oauth1-helper/oauth1_tests.js +++ b/packages/accounts-oauth1-helper/oauth1_tests.js @@ -18,7 +18,7 @@ Tinytest.add("oauth2 - loginResultForState is stored", function (test) { // simulate logging in using foobook var req = {method: "POST", - url: "/_oauth1/foobook?close", + url: "/_oauth/foobook?close", query: {state: "STATE"}}; Meteor.accounts.oauth1._handleRequest(req, new http.ServerResponse(req)); diff --git a/packages/accounts-oauth2-helper/oauth2_server.js b/packages/accounts-oauth2-helper/oauth2_server.js index 1409589579..6853951020 100644 --- a/packages/accounts-oauth2-helper/oauth2_server.js +++ b/packages/accounts-oauth2-helper/oauth2_server.js @@ -56,8 +56,13 @@ var barePath = req.url.substring(0, req.url.indexOf('?')); var splitPath = barePath.split('/'); + // Find service based on url + var serviceName = splitPath[2]; + var service = Meteor.accounts.oauth2._services[serviceName]; + // Any non-oauth request will continue down the default middlewares - if (splitPath[1] !== '_oauth') { + // Same goes for service that hasn't been registered + if (splitPath[1] !== '_oauth' || !service) { next(); return; } @@ -66,40 +71,19 @@ // This way the subsequent call to the `login` method will be // immediate. - var serviceName = splitPath[2]; - var service = Meteor.accounts.oauth2._services[serviceName]; + // Get or create user id + var oauthResult = service.handleOauthRequest(req.query); - try { - // Get or create user id - var oauthResult = service && service.handleOauthRequest(req.query); + if (oauthResult) { // could be null if user declined permissions + var userId = Meteor.accounts.updateOrCreateUser(oauthResult.options, oauthResult.extra); - // could be null if user declined permissions, or if there was an - // error of some sort. - if (oauthResult && req.query.state) { - var userId = Meteor.accounts.updateOrCreateUser( - oauthResult.options, oauthResult.extra); + // Generate and store a login token for reconnect + // XXX this could go in accounts_server.js instead + var loginToken = Meteor.accounts._loginTokens.insert({userId: userId}); - // Generate and store a login token for reconnect - // XXX this could go in accounts_server.js instead - var loginToken = Meteor.accounts._loginTokens.insert({userId: userId}); - - // Store results to subsequent call to `login` - Meteor.accounts.oauth2._loginResultForState[req.query.state] = - {token: loginToken, id: userId}; - } - } catch (err) { - // if we got thrown an error, save it off, it will get passed to - // the approporiate login call (if any) and reported there. - // - // The other option would be to display it in the popup tab that - // is still open at this point, ignoring the 'close' or 'redirect' - // we were passed. But then the developer wouldn't be able to - // style the error or react to it in any way. - if (req.query.state && err instanceof Error) - Meteor.accounts.oauth2._loginResultForState[req.query.state] = err; - - // also log to the server console, so the developer sees it. - Meteor._debug("Exception in oauth2 handler", err); + // Store results to subsequent call to `login` + Meteor.accounts.oauth2._loginResultForState[req.query.state] = + {token: loginToken, id: userId}; } // We support ?close and ?redirect=URL. Any other query should diff --git a/packages/accounts-twitter/twitter_client.js b/packages/accounts-twitter/twitter_client.js index 55f44f0973..40d36b1482 100644 --- a/packages/accounts-twitter/twitter_client.js +++ b/packages/accounts-twitter/twitter_client.js @@ -4,8 +4,8 @@ throw new Meteor.accounts.ConfigError("Need to call Meteor.accounts.twitter.config first"); var state = Meteor.uuid(); - var callbackUrl = Meteor.accounts.twitter._appUrl + '/_oauth1/twitter?close&state=' + state; - var url = '/_oauth1/twitter/request_token?callbackUrl=' + encodeURIComponent(callbackUrl) + var callbackUrl = Meteor.accounts.twitter._appUrl + '/_oauth/twitter?close&state=' + state; + var url = '/_oauth/twitter/request_token?callbackUrl=' + encodeURIComponent(callbackUrl) Meteor.accounts.oauth1.initiateLogin(state, url); };