Merge remote-tracking branch 'origin/master' into evanp-issue144
This commit is contained in:
commit
4e351fef16
20
Readme.md
20
Readme.md
|
@ -6,6 +6,8 @@ Tested against Twitter (http://twitter.com), term.ie (http://term.ie/oauth/examp
|
|||
|
||||
Also provides rudimentary OAuth2 support, tested against facebook, github, foursquare, google and Janrain. For more complete usage examples please take a look at connect-auth (http://github.com/ciaranj/connect-auth)
|
||||
|
||||
[![Clone in Koding](http://learn.koding.com/btn/clone_d.png)][koding]
|
||||
[koding]: https://koding.com/Teamwork?import=https://github.com/ciaranj/node-oauth/archive/master.zip&c=git1
|
||||
|
||||
Installation
|
||||
==============
|
||||
|
@ -22,7 +24,7 @@ To run examples/tests insall Mocha `$ npm install -g mocha` and run `$ mocha you
|
|||
|
||||
```javascript
|
||||
describe('OAuth1.0',function(){
|
||||
var OAuth = require('OAuth');
|
||||
var OAuth = require('oauth');
|
||||
|
||||
it('tests trends Twitter API v1.1',function(done){
|
||||
var oauth = new OAuth.OAuth(
|
||||
|
@ -36,7 +38,7 @@ describe('OAuth1.0',function(){
|
|||
);
|
||||
oauth.get(
|
||||
'https://api.twitter.com/1.1/trends/place.json?id=23424977',
|
||||
'your user toke for this app', //test user token
|
||||
'your user token for this app', //test user token
|
||||
'your user secret for this app', //test user secret
|
||||
function (e, data, res){
|
||||
if (e) console.error(e);
|
||||
|
@ -50,7 +52,7 @@ describe('OAuth1.0',function(){
|
|||
## OAuth2.0
|
||||
```javascript
|
||||
describe('OAuth2',function(){
|
||||
var OAuth = require('OAuth');
|
||||
var OAuth = require('oauth');
|
||||
|
||||
it('gets bearer token', function(done){
|
||||
var OAuth2 = OAuth.OAuth2;
|
||||
|
@ -75,6 +77,11 @@ describe('OAuth2',function(){
|
|||
Change History
|
||||
==============
|
||||
|
||||
* 0.9.11
|
||||
- OAuth2: No longer sends the type=webserver argument with the OAuth2 requests (thank you bendiy)
|
||||
- OAuth2: Provides a default (and overrideable) User-Agent header (thanks to Andrew Martens & Daniel Mahlow)
|
||||
- OAuth1: New followRedirects client option (true by default) (thanks to Pieter Joost van de Sande)
|
||||
- OAuth1: Adds RSA-SHA1 support (thanks to Jeffrey D. Van Alstine & Michael Garvin & Andreas Knecht)
|
||||
* 0.9.10
|
||||
- OAuth2: Addresses 2 issues that came in with 0.9.9, #129 & #125 (thank you José F. Romaniello)
|
||||
* 0.9.9
|
||||
|
@ -156,3 +163,10 @@ Contributors (In no particular order)
|
|||
* rolandboon - http://rolandboon.com
|
||||
* Brian Park - http://github.com/yaru22
|
||||
* José F. Romaniello - http://github.com/jfromaniello
|
||||
* bendiy - https://github.com/bendiy
|
||||
* Andrew Martins - http://www.andrewmartens.com
|
||||
* Daniel Mahlow - https://github.com/dmahlow
|
||||
* Pieter Joost van de Sande - https://github.com/pjvds
|
||||
* Jeffrey D. Van Alstine
|
||||
* Michael Garvin
|
||||
* Andreas Knecht
|
||||
|
|
28
lib/oauth.js
28
lib/oauth.js
|
@ -13,6 +13,9 @@ exports.OAuth= function(requestUrl, accessUrl, consumerKey, consumerSecret, vers
|
|||
this._accessUrl= accessUrl;
|
||||
this._consumerKey= consumerKey;
|
||||
this._consumerSecret= this._encodeData( consumerSecret );
|
||||
if (signatureMethod == "RSA-SHA1") {
|
||||
this._privateKey = consumerSecret;
|
||||
}
|
||||
this._version= version;
|
||||
if( authorize_callback === undefined ) {
|
||||
this._authorize_callback= "oob";
|
||||
|
@ -21,7 +24,7 @@ exports.OAuth= function(requestUrl, accessUrl, consumerKey, consumerSecret, vers
|
|||
this._authorize_callback= authorize_callback;
|
||||
}
|
||||
|
||||
if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1")
|
||||
if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1" && signatureMethod != "RSA-SHA1")
|
||||
throw new Error("Un-supported signature method: " + signatureMethod )
|
||||
this._signatureMethod= signatureMethod;
|
||||
this._nonceSize= nonceSize || 32;
|
||||
|
@ -29,7 +32,8 @@ exports.OAuth= function(requestUrl, accessUrl, consumerKey, consumerSecret, vers
|
|||
"Connection" : "close",
|
||||
"User-Agent" : "Node authentication"}
|
||||
this._clientOptions= this._defaultClientOptions= {"requestTokenHttpMethod": "POST",
|
||||
"accessTokenHttpMethod": "POST"};
|
||||
"accessTokenHttpMethod": "POST",
|
||||
"followRedirects": true};
|
||||
this._oauthParameterSeperator = ",";
|
||||
};
|
||||
|
||||
|
@ -40,9 +44,12 @@ exports.OAuthEcho= function(realm, verify_credentials, consumerKey, consumerSecr
|
|||
this._verifyCredentials = verify_credentials;
|
||||
this._consumerKey= consumerKey;
|
||||
this._consumerSecret= this._encodeData( consumerSecret );
|
||||
if (signatureMethod == "RSA-SHA1") {
|
||||
this._privateKey = consumerSecret;
|
||||
}
|
||||
this._version= version;
|
||||
|
||||
if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1")
|
||||
if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1" && signatureMethod != "RSA-SHA1")
|
||||
throw new Error("Un-supported signature method: " + signatureMethod );
|
||||
this._signatureMethod= signatureMethod;
|
||||
this._nonceSize= nonceSize || 32;
|
||||
|
@ -159,8 +166,8 @@ exports.OAuth.prototype._sortRequestParams= function(argument_pairs) {
|
|||
return argument_pairs;
|
||||
}
|
||||
|
||||
exports.OAuth.prototype._normaliseRequestParams= function(arguments) {
|
||||
var argument_pairs= this._makeArrayOfArgumentsHash(arguments);
|
||||
exports.OAuth.prototype._normaliseRequestParams= function(args) {
|
||||
var argument_pairs= this._makeArrayOfArgumentsHash(args);
|
||||
// First encode them #3.4.1.3.2 .1
|
||||
for(var i=0;i<argument_pairs.length;i++) {
|
||||
argument_pairs[i][0]= this._encodeData( argument_pairs[i][0] );
|
||||
|
@ -197,6 +204,10 @@ exports.OAuth.prototype._createSignature= function(signatureBase, tokenSecret) {
|
|||
if( this._signatureMethod == "PLAINTEXT" ) {
|
||||
hash= key;
|
||||
}
|
||||
else if (this._signatureMethod == "RSA-SHA1") {
|
||||
key = this._privateKey || "";
|
||||
hash= crypto.createSign("RSA-SHA1").update(signatureBase).sign(key, 'base64');
|
||||
}
|
||||
else {
|
||||
if( crypto.Hmac ) {
|
||||
hash = crypto.createHmac("sha1", key).update(signatureBase).digest("base64");
|
||||
|
@ -361,6 +372,7 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke
|
|||
request= this._createClient(parsedUrl.port, parsedUrl.hostname, method, path, headers);
|
||||
}
|
||||
|
||||
var clientOptions = this._clientOptions;
|
||||
if( callback ) {
|
||||
var data="";
|
||||
var self= this;
|
||||
|
@ -369,14 +381,14 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke
|
|||
// allow this behaviour.
|
||||
var allowEarlyClose= OAuthUtils.isAnEarlyCloseHost( parsedUrl.hostname );
|
||||
var callbackCalled= false;
|
||||
function passBackControl( response ) {
|
||||
var passBackControl = function( response ) {
|
||||
if(!callbackCalled) {
|
||||
callbackCalled= true;
|
||||
if ( response.statusCode >= 200 && response.statusCode <= 299 ) {
|
||||
callback(null, data, response);
|
||||
} else {
|
||||
// Follow 301 or 302 redirects with Location HTTP header
|
||||
if((response.statusCode == 301 || response.statusCode == 302) && response.headers && response.headers.location) {
|
||||
if((response.statusCode == 301 || response.statusCode == 302) && clientOptions.followRedirects && response.headers && response.headers.location) {
|
||||
self._performSecureRequest( oauth_token, oauth_token_secret, method, response.headers.location, extra_params, post_body, post_content_type, callback);
|
||||
}
|
||||
else {
|
||||
|
@ -402,8 +414,10 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke
|
|||
});
|
||||
|
||||
request.on("error", function(err) {
|
||||
if(!callbackCalled) {
|
||||
callbackCalled= true;
|
||||
callback( err )
|
||||
}
|
||||
});
|
||||
|
||||
if( (method == "POST" || method =="PUT") && post_body != null && post_body != "" ) {
|
||||
|
|
|
@ -49,19 +49,25 @@ exports.OAuth2.prototype.buildAuthHeader= function(token) {
|
|||
return this._authMethod + ' ' + token;
|
||||
};
|
||||
|
||||
exports.OAuth2.prototype._chooseHttpLibrary= function( parsedUrl ) {
|
||||
var http_library= https;
|
||||
// As this is OAUth2, we *assume* https unless told explicitly otherwise.
|
||||
if( parsedUrl.protocol != "https:" ) {
|
||||
http_library= http;
|
||||
}
|
||||
return http_library;
|
||||
};
|
||||
|
||||
exports.OAuth2.prototype._request= function(method, url, headers, post_body, access_token, callback) {
|
||||
|
||||
var http_library= https;
|
||||
var creds = crypto.createCredentials({ });
|
||||
var parsedUrl= URL.parse( url, true );
|
||||
if( parsedUrl.protocol == "https:" && !parsedUrl.port ) {
|
||||
parsedUrl.port= 443;
|
||||
}
|
||||
|
||||
// As this is OAUth2, we *assume* https unless told explicitly otherwise.
|
||||
if( parsedUrl.protocol != "https:" ) {
|
||||
http_library= http;
|
||||
}
|
||||
var http_library= this._chooseHttpLibrary( parsedUrl );
|
||||
|
||||
|
||||
var realHeaders= {};
|
||||
for( var key in this._customHeaders ) {
|
||||
|
@ -74,6 +80,10 @@ exports.OAuth2.prototype._request= function(method, url, headers, post_body, acc
|
|||
}
|
||||
realHeaders['Host']= parsedUrl.host;
|
||||
|
||||
if (!realHeaders['User-Agent']) {
|
||||
realHeaders['User-Agent'] = 'Node-oauth';
|
||||
}
|
||||
|
||||
realHeaders['Content-Length']= post_body ? Buffer.byteLength(post_body) : 0;
|
||||
if( access_token && !('Authorization' in realHeaders)) {
|
||||
if( ! parsedUrl.query ) parsedUrl.query= {};
|
||||
|
@ -129,7 +139,7 @@ exports.OAuth2.prototype._executeRequest= function( http_library, options, post_
|
|||
callback(e);
|
||||
});
|
||||
|
||||
if( options.method == 'POST' && post_body ) {
|
||||
if( (options.method == 'POST' || options.method == 'PUT') && post_body ) {
|
||||
request.write(post_body);
|
||||
}
|
||||
request.end();
|
||||
|
@ -138,7 +148,6 @@ exports.OAuth2.prototype._executeRequest= function( http_library, options, post_
|
|||
exports.OAuth2.prototype.getAuthorizeUrl= function( params ) {
|
||||
var params= params || {};
|
||||
params['client_id'] = this._clientId;
|
||||
params['type'] = 'web_server';
|
||||
return this._baseSite + this._authorizeUrl + "?" + querystring.stringify(params);
|
||||
}
|
||||
|
||||
|
@ -146,7 +155,6 @@ exports.OAuth2.prototype.getOAuthAccessToken= function(code, params, callback) {
|
|||
var params= params || {};
|
||||
params['client_id'] = this._clientId;
|
||||
params['client_secret'] = this._clientSecret;
|
||||
params['type']= 'web_server';
|
||||
var codeParam = (params.grant_type === 'refresh_token') ? 'refresh_token' : 'code';
|
||||
params[codeParam]= code;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ "name" : "oauth"
|
||||
, "description" : "Library for interacting with OAuth 1.0, 1.0A, 2 and Echo. Provides simplified client access and allows for construction of more complex apis and OAuth providers."
|
||||
, "version" : "0.9.10"
|
||||
, "version" : "0.9.11"
|
||||
, "directories" : { "lib" : "./lib" }
|
||||
, "main" : "index.js"
|
||||
, "author" : "Ciaran Jessup <ciaranj@gmail.com>"
|
||||
|
|
193
tests/oauth.js
193
tests/oauth.js
|
@ -2,7 +2,8 @@ var vows = require('vows'),
|
|||
assert = require('assert'),
|
||||
events = require('events'),
|
||||
OAuth= require('../lib/oauth').OAuth,
|
||||
OAuthEcho= require('../lib/oauth').OAuthEcho;
|
||||
OAuthEcho= require('../lib/oauth').OAuthEcho,
|
||||
crypto = require('crypto');
|
||||
|
||||
var DummyResponse =function( statusCode ) {
|
||||
this.statusCode= statusCode;
|
||||
|
@ -23,7 +24,37 @@ DummyRequest.prototype.end= function(){
|
|||
this.response.emit('end');
|
||||
}
|
||||
|
||||
//Valid RSA keypair used to test RSA-SHA1 signature method
|
||||
var RsaPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\n" +
|
||||
"MIICXQIBAAKBgQDizE4gQP5nPQhzof/Vp2U2DDY3UY/Gxha2CwKW0URe7McxtnmE\n" +
|
||||
"CrZnT1n/YtfrrCNxY5KMP4o8hMrxsYEe05+1ZGFT68ztms3puUxilU5E3BQMhz1t\n" +
|
||||
"JMJEGcTt8nZUlM4utli7fHgDtWbhvqvYjRMGn3AjyLOfY8XZvnFkGjipvQIDAQAB\n" +
|
||||
"AoGAKgk6FcpWHOZ4EY6eL4iGPt1Gkzw/zNTcUsN5qGCDLqDuTq2Gmk2t/zn68VXt\n" +
|
||||
"tVXDf/m3qN0CDzOBtghzaTZKLGhnSewQ98obMWgPcvAsb4adEEeW1/xigbMiaW2X\n" +
|
||||
"cu6GhZxY16edbuQ40LRrPoVK94nXQpj8p7w4IQ301Sm8PSECQQD1ZlOj4ugvfhEt\n" +
|
||||
"exi4WyAaM45fylmN290UXYqZ8SYPI/VliDytIlMfyq5Rv+l+dud1XDPrWOQ0ImgV\n" +
|
||||
"HJn7uvoZAkEA7JhHNmHF9dbdF9Koj86K2Cl6c8KUu7U7d2BAuB6pPkt8+D8+y4St\n" +
|
||||
"PaCmN4oP4X+sf5rqBYoXywHlqEei2BdpRQJBAMYgR4cZu7wcXGIL8HlnmROObHSK\n" +
|
||||
"OqN9z5CRtUV0nPW8YnQG+nYOMG6KhRMbjri750OpnYF100kEPmRNI0VKQIECQE8R\n" +
|
||||
"fQsRleTYz768ahTVQ9WF1ySErMwmfx8gDcD6jjkBZVxZVpURXAwyehopi7Eix/VF\n" +
|
||||
"QlxjkBwKIEQi3Ks297kCQQCL9by1bueKDMJO2YX1Brm767pkDKkWtGfPS+d3xMtC\n" +
|
||||
"KJHHCqrS1V+D5Q89x5wIRHKxE5UMTc0JNa554OxwFORX\n" +
|
||||
"-----END RSA PRIVATE KEY-----";
|
||||
|
||||
var RsaPublicKey = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDizE4gQP5nPQhzof/Vp2U2DDY3\n" +
|
||||
"UY/Gxha2CwKW0URe7McxtnmECrZnT1n/YtfrrCNxY5KMP4o8hMrxsYEe05+1ZGFT\n" +
|
||||
"68ztms3puUxilU5E3BQMhz1tJMJEGcTt8nZUlM4utli7fHgDtWbhvqvYjRMGn3Aj\n" +
|
||||
"yLOfY8XZvnFkGjipvQIDAQAB\n" +
|
||||
"-----END PUBLIC KEY-----";
|
||||
|
||||
vows.describe('OAuth').addBatch({
|
||||
'When newing OAuth': {
|
||||
topic: new OAuth(null, null, null, null, null, null, "PLAINTEXT"),
|
||||
'followRedirects is enabled by default': function (oa) {
|
||||
assert.equal(oa._clientOptions.followRedirects, true)
|
||||
}
|
||||
},
|
||||
'When generating the signature base string described in http://oauth.net/core/1.0/#sig_base_example': {
|
||||
topic: new OAuth(null, null, null, null, null, null, "HMAC-SHA1"),
|
||||
'we get the expected result string': function (oa) {
|
||||
|
@ -32,6 +63,20 @@ vows.describe('OAuth').addBatch({
|
|||
assert.equal( result, "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal");
|
||||
}
|
||||
},
|
||||
'When generating the signature with RSA-SHA1': {
|
||||
topic: new OAuth(null, null, null, RsaPrivateKey, null, null, "RSA-SHA1"),
|
||||
'we get a valid oauth signature': function (oa) {
|
||||
var signatureBase = "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal";
|
||||
var oauthSignature = oa._createSignature(signatureBase, "xyz4992k83j47x0b");
|
||||
|
||||
assert.equal( oauthSignature, "qS4rhWog7GPgo4ZCJvUdC/1ZAax/Q4Ab9yOBvgxSopvmKUKp5rso+Zda46GbyN2hnYDTiA/g3P/d/YiPWa454BEBb/KWFV83HpLDIoqUUhJnlXX9MqRQQac0oeope4fWbGlfTdL2PXjSFJmvfrzybERD/ZufsFtVrQKS3QBpYiw=");
|
||||
|
||||
//now check that given the public key we can verify this signature
|
||||
var verifier = crypto.createVerify("RSA-SHA1").update(signatureBase);
|
||||
var valid = verifier.verify(RsaPublicKey, oauthSignature, 'base64');
|
||||
assert.ok( valid, "Signature could not be verified with RSA public key");
|
||||
}
|
||||
},
|
||||
'When generating the signature base string with PLAINTEXT': {
|
||||
topic: new OAuth(null, null, null, null, null, null, "PLAINTEXT"),
|
||||
'we get the expected result string': function (oa) {
|
||||
|
@ -521,7 +566,7 @@ vows.describe('OAuth').addBatch({
|
|||
oa._createClient= op;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'PUT' : {
|
||||
'if no callback is passed' : {
|
||||
|
@ -817,6 +862,78 @@ vows.describe('OAuth').addBatch({
|
|||
oa._createClient= op;
|
||||
}
|
||||
}
|
||||
},
|
||||
'and followRedirect is true' : {
|
||||
'it should (re)perform the secure request but with the new location' : function(oa) {
|
||||
var op= oa._createClient;
|
||||
var psr= oa._performSecureRequest;
|
||||
var responseCounter = 1;
|
||||
var callbackCalled = false;
|
||||
var DummyResponse =function() {
|
||||
if( responseCounter == 1 ){
|
||||
this.statusCode= 301;
|
||||
this.headers= {location:"http://redirectto.com"};
|
||||
responseCounter++;
|
||||
}
|
||||
else {
|
||||
this.statusCode= 200;
|
||||
}
|
||||
}
|
||||
DummyResponse.prototype= events.EventEmitter.prototype;
|
||||
DummyResponse.prototype.setEncoding= function() {}
|
||||
|
||||
try {
|
||||
oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
|
||||
return new DummyRequest( new DummyResponse() );
|
||||
}
|
||||
oa._performSecureRequest= function( oauth_token, oauth_token_secret, method, url, extra_params, post_body, post_content_type, callback ) {
|
||||
if( responseCounter == 1 ) {
|
||||
assert.equal(url, "http://originalurl.com");
|
||||
}
|
||||
else {
|
||||
assert.equal(url, "http://redirectto.com");
|
||||
}
|
||||
return psr.call(oa, oauth_token, oauth_token_secret, method, url, extra_params, post_body, post_content_type, callback )
|
||||
}
|
||||
|
||||
oa._performSecureRequest("token", "token_secret", 'POST', 'http://originalurl.com', {"scope": "foobar,1,2"}, null, null, function() {
|
||||
// callback
|
||||
assert.equal(responseCounter, 2);
|
||||
callbackCalled= true;
|
||||
});
|
||||
assert.equal(callbackCalled, true)
|
||||
}
|
||||
finally {
|
||||
oa._createClient= op;
|
||||
oa._performSecureRequest= psr;
|
||||
}
|
||||
}
|
||||
},
|
||||
'and followRedirect is false' : {
|
||||
'it should not perform the secure request with the new location' : function(oa) {
|
||||
var op= oa._createClient;
|
||||
oa.setClientOptions({ followRedirects: false });
|
||||
var DummyResponse =function() {
|
||||
this.statusCode= 301;
|
||||
this.headers= {location:"http://redirectto.com"};
|
||||
}
|
||||
DummyResponse.prototype= events.EventEmitter.prototype;
|
||||
DummyResponse.prototype.setEncoding= function() {}
|
||||
|
||||
try {
|
||||
oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
|
||||
return new DummyRequest( new DummyResponse() );
|
||||
}
|
||||
oa._performSecureRequest("token", "token_secret", 'POST', 'http://originalurl.com', {"scope": "foobar,1,2"}, null, null, function(res, data, response) {
|
||||
// callback
|
||||
assert.equal(res.statusCode, 301);
|
||||
});
|
||||
}
|
||||
finally {
|
||||
oa._createClient= op;
|
||||
oa.setClientOptions({followRedirects:true});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'And A 302 redirect is received' : {
|
||||
|
@ -885,6 +1002,78 @@ vows.describe('OAuth').addBatch({
|
|||
oa._createClient= op;
|
||||
}
|
||||
}
|
||||
},
|
||||
'and followRedirect is true' : {
|
||||
'it should (re)perform the secure request but with the new location' : function(oa) {
|
||||
var op= oa._createClient;
|
||||
var psr= oa._performSecureRequest;
|
||||
var responseCounter = 1;
|
||||
var callbackCalled = false;
|
||||
var DummyResponse =function() {
|
||||
if( responseCounter == 1 ){
|
||||
this.statusCode= 302;
|
||||
this.headers= {location:"http://redirectto.com"};
|
||||
responseCounter++;
|
||||
}
|
||||
else {
|
||||
this.statusCode= 200;
|
||||
}
|
||||
}
|
||||
DummyResponse.prototype= events.EventEmitter.prototype;
|
||||
DummyResponse.prototype.setEncoding= function() {}
|
||||
|
||||
try {
|
||||
oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
|
||||
return new DummyRequest( new DummyResponse() );
|
||||
}
|
||||
oa._performSecureRequest= function( oauth_token, oauth_token_secret, method, url, extra_params, post_body, post_content_type, callback ) {
|
||||
if( responseCounter == 1 ) {
|
||||
assert.equal(url, "http://originalurl.com");
|
||||
}
|
||||
else {
|
||||
assert.equal(url, "http://redirectto.com");
|
||||
}
|
||||
return psr.call(oa, oauth_token, oauth_token_secret, method, url, extra_params, post_body, post_content_type, callback )
|
||||
}
|
||||
|
||||
oa._performSecureRequest("token", "token_secret", 'POST', 'http://originalurl.com', {"scope": "foobar,1,2"}, null, null, function() {
|
||||
// callback
|
||||
assert.equal(responseCounter, 2);
|
||||
callbackCalled= true;
|
||||
});
|
||||
assert.equal(callbackCalled, true)
|
||||
}
|
||||
finally {
|
||||
oa._createClient= op;
|
||||
oa._performSecureRequest= psr;
|
||||
}
|
||||
}
|
||||
},
|
||||
'and followRedirect is false' : {
|
||||
'it should not perform the secure request with the new location' : function(oa) {
|
||||
var op= oa._createClient;
|
||||
oa.setClientOptions({ followRedirects: false });
|
||||
var DummyResponse =function() {
|
||||
this.statusCode= 302;
|
||||
this.headers= {location:"http://redirectto.com"};
|
||||
}
|
||||
DummyResponse.prototype= events.EventEmitter.prototype;
|
||||
DummyResponse.prototype.setEncoding= function() {}
|
||||
|
||||
try {
|
||||
oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
|
||||
return new DummyRequest( new DummyResponse() );
|
||||
}
|
||||
oa._performSecureRequest("token", "token_secret", 'POST', 'http://originalurl.com', {"scope": "foobar,1,2"}, null, null, function(res, data, response) {
|
||||
// callback
|
||||
assert.equal(res.statusCode, 302);
|
||||
});
|
||||
}
|
||||
finally {
|
||||
oa._createClient= op;
|
||||
oa.setClientOptions({followRedirects:true});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,12 +125,89 @@ vows.describe('OAuth2').addBatch({
|
|||
'Given an OAuth2 instance with clientId, clientSecret and customHeaders': {
|
||||
topic: new OAuth2("clientId", "clientSecret", undefined, undefined, undefined,
|
||||
{ 'SomeHeader': '123' }),
|
||||
'When calling get': {
|
||||
'When GETing': {
|
||||
'we should see the custom headers mixed into headers property in options passed to http-library' : function(oa) {
|
||||
oa._executeRequest= function( http_library, options, callback ) {
|
||||
assert.equal(options.headers["SomeHeader"], "123");
|
||||
};
|
||||
oa.get("", {});
|
||||
},
|
||||
}
|
||||
},
|
||||
'Given an OAuth2 instance with a clientId and clientSecret': {
|
||||
topic: new OAuth2("clientId", "clientSecret"),
|
||||
'When POSTing': {
|
||||
'we should see a given string being sent to the request' : function(oa) {
|
||||
var bodyWritten= false;
|
||||
oa._chooseHttpLibrary= function() {
|
||||
return {
|
||||
request: function(options) {
|
||||
assert.equal(options.headers["Content-Type"], "text/plain");
|
||||
assert.equal(options.headers["Content-Length"], 26);
|
||||
assert.equal(options.method, "POST");
|
||||
return {
|
||||
end: function() {},
|
||||
on: function() {},
|
||||
write: function(body) {
|
||||
bodyWritten= true;
|
||||
assert.isNotNull(body);
|
||||
assert.equal(body, "THIS_IS_A_POST_BODY_STRING")
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
oa._request("POST", "", {"Content-Type":"text/plain"}, "THIS_IS_A_POST_BODY_STRING");
|
||||
assert.ok( bodyWritten );
|
||||
}
|
||||
},
|
||||
'When PUTing': {
|
||||
'we should see a given string being sent to the request' : function(oa) {
|
||||
var bodyWritten= false;
|
||||
oa._chooseHttpLibrary= function() {
|
||||
return {
|
||||
request: function(options) {
|
||||
assert.equal(options.headers["Content-Type"], "text/plain");
|
||||
assert.equal(options.headers["Content-Length"], 25);
|
||||
assert.equal(options.method, "PUT");
|
||||
return {
|
||||
end: function() {},
|
||||
on: function() {},
|
||||
write: function(body) {
|
||||
bodyWritten= true;
|
||||
assert.isNotNull(body);
|
||||
assert.equal(body, "THIS_IS_A_PUT_BODY_STRING")
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
oa._request("PUT", "", {"Content-Type":"text/plain"}, "THIS_IS_A_PUT_BODY_STRING");
|
||||
assert.ok( bodyWritten );
|
||||
}
|
||||
}
|
||||
},
|
||||
'When the user passes in the User-Agent in customHeaders': {
|
||||
topic: new OAuth2("clientId", "clientSecret", undefined, undefined, undefined,
|
||||
{ 'User-Agent': '123Agent' }),
|
||||
'When calling get': {
|
||||
'we should see the User-Agent mixed into headers property in options passed to http-library' : function(oa) {
|
||||
oa._executeRequest= function( http_library, options, callback ) {
|
||||
assert.equal(options.headers["User-Agent"], "123Agent");
|
||||
};
|
||||
oa.get("", {});
|
||||
}
|
||||
}
|
||||
},
|
||||
'When the user does not pass in a User-Agent in customHeaders': {
|
||||
topic: new OAuth2("clientId", "clientSecret", undefined, undefined, undefined,
|
||||
undefined),
|
||||
'When calling get': {
|
||||
'we should see the default User-Agent mixed into headers property in options passed to http-library' : function(oa) {
|
||||
oa._executeRequest= function( http_library, options, callback ) {
|
||||
assert.equal(options.headers["User-Agent"], "Node-oauth");
|
||||
};
|
||||
oa.get("", {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue