Update client to use hawk credentails instead of oauth

This commit is contained in:
Greg Arndt 2015-11-02 10:21:06 -06:00
Родитель 8415e97654
Коммит d9ecece744
4 изменённых файлов: 38 добавлений и 73 удалений

Просмотреть файл

@ -10,8 +10,8 @@ var Project = require('mozilla-treeherder/project');
// this configuration can be acquired from an ateam member working on
// treeherder (mdoglio).
var project = new Project('gaia', {
consumerKey: '...',
consumerSecret: '',
clientId: '...',
secret: '',
// Disabled by default but will retry post / put requests if a 429 is
// returned.
throttleRetries: 2
@ -30,7 +30,7 @@ See all the options with:
[treeherder-service](https://github.com/mozilla/treeherder-service) api errors will
include a traceback from the server. Most times these errors are simply
something you did wrong (no oauth credentials, wrong parameters, etc...)
something you did wrong (no hawk credentials, wrong parameters, etc...)
but there are times when there are actually bugs in treeherder... Submit
an [issue](https://bugzilla.mozilla.org/enter_bug.cgi?product=Tree%20Management&component=Treeherder) with the traceback.

Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "mozilla-treeherder",
"version": "0.5.0",
"version": "0.6.0",
"description": "Treeherder client for mozilla's test reporting UI",
"main": "project.js",
"bin": {
@ -43,9 +43,10 @@
"commander": "~2.1.0",
"debug": "^2.1.1",
"github": "~0.1.14",
"oauth": "~0.9.11",
"hawk": "^3.1.0",
"promise": "~4.0.0",
"superagent": "~0.16.0",
"superagent-promise": "0.0.0"
"superagent-promise": "0.0.0",
"utf8": "^2.1.1"
}
}

Просмотреть файл

@ -13,51 +13,25 @@ var request = require('superagent-promise');
var debug = require('debug')('mozilla-treeherder:project');
var Promise = require('promise');
var OAuth = require('oauth').OAuth;
var hawk = require('hawk');
var HttpError = require('./httperror');
var utf8 = require('utf8');
function buildRequest(oauth, user, method, url, body) {
// we need to directly sign the body since oauth node does not do this for us.
function buildRequest(credentials, user, method, url, body) {
body = JSON.stringify(body || '');
var queryParams = oauth._prepareParameters(
null, // no tokens in 2 legged oauth
null, // ^
method,
url,
/**
*/
{
// future book keeping for treeherder not sure what it's going to be used
// for...
user: user,
// node oauth does not provide body hasing but its easy to do so... its
// always sha1 as far as I can tell (at least the server only cares about
// sha1)
oauth_body_hash: crypto.createHash('sha1').update(body).digest('base64'),
// per http://tools.ietf.org/html/rfc5849#section-2.1 it must be empty if
// not used to indicate two legged oauth...
oauth_token: ''
}
);
var payload = {
credentials: credentials,
contentType: 'application/json',
payload: utf8.encode(body)
};
var header = hawk.client.header(url, method.toUpperCase(), payload);
var req = request(method, url).
set('Content-Type', 'application/json').
set('Authorization', header.field).
send(body);
// map the query parameters in order into an object
var query = {};
queryParams.reduce(function(result, value) {
result[value[0]] = value[1];
return result;
}, query);
req.query(query);
// return a promise for the result...
return req.end();
}
@ -124,8 +98,8 @@ var project = new Project('gaia', {
@param {String} project name.
@param {Object} config for project.
@param {String} config.consumerKey for oauth.
@param {String} config.consumerSecret also for oauth.
@param {String} config.clientId for hawk.
@param {String} config.secret also for hawk.
@param {Number} [config.throttleRetries=0]
@constructor
@alias module:mozilla-treeherder/project
@ -139,46 +113,36 @@ function Project(project, config) {
this.url = url + 'project/' + project + '/';
this.throttleRetries = config.throttleRetries || 0;
// generally oauth is only required for posting so don't require it for all
// generally authenticated requests are only required for posting so don't require it for all
// requests...
if (
config &&
config.consumerKey &&
config.consumerSecret
) {
// https://github.com/ciaranj/node-oauth/blob/171e668f386a3e1ba0bcb915b8dc7fdc9335aa62/lib/oauth.js#L9
this.oauth = new OAuth(
null, // 2 legged oauth has no urls
null, // ^
config.consumerKey, // per project key
config.consumerSecret, // per project secret
'1.0', // oauth version
null, // no callbacks in 2 legged oauth
'HMAC-SHA1' // signature type expected by the treeherder server.
);
if ( config && config.clientId && config.secret) {
this.credentials = {
id: config.clientId,
key: config.secret,
algorithm: 'sha256'
};
}
}
Project.prototype = {
/**
Issue a project specific api request with oauth credentials.
Issue a project specific api request with hawk credentials.
@param {String} method http method type.
@param {String} path the subpath in the project.
@param {Object} body of the http request.
@return {Promise<Object>}
*/
oauthRequest: function(method, path, body) {
authRequest: function(method, path, body) {
return new Promise(function(accept, reject) {
if (!this.oauth) {
if (!this.credentials) {
return reject(
new Error('Cannot issue secured request without consumerKey and consumerSecret')
new Error('Cannot issue secured request without client ID and secret')
);
}
buildRequest(
this.oauth,
this.credentials,
this.user,
method,
this.url + path,
@ -246,7 +210,7 @@ Project.prototype = {
@return {Promise<Object>}
*/
postResultset: throttleDecorator(function(resultset) {
return this.oauthRequest('POST', 'resultset/', resultset).then(handleResponse);
return this.authRequest('POST', 'resultset/', resultset).then(handleResponse);
}),
/**
@ -290,7 +254,7 @@ Project.prototype = {
@see http://treeherder-dev.allizom.org/docs/#!/project/Jobs_post_4
*/
postJobs: throttleDecorator(function(jobs) {
return this.oauthRequest('POST', 'jobs/', jobs).then(handleResponse);
return this.authRequest('POST', 'jobs/', jobs).then(handleResponse);
})
};

Просмотреть файл

@ -16,8 +16,6 @@ suite('project', function() {
}
function buildNock(path) {
// remove the oauth credentials (we can't really verify this works 100%
// anyway...)
return nock(subject.url).filteringPath(/\?(.*)/, '');
}
@ -30,9 +28,11 @@ suite('project', function() {
});
setup(function() {
// NOTE: This does not test against a live treeherder instance, so credentials
// are merely for testing logic
subject = new Project(PROJECT_NAME, {
consumerKey: '3d3809b2-f656-4e24-ac10-3590e5cc4214',
consumerSecret: 'e5dfb0b2-6559-4216-864b-bb87b51b4e10'
clientId: '3d3809b2-f656-4e24-ac10-3590e5cc4214',
secret: 'e5dfb0b2-6559-4216-864b-bb87b51b4e10'
});
});
@ -149,7 +149,7 @@ suite('project', function() {
});
});
test('attempt to issue post without oauth', function() {
test('attempt to issue post without credentials', function() {
var subject = new Project(PROJECT_NAME, {});
return subject.postResultset().catch(function(err) {