Skip to content

Commit

Permalink
Fixed code to work with google signature style and standard oauth
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Amor Kvalheim committed Apr 14, 2010
1 parent fc68688 commit fadb019
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 10 deletions.
19 changes: 16 additions & 3 deletions lib/oauth/oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,19 @@ exports.OAuth = Plugin.extend({
**/
var requestTokenMethod = function() {
var self = this;
plugin.oauth_service.requestToken(this.method, 'http', this.headers['host'], this.url.href, this.headers, this.params, function(err, result) {
var finalPath = this.url.href.split(/\?/)[0];

plugin.oauth_service.requestToken(this.method, 'http', this.headers['host'], finalPath, this.headers, this.params, function(err, result) {
if(err) {
sys.puts("======================== status:" + err.statusCode);
sys.puts("======================== message:" + err.message);

self.halt(err.statusCode, err.message)
} else {
self.halt(200, ["oauth_token=" + result["token"], "oauth_token_secret=" + result["token_secret"], "oauth_callback_confirmed=" + result["oauth_callback_confirmed"]].join("&"));
}
});
// self.halt(400, querystring.escape("oauth_token=82fac54b189e080000010000&oauth_token_secret=82fac54b3eba010000020000&oauth_callback_confirmed=true"));
};
// Handle both get and request methods
post(options['request_token_url'], requestTokenMethod);
Expand Down Expand Up @@ -96,8 +102,11 @@ exports.OAuth = Plugin.extend({
plugin.authorize_provider.call(self, err, false, {token:oauth_token});
} else {
if(result.callback != null && result.callback != "oob") {
var callback = querystring.unescape(result.callback);
// Correctly add the tokens if the callback has a ? allready
var redirect_url = callback.match(/\?/) != null ? "&oauth_token=" + result.token + "&oauth_verifier=" + result.verifier : "?oauth_token=" + result.token + "&oauth_verifier=" + result.verifier;
// Signal that a redirect is in order after finished process
self.redirect(querystring.unescape(result.callback) + "?oauth_token=" + result.token + "&oauth_verifier=" + result.verifier);
self.redirect(querystring.unescape(result.callback) + redirect_url);
} else {
plugin.authorization_finished_provider.call(self, err, result);
}
Expand All @@ -111,9 +120,13 @@ exports.OAuth = Plugin.extend({
**/
var accessTokenMethod = function() {
var self = this;
var finalPath = this.url.href.split(/\?/)[0];

plugin.oauth_service.accessToken(this.method, 'http', this.headers['host'], this.url.href, this.headers, this.params, function(err, result) {
plugin.oauth_service.accessToken(this.method, 'http', this.headers['host'], finalPath, this.headers, this.params, function(err, result) {
if(err) {
sys.puts("======================== status:" + err.statusCode);
sys.puts("======================== message:" + err.message);

self.halt(err.statusCode, err.message);
} else {
self.halt(200, "oauth_token=" + result.access_token + "&oauth_token_secret=" + result.token_secret);
Expand Down
43 changes: 36 additions & 7 deletions lib/oauth/oauth_services.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ OAuthServices.prototype.authorize = function(method, protocol, url, path, header
self.provider.applicationByConsumerKey(token.consumer_key, function(err, user) {
if(user.consumer_key == null || user.secret == null) { callback(new errors.OAuthProviderError("provider: applicationByConsumerKey must return a object with fields [token, secret]"), null); return;}
// If we have a user for this consumer key let's calculate the signature
var calculatedSignature = self.calculateSignature(method, protocol, url, path, requestParameters, token.token_secret, user.secret);
var calculatedSignature = self.calculateSignature(method, protocol, url, path, requestParameters, token.token_secret, user.secret);
// Check if the signature is correct and return a access token
if(calculatedSignature == requestParameters.oauth_signature) {
if(calculatedSignature == requestParameters.oauth_signature || self.calculateSignatureGoogleWay(method, protocol, url, path, requestParameters, token.token_secret, user.secret) == requestParameters.oauth_signature) {
callback(null, true);
} else {
callback(new errors.OAuthBadRequestError("Invalid signature"), null);
Expand Down Expand Up @@ -80,7 +80,7 @@ OAuthServices.prototype.requestToken = function(method, protocol, url, path, hea
// If we have a user for this consumer key let's calculate the signature
var calculatedSignature = self.calculateSignature(method, protocol, url, path, requestParameters, user.token, user.secret);
// Check if the signature is correct and return a request token
if(calculatedSignature == requestParameters.oauth_signature) {
if(calculatedSignature == requestParameters.oauth_signature || self.calculateSignatureGoogleWay(method, protocol, url, path, requestParameters, user.token, user.secret) == requestParameters.oauth_signature) {
self.provider.generateRequestToken(requestParameters.oauth_consumer_key, requestParameters.oauth_callback, function(err, result) {
if(err) {
callback(new errors.OAuthProviderError("internal error"), null);
Expand All @@ -101,6 +101,10 @@ OAuthServices.prototype.requestToken = function(method, protocol, url, path, hea
OAuthServices.prototype.accessToken = function(method, protocol, url, path, headers, parameters, callback) {
var requestParameters = this.parseParameters(headers, parameters);
if(requestParameters == null) { callback(new errors.OAuthBadRequestError("Missing required parameter"), null); return };

sys.puts(sys.inspect(requestParameters));
sys.puts(sys.inspect(headers));

// Ensure correct parameters are available
if(!this.validateParameters(requestParameters, ['oauth_consumer_key', 'oauth_token', 'oauth_signature_method', 'oauth_signature', 'oauth_timestamp', 'oauth_nonce', 'oauth_verifier'])) { callback(new errors.OAuthBadRequestError("Missing required parameter")); return };
var self = this;
Expand All @@ -127,7 +131,7 @@ OAuthServices.prototype.accessToken = function(method, protocol, url, path, head
// If we have a user for this consumer key let's calculate the signature
var calculatedSignature = self.calculateSignature(method, protocol, url, path, requestParameters, tokenObject.token_secret, user.secret);
// Check if the signature is correct and return a access token
if(calculatedSignature == requestParameters.oauth_signature) {
if(calculatedSignature == requestParameters.oauth_signature || self.calculateSignatureGoogleWay(method, protocol, url, path, requestParameters, tokenObject.token_secret, user.secret) == requestParameters.oauth_signature) {
self.provider.generateAccessToken(requestParameters['oauth_token'], function(err, result) {
if(result.access_token == null || result.token_secret == null) { callback(new errors.OAuthProviderError("generateAccessToken must return a object with fields [access_token, token_secret]"), null); return; }
callback(null, result);
Expand Down Expand Up @@ -185,18 +189,43 @@ OAuthServices.prototype.calculateSignature = function(method, protocol, url, pat
var values = [];
for(var name in parameters) { if(name != 'oauth_signature') values.push(name); };
values = values.sort();
// Let's build the actual string for the signature
var concatString = method + "&" + querystring.escape(protocol + "://" + url + path) + "&" + querystring.escape(values.map(function(value) {
return value + "=" + parameters[value];
}, '').join("&"));
//
// sys.puts("---------------------------------------------------------------------------");
// sys.puts(concatString);
// sys.puts("---------------------------------------------------------------------------");
//
// Calculated signature
return querystring.escape(crypto.SHA1.b64_hmac_sha1(key, concatString) + "=");
}

OAuthServices.prototype.calculateSignatureGoogleWay = function(method, protocol, url, path, parameters, token, secret) {
// Create secret key for encryption
var key = secret + "&" + (token != null ? token : '');
// Create array of names and sort it
var values = [];
for(var name in parameters) { if(name != 'oauth_signature') values.push(name); };
values = values.sort();
var concatString = method + "&" + querystring.escape(protocol + "://" + url + path) + "&" + querystring.escape(values.map(function(value) {
return querystring.escape(value) + "=" + querystring.escape(parameters[value]);
}, '').join("&"));

// sys.puts("---------------------------------------------------------------------------");
// sys.puts(concatString);
// sys.puts("---------------------------------------------------------------------------");

// Calculated signature
return crypto.SHA1.b64_hmac_sha1(key, concatString) + "=";
}

OAuthServices.prototype.parseParameters = function(headers, parameters) {
// Check if this is sent by headers or parameters
if(parameters['oauth_consumer_key'] != null) {
return parameters;
if(parameters.get != null && parameters.get['oauth_consumer_key'] != null) {
return parameters.get;
} else if(parameters.post != null && parameters.post['oauth_consumer_key'] != null) {
return parameters.post;
} else if(headers['authorization'] != null && headers['authorization'].indexOf('OAuth') != -1) {
var authorizationString = headers['authorization'].substring('OAuth '.length, headers['authorization'].length);
// Trim the strings and split the values
Expand Down

0 comments on commit fadb019

Please sign in to comment.