Skip to content

Commit

Permalink
Merge pull request #39 from tbetbetbe/node-auth-correct-jwt-get-reque…
Browse files Browse the repository at this point in the history
…st-metadata

Node auth correct jwt get request metadata
  • Loading branch information
tbetbetbe committed May 21, 2015
2 parents e44071e + a44331e commit 12fd818
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 77 deletions.
34 changes: 17 additions & 17 deletions lib/auth/jwtaccess.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ JWTAccess.prototype.createScopedRequired = function() {
* Get a non-expired access token, after refreshing if necessary
*
* @param {string} authURI the URI being authorized
* @param {function} accessTokenFn a callback invoked with the access
* token.
* @param {function} metadataCb a callback invoked with the jwt
* request metadata.
*/
JWTAccess.prototype.getRequestMetadata = function(authURI, accessTokenFn) {
JWTAccess.prototype.getRequestMetadata = function(authURI, metadataCb) {
var iat = Math.floor(new Date().getTime() / 1000);
var exp = iat + 3600; // 3600 seconds = 1 hour

Expand All @@ -75,12 +75,12 @@ JWTAccess.prototype.getRequestMetadata = function(authURI, accessTokenFn) {
secret: this.key
};

// Sign the jwt and invoke accessTokenFn with it.
this._signJWT(assertion, function(err, signedJWT) {
// Sign the jwt and invoke metadataCb with it.
return this._signJWT(assertion, function(err, signedJWT) {
if (!err) {
accessTokenFn(null, {'Authorization': 'Bearer ' + signedJWT});
return metadataCb(null, {'Authorization': 'Bearer ' + signedJWT});
} else {
accessTokenFn(err, null);
return metadataCb(err, null);
}
});
};
Expand All @@ -92,26 +92,26 @@ JWTAccess.prototype.getRequestMetadata = function(authURI, accessTokenFn) {
*/
JWTAccess.prototype.fromJSON = function(json, opt_callback) {
var that = this;
var callback = opt_callback || noop;
var done = opt_callback || noop;
if (!json) {
callback(new Error(
done(new Error(
'Must pass in a JSON object containing the service account auth settings.'));
return;
}
if (!json.client_email) {
callback(new Error(
done(new Error(
'The incoming JSON object does not contain a client_email field'));
return;
}
if (!json.private_key) {
callback(new Error(
done(new Error(
'The incoming JSON object does not contain a private_key field'));
return;
}
// Extract the relevant information from the json key file.
that.email = json.client_email;
that.key = json.private_key;
callback();
done();
};

/**
Expand All @@ -121,10 +121,10 @@ JWTAccess.prototype.fromJSON = function(json, opt_callback) {
*/
JWTAccess.prototype.fromStream = function(stream, opt_callback) {
var that = this;
var callback = opt_callback || noop;
var done = opt_callback || noop;
if (!stream) {
process.nextTick(function() {
callback(
done(
new Error('Must pass in a stream containing the service account auth settings.'));
});
return;
Expand All @@ -139,7 +139,7 @@ JWTAccess.prototype.fromStream = function(stream, opt_callback) {
var data = JSON.parse(s);
that.fromJSON(data, opt_callback);
} catch (err) {
callback(err);
done(err);
}
});
};
Expand All @@ -155,9 +155,9 @@ JWTAccess.prototype.fromStream = function(stream, opt_callback) {
*/
JWTAccess.prototype._signJWT = function(assertion, signedJwtFn) {
try {
signedJwtFn(null, jws.sign(assertion));
return signedJwtFn(null, jws.sign(assertion));
} catch (err) {
signedJwtFn(err);
return signedJwtFn(err);
}
};

Expand Down
52 changes: 26 additions & 26 deletions lib/auth/jwtclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
var Auth2Client = require('./oauth2client.js');
var gToken = require('gtoken');
var JWTAccess = require('./jwtaccess.js');
var noop = require('lodash.noop');
var util = require('util');


/**
* JWT service account credentials.
*
Expand Down Expand Up @@ -53,13 +55,6 @@ function JWT(email, keyFile, key, scopes, subject) {
*/
util.inherits(JWT, Auth2Client);

// Executes the given callback if it is not null.
function callback(c, err, res) {
if (c) {
c(err, res);
}
}

/**
* Creates a copy of the credential with the specified scopes.
* @param {(string|array)=} scopes List of requested scopes or a single scope.
Expand All @@ -73,16 +68,16 @@ JWT.prototype.createScoped = function(scopes) {
* Obtains the metadata to be sent with the request.
*
* @param {string} opt_uri the URI being authorized.
* @param {function} cb_with_metadata
* @param {function} metadataCb
*/
JWT.prototype.getRequestMetadata = function(opt_uri, cb_with_metadata) {
JWT.prototype.getRequestMetadata = function(opt_uri, metadataCb) {
if (this.createScopedRequired() && opt_uri) {
// no scopes have been set, but a uri has been provided. Use JWTAccess credentials.
var alt = new JWTAccess(this.email, this.key);
alt.getRequestMetadata(opt_uri, cb_with_metadata);
return alt.getRequestMetadata(opt_uri, metadataCb);
} else {
JWT.super_.prototype.getRequestMetadata.call(
this, opt_uri, cb_with_metadata);
return JWT.super_.prototype.getRequestMetadata.call(
this, opt_uri, metadataCb);
}
};

Expand Down Expand Up @@ -112,6 +107,7 @@ JWT.prototype.createScopedRequired = function() {
*/
JWT.prototype.authorize = function(opt_callback) {
var that = this;
var done = opt_callback || noop;

that.refreshToken_(null, function(err, result) {
if (!err) {
Expand All @@ -120,7 +116,7 @@ JWT.prototype.authorize = function(opt_callback) {
that.key = that.gtoken.key;
that.email = that.gtoken.iss;
}
callback(opt_callback, err, result);
done(err, result);
});
};

Expand All @@ -132,12 +128,14 @@ JWT.prototype.authorize = function(opt_callback) {
* @private
*/
JWT.prototype.refreshToken_ = function(ignored_, opt_callback) {
this._createGToken(function(err, gToken) {
var done = opt_callback || noop;

return this._createGToken(function(err, gToken) {
if (err) {
callback(opt_callback, err);
return done(err);
} else {
gToken.getToken(function (err, token) {
callback(opt_callback, err, {
return gToken.getToken(function (err, token) {
return done(err, {
access_token: token,
token_type: 'Bearer',
expiry_date: gToken.expires_at
Expand All @@ -155,25 +153,26 @@ JWT.prototype.refreshToken_ = function(ignored_, opt_callback) {
*/
JWT.prototype.fromJSON = function(json, opt_callback) {
var that = this;
var done = opt_callback || noop;
if (!json) {
callback(opt_callback, new Error(
done(new Error(
'Must pass in a JSON object containing the service account auth settings.'));
return;
}
if (!json.client_email) {
callback(opt_callback, new Error(
done(new Error(
'The incoming JSON object does not contain a client_email field'));
return;
}
if (!json.private_key) {
callback(opt_callback, new Error(
done(new Error(
'The incoming JSON object does not contain a private_key field'));
return;
}
// Extract the relevant information from the json key file.
that.email = json.client_email;
that.key = json.private_key;
callback(opt_callback);
done();
};

/**
Expand All @@ -183,10 +182,11 @@ JWT.prototype.fromJSON = function(json, opt_callback) {
*/
JWT.prototype.fromStream = function(stream, opt_callback) {
var that = this;
var done = opt_callback || noop;

if (!stream) {
process.nextTick(function() {
callback(
opt_callback,
done(
new Error('Must pass in a stream containing the service account auth settings.'));
});
return;
Expand All @@ -201,7 +201,7 @@ JWT.prototype.fromStream = function(stream, opt_callback) {
var data = JSON.parse(s);
that.fromJSON(data, opt_callback);
} catch (err) {
callback(opt_callback, err);
done(err);
}
});
};
Expand All @@ -213,7 +213,7 @@ JWT.prototype.fromStream = function(stream, opt_callback) {
*/
JWT.prototype._createGToken = function(callback) {
if (this.gtoken) {
callback(null, this.gtoken);
return callback(null, this.gtoken);
} else {
this.gtoken = this.gToken({
iss: this.email,
Expand All @@ -222,7 +222,7 @@ JWT.prototype._createGToken = function(callback) {
keyFile: this.keyFile,
key: this.key
});
callback(null, this.gtoken);
return callback(null, this.gtoken);
}
};

Expand Down
47 changes: 23 additions & 24 deletions lib/auth/oauth2client.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@

'use strict';

var querystring = require('querystring');
var AuthClient = require('./authclient.js');
var util = require('util');
var PemVerifier = require('./../pemverifier.js');
var LoginTicket = require('./loginticket.js');
var noop = require('lodash.noop');
var PemVerifier = require('./../pemverifier.js');
var querystring = require('querystring');
var util = require('util');

var certificateCache = null;
var certificateExpiry = null;
Expand Down Expand Up @@ -149,9 +150,8 @@ OAuth2Client.prototype.getToken = function(code, opt_callback) {
tokens.expiry_date = ((new Date()).getTime() + (tokens.expires_in * 1000));
delete tokens.expires_in;
}
if (opt_callback) {
opt_callback(err, tokens, response);
}
var done = opt_callback || noop;
done(err, tokens, response);
});
};

Expand All @@ -171,7 +171,7 @@ OAuth2Client.prototype.refreshToken_ = function(refresh_token, opt_callback) {
};

// request for new token
this.transporter.request({
return this.transporter.request({
method: 'POST',
uri: uri,
form: values,
Expand All @@ -181,9 +181,8 @@ OAuth2Client.prototype.refreshToken_ = function(refresh_token, opt_callback) {
tokens.expiry_date = ((new Date()).getTime() + (tokens.expires_in * 1000));
delete tokens.expires_in;
}
if (opt_callback) {
opt_callback(err, tokens, response);
}
var done = opt_callback || noop;
done(err, tokens, response);
});
};

Expand Down Expand Up @@ -262,14 +261,14 @@ OAuth2Client.prototype.getAccessToken = function(callback) {
* {Authorization: 'Bearer <access_token_value>'}
*
* @param {string} opt_uri the Uri being authorized
* @param {function} cb_with_metadata the func described above
* @param {function} metadataCb the func described above
*/
OAuth2Client.prototype.getRequestMetadata = function(opt_uri, cb_with_metadata) {
OAuth2Client.prototype.getRequestMetadata = function(opt_uri, metadataCb) {
var that = this;
var thisCreds = this.credentials;

if (!thisCreds.access_token && !thisCreds.refresh_token) {
return cb_with_metadata(new Error('No access or refresh token is set.'), null);
return metadataCb(new Error('No access or refresh token is set.'), null);
}

// if no expiry time, assume it's not expired
Expand All @@ -279,23 +278,23 @@ OAuth2Client.prototype.getRequestMetadata = function(opt_uri, cb_with_metadata)
if (thisCreds.access_token && !isTokenExpired) {
thisCreds.token_type = thisCreds.token_type || 'Bearer';
var headers = {'Authorization': thisCreds.token_type + ' ' + thisCreds.access_token };
return cb_with_metadata(null, headers , null);
return metadataCb(null, headers , null);
}

this.refreshToken_(thisCreds.refresh_token, function(err, tokens, response) {
return this.refreshToken_(thisCreds.refresh_token, function(err, tokens, response) {
if (err) {
cb_with_metadata(err, null, response);
return metadataCb(err, null, response);
} else {
if (!tokens || (tokens && !tokens.access_token)) {
return cb_with_metadata(new Error('Could not refresh access token.'), null, response);
return metadataCb(new Error('Could not refresh access token.'), null, response);
}

var credentials = that.credentials;
credentials.token_type = credentials.token_type || 'Bearer';
tokens.refresh_token = credentials.refresh_token;
that.credentials = tokens;
var headers = {'Authorization': credentials.token_type + ' ' + tokens.access_token };
cb_with_metadata(null, headers , response);
return metadataCb(err, headers , response);
}
});
};
Expand Down Expand Up @@ -340,23 +339,23 @@ OAuth2Client.prototype.request = function(opts, callback) {
var that = this;

// Hook the callback routine to call the _postRequest method.
var my_callback = function(e, b, r) {
that._postRequest(e, b, r, callback);
var postRequestCb = function(err, body, resp) {
that._postRequest(err, body, resp, callback);
};

var cb_with_auth = function(err, headers, response) {
var authCb = function(err, headers, response) {
if (err) {
my_callback(err, null, response);
postRequestCb(err, null, response);
} else {
if (headers) {
opts.headers = opts.headers || {};
opts.headers.Authorization = headers.Authorization;
}
return that._makeRequest(opts, my_callback);
return that._makeRequest(opts, postRequestCb);
}
};
var unusedUri = null;
return this.getRequestMetadata(unusedUri, cb_with_auth);
return this.getRequestMetadata(unusedUri, authCb);
};

/**
Expand Down
Loading

0 comments on commit 12fd818

Please sign in to comment.