Permalink
Browse files

Move Foursquare strategy to use new 'supported' Oauth2 API

  • Loading branch information...
ciaranj committed Jun 29, 2011
1 parent 59c5868 commit 89bc6238c2bb5568e32f9848e86267d14330a6e2
Showing with 89 additions and 80 deletions.
  1. +23 −19 README.md
  2. +65 −60 lib/auth.strategies/foursquare.js
  3. +1 −1 support/oauth
View
@@ -56,29 +56,33 @@ For twitter auth
Changelog
=========
* 0.2.3
Added support for BitBucket (Thanks simplegeo)
Fixed bug introduced in 0.2.2 when dealing with strategies that 'fail'
* 0.2.2
Added index.js ( Pau Ramon Revilla ) to root folder for easier inclusion
Added support for SSO with http://t.sina.com.cn/ ( Danny Siu )
Added hd query parameter to allow Google Hosted Domain for google sSO strategy ( Olmo Maldonado )
* 0.3.0
Modified 'request.Authenticate(...)' to pass back 'undefined' when an active authentication strategy has required a communication with the browser to fully complete the authentication process. - *Possible Breaking change*
Fixed various failure cases for nearly all strategies (utilising the new 'undefined' authentication type)
Migrated Foursquare strategy to OAuth2 (requires at least v0.9.3 of node-oauth)
* 0.2.3
Added support for BitBucket (Thanks simplegeo)
Fixed bug introduced in 0.2.2 when dealing with strategies that 'fail'
* 0.2.2
Added index.js ( Pau Ramon Revilla ) to root folder for easier inclusion
Added support for SSO with http://t.sina.com.cn/ ( Danny Siu )
Added hd query parameter to allow Google Hosted Domain for google sSO strategy ( Olmo Maldonado )
Adds prelimenary support for the new HTTP MAC authentication scheme as defined by RFC-to-be:
http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token ( Eran Hammer-Lahav )
Added support for SSO with google (not using OpenId, but OAuth, so an intermediary approach) (Masahiro Hayashi)
Twitter strategy now supports OAuth Callback Urls (Ben Marvell)
Added option 'isAutoRespond' to handle authentication errors by the application with the HTTP Schemes. (Eran Hammer-Lahav)
Support for 'scoped' users (aka multiple con-current authentications) (Logan Aube)
* 0.2.1
Removed dead file that was seemingly breaking nDistro
http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token ( Eran Hammer-Lahav )
Added support for SSO with google (not using OpenId, but OAuth, so an intermediary approach) (Masahiro Hayashi)
Twitter strategy now supports OAuth Callback Urls (Ben Marvell)
Added option 'isAutoRespond' to handle authentication errors by the application with the HTTP Schemes. (Eran Hammer-Lahav)
Support for 'scoped' users (aka multiple con-current authentications) (Logan Aube)
* 0.2.1
Removed dead file that was seemingly breaking nDistro
* 0.2.0
Updated HTTP strategies c/o Robbie Clutton no longer require passwords to be stored in the plain. - *Breaking change*
Changed the default javascript file from auth.js to index.js. - *Breaking change*
Updated HTTP strategies c/o Robbie Clutton no longer require passwords to be stored in the plain. - *Breaking change*
Changed the default javascript file from auth.js to index.js. - *Breaking change*
Fixed the isAuthenticated mechanism to work with mongodb (Lakin Wecker, Richard Walsh)
Realm parameter now ignored in the Authorization header for the OAuth Provider strategy (Wade Simmons)
Realm parameter now ignored in the Authorization header for the OAuth Provider strategy (Wade Simmons)
* 0.1.3
Strategies can now be written that do not require the session middleware.
Strategies can now be written that do not require the session middleware.
* 0.1.2
Added in new strategy that allows your authentication strategy to be a custom OAuth provider.
Added in new strategy that allows your authentication strategy to be a custom OAuth provider.
* 0.1.0
New simplified configuration (connect idiomatic) of strategies implemented.
@@ -1,78 +1,83 @@
/*!
* Copyright(c) 2010 stunti
* Copyright(c) 2010 Ciaran Jessup <ciaranj@gmail.com>
* Derived from work by 'Stunti'
* MIT Licensed
*/
var OAuth= require("oauth").OAuth,
var OAuth= require("oauth").OAuth2,
url = require("url"),
connect = require("connect"),
http = require('http');
Foursquare= module.exports= function(options, server) {
Facebook= module.exports= function(options, server) {
options= options || {}
var that= {};
var my= {};
that.name = options.name || "foursquare";
// Construct the internal OAuth client
my._oAuth= new OAuth("http://foursquare.com/oauth/request_token",
"http://foursquare.com/oauth/access_token",
options.consumerKey, options.consumerSecret,
"1.0", null, "HMAC-SHA1");
// Build the authentication routes required
that.setupRoutes= function(server) {
server.use('/', connect.router(function routes(app){
app.get('/auth/foursquare_callback', function(req, res){
req.authenticate([that.name], function(error, authenticated) {
res.writeHead(303, { 'Location': req.session.foursquare_redirect_url });
res.end('');
});
});
}));
}
my._oAuth= new OAuth(options.appId, options.appSecret, "https://foursquare.com", "/oauth2/authenticate", "/oauth2/access_token");
my._oAuth.setAccessTokenName("oauth_token");
my._redirectUri= options.callback;
// Give the strategy a name
that.name = options.name || "foursquare";
// Build the authentication routes required
that.setupRoutes= function(server) {
server.use('/', connect.router(function routes(app){
app.get('/auth/foursquare_callback', function(req, res){
req.authenticate([that.name], function(error, authenticated) {
res.writeHead(303, { 'Location': req.session.foursquare_redirect_url });
res.end('');
});
});
}));
}
// Declare the method that actually does the authentication
that.authenticate= function(request, response, callback) {
//todo: if multiple connect middlewares were doing this, it would be more efficient to do it in the stack??
var parsedUrl= url.parse(request.url, true);
//todo: makw the call timeout ....
var parsedUrl= url.parse(request.url, true);
var self= this;
if( parsedUrl.query && parsedUrl.query.oauth_token && request.session.auth["foursquare_oauth_token_secret"] ) {
my._oAuth.getOAuthAccessToken(parsedUrl.query.oauth_token,
request.session.auth["foursquare_oauth_token_secret"],
function( error, oauth_token, oauth_token_secret, additionalParameters ) {
if( error ) {
require('sys').debug('error in foursquare');
callback(null);
} else {
request.session.auth["foursquare_oauth_token_secret"] = oauth_token_secret;
request.session.auth["foursquare_oauth_token"] = oauth_token;
my._oAuth.getProtectedResource("http://api.foursquare.com/v1/user.json", "GET",
oauth_token, oauth_token_secret,
function(err, data, response) {
if(err ) {
callback(null);
}
else {
var user= JSON.parse(data).user;
self.success(user, callback)
}
});
}
});
} else {
my._oAuth.getOAuthRequestToken(function(error, oauth_token, oauth_token_secret, oauth_authorize_url, additionalParameters ) {
if (error) {
callback(null); // Ignore the error upstream, treat as validation failure.
} else {
request.session['foursquare_redirect_url'] = request.url;
request.session.auth["foursquare_oauth_token_secret"] = oauth_token_secret;
request.session.auth["foursquare_oauth_token"] = oauth_token;
self.redirect(response, "http://foursquare.com/oauth/authorize?oauth_token=" + oauth_token, callback);
}
});
}
};
this._foursquare_fail= function(callback) {
request.getAuthDetails()['foursquare_login_attempt_failed']= true;
this.fail(callback);
}
if( request.getAuthDetails()['foursquare_login_attempt_failed'] === true ) {
// Because we bounce through authentication calls across multiple requests
// we use this to keep track of the fact we *Really* have failed to authenticate
// so that we don't keep re-trying to authenticate forever.
delete request.getAuthDetails()['foursquare_login_attempt_failed'];
self.fail( callback );
}
else {
if( parsedUrl.query && ( parsedUrl.query.code || parsedUrl.query.error === 'access_denied' ) ) {
if( parsedUrl.query.error == 'access_denied' ) {
self._foursquare_fail(callback);
} else {
my._oAuth.getOAuthAccessToken(parsedUrl.query && parsedUrl.query.code ,
{redirect_uri: my._redirectUri,grant_type : "authorization_code"},
function( error, access_token, refresh_token ){
if( error ) callback(error)
else {
request.session["access_token"]= access_token;
if( refresh_token ) request.session["refresh_token"]= refresh_token;
my._oAuth.getProtectedResource("https://api.foursquare.com/v2/users/self", request.session["access_token"], function (error, data, response) {
if( error ) {
self._foursquare_fail(callback);
}else {
self.success(JSON.parse(data), callback)
}
})
}
});
}
}
else {
request.session['foursquare_redirect_url']= request.url;
var redirectUrl= my._oAuth.getAuthorizeUrl({redirect_uri : my._redirectUri, response_type: "code" })
self.redirect(response, redirectUrl, callback);
}
}
}
return that;
}
};

0 comments on commit 89bc623

Please sign in to comment.