Skip to content

Commit

Permalink
Fixes #43 Add oauth_body_hash (#44)
Browse files Browse the repository at this point in the history
* Add oauth_body_hash capability

* Add token secret to hash body function

* correct base_string with oauth-body-hash

* Version bump and formatting changes

* Added documentation and fixed oauth param name

* Added tests for oauth_body_hash signing
  • Loading branch information
Andrew Butterfield authored and ddo committed Jan 17, 2017
1 parent 50dd716 commit 91557b7
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ $.ajax({
* url: ``String``
* method: ``String`` default ``'GET'``
* data: ``Object`` any custom data you want to send with, including extra oauth option ``oauth_*`` as oauth_callback, oauth_version...
* includeBodyHash: ``Boolean`` default ``false`` set to true if you want ``oauth_body_hash`` signing

```js
var request_data = {
Expand Down
21 changes: 20 additions & 1 deletion oauth-1.0a.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ OAuth.prototype.authorize = function(request, token) {
request.data = {};
}

if(request.includeBodyHash) {
oauth_data.oauth_body_hash = this.getBodyHash(request, token.secret)
}

oauth_data.oauth_signature = this.getSignature(request, token.secret, oauth_data);

return oauth_data;
Expand All @@ -94,6 +98,16 @@ OAuth.prototype.getSignature = function(request, token_secret, oauth_data) {
return this.hash_function(this.getBaseString(request, oauth_data), this.getSigningKey(token_secret));
};

/**
* Create a OAuth Body Hash
* @param {Object} request data
*/
OAuth.prototype.getBodyHash = function(request, token_secret) {
var body = typeof request.data === 'string' ? request.data : JSON.stringify(request.data)

return this.hash_function(body, this.getSigningKey(token_secret))
};

/**
* Base String = Method + Base Url + ParameterString
* @param {Object} request data
Expand All @@ -115,7 +129,12 @@ OAuth.prototype.getBaseString = function(request, oauth_data) {
* @return {Object} Parameter string data
*/
OAuth.prototype.getParameterString = function(request, oauth_data) {
var base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.mergeObject(request.data, this.deParamUrl(request.url)))));
var base_string_data;
if (oauth_data.oauth_body_hash) {
base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.deParamUrl(request.url))));
} else {
base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.mergeObject(request.data, this.deParamUrl(request.url)))));
}

var data_str = '';

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "oauth-1.0a",
"version": "2.0.0",
"version": "2.1.0",
"description": "OAuth 1.0a Request Authorization for Node and Browser.",
"scripts": {
"test": "make test"
Expand Down
131 changes: 131 additions & 0 deletions test/oauth_body_hash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
var expect = require('chai').expect;
var OAuth = require('../oauth-1.0a');
var crypto = require('crypto');

describe("OAuth Body Hash", function() {
var oauth = new OAuth({
consumer: {
key: '1434affd-4d69-4a1a-bace-cc5c6fe493bc',
secret: '932a216f-fb94-43b6-a2d2-e9c6b345cbea'
},
signature_method: 'HMAC-SHA1',
hash_function: function(base_string, key) {
return crypto.createHmac('sha1', key).update(base_string).digest('base64');
}
});

//overide for testing only !!!
oauth.getTimeStamp = function() {
return 1484599369;
};

//overide for testing only !!!
oauth.getNonce = function(length) {
return 't62lMDp9DLwKZJJbZTpmSAhRINGBEOcF';
};

var request = {
url: 'http://canvas.docker/api/lti/accounts/1/tool_proxy',
method: 'POST',
data: {
"@context":[
"http://purl.imsglobal.org/ctx/lti/v2/ToolProxy"
],
"@type":"ToolProxy",
"lti_version":"LTI-2p1",
"tool_proxy_guid":"0cf04d67-8a0d-4d41-af61-6e8c6fc3e68c",
"tool_consumer_profile":"http://canvas.docker/api/lti/accounts/1/tool_consumer_profile/339b6700-e4cb-47c5-a54f-3ee0064921a9",
"tool_profile":{
"lti_version":"LTI-2p1",
"product_instance":{
"guid":"fd75124a-140e-470f-944c-114d2d93db40",
"product_info":{
"product_name":{
"default_value":"TestTool",
"key":"tool.name"
},
"product_version":"0.1.0",
"product_family":{
"code":"testtool",
"vendor":{
"code":"Example.com",
"vendor_name":{
"default_value":"Example",
"key":"tool.vendor.name"
}
}
}
}
},
"base_url_choice":[
{
"default_base_url":"http://example.docker/",
"selector":{
"applies_to":[
"MessageHandler"
]
}
}
],
"resource_handler":[
{
"resource_type":{
"code":"testtool"
},
"resource_name":{
"default_value":"TestTool",
"key":"testtool.resource.name"
},
"message":[
{
"message_type":"basic-lti-launch-request",
"path":"lti_launch",
"enabled_capability":[
"Canvas.placements.courseNavigation"
]
}
]
}
]
},
"enabled_capability":[
"OAuth.splitSecret"
],
"security_contract":{
"tp_half_shared_secret":"1c7849d3c9f037a9891575c8508d3aaab6a9e1312b5d0353625f83d68f0d545344f81ff9e1849b6400982a0d3f6bf953c6095265e3b6d700a73f5be94ce5654c"
}
},
includeBodyHash: true
};

describe('#getBodyHash', function() {
it('should handle data encoded as an object', function() {
expect(oauth.getBodyHash(request, '')).to.equal('F7L9O06JqL/LZpQBlsKC/7R53uM=')
});

it('should handle data encoded as a string', function() {
request.data = JSON.stringify(request.data)
expect(oauth.getBodyHash(request, '')).to.equal('F7L9O06JqL/LZpQBlsKC/7R53uM=')
});
});

describe('#authorize', function() {
it('should properly include an oauth_body_hash param', function() {
expect(oauth.authorize(request)).to.eql({
oauth_consumer_key: '1434affd-4d69-4a1a-bace-cc5c6fe493bc',
oauth_nonce: 't62lMDp9DLwKZJJbZTpmSAhRINGBEOcF',
oauth_signature_method: 'HMAC-SHA1',
oauth_timestamp: 1484599369,
oauth_version: '1.0',
oauth_body_hash: 'F7L9O06JqL/LZpQBlsKC/7R53uM=',
oauth_signature: 'ayrFZ4NkVhALlAPY8WjDJXuzK8Y='
});
});
});

describe('#toHeader', function() {
it('should properly include an oauth_body_hash header', function() {
expect(oauth.toHeader(oauth.authorize(request))).to.have.property('Authorization', 'OAuth oauth_body_hash="F7L9O06JqL%2FLZpQBlsKC%2F7R53uM%3D", oauth_consumer_key="1434affd-4d69-4a1a-bace-cc5c6fe493bc", oauth_nonce="t62lMDp9DLwKZJJbZTpmSAhRINGBEOcF", oauth_signature="ayrFZ4NkVhALlAPY8WjDJXuzK8Y%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1484599369", oauth_version="1.0"');
});
});
});

0 comments on commit 91557b7

Please sign in to comment.