From 9ab8488a048791cb59f1d686eb0c6c01844548ec Mon Sep 17 00:00:00 2001 From: Stephen Sawchuk Date: Wed, 17 Sep 2014 11:26:28 -0400 Subject: [PATCH] fix(connection): set token expiration date for GCE A response from the GCE metadata server responds with data in a different format from that of the GAPIToken() request. Instead of looking for a property that doesn't exist `token_expires`, we now calculate the expiration timestamp from `expires_in`. For more, see [Authenticating from Google Compute Engine][auth]. [auth]:https://developers.google.com/compute/docs/authentication#applications Fixes #212 --- lib/common/connection.js | 2 +- test/common/connection.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/common/connection.js b/lib/common/connection.js index 41470241cbae..7244a286b38f 100644 --- a/lib/common/connection.js +++ b/lib/common/connection.js @@ -165,7 +165,7 @@ Connection.prototype.fetchToken = function(callback) { callback(err); return; } - var exp = new Date(body.token_expires * 1000); + var exp = new Date(Date.now() + body.expires_in * 1000); callback(null, new Token(body.access_token, exp)); }); return; diff --git a/test/common/connection.js b/test/common/connection.js index 97740ff8bc8b..0c1a73c95ba5 100644 --- a/test/common/connection.js +++ b/test/common/connection.js @@ -98,6 +98,41 @@ describe('Connection', function() { var tokenNeverExpires = new connection.Token('token', new Date(3000, 0, 0)); var tokenExpired = new connection.Token('token', new Date(2011, 0, 0)); + describe('GCE', function() { + var gceConn; + var metadataResponse = { + body: { + access_token: 'y.8', + expires_in: 60 + } + }; + + beforeEach(function() { + gceConn = new connection.Connection(); + }); + + it('should fetch a token from the metadata server', function() { + gceConn.requester = function(opts) { + assert.equal(opts.uri.indexOf('http://metadata/'), 0); + }; + gceConn.fetchToken(); + }); + + it('should build token from metadata\'s response', function() { + gceConn.requester = function(opts, callback) { + callback(null, metadataResponse, metadataResponse.body); + }; + gceConn.fetchToken(function(err, token) { + assert.ifError(err); + assert(token instanceof connection.Token); + assert.equal(token.accessToken, metadataResponse.body.access_token); + var addedMs = metadataResponse.body.expires_in * 1000; + var tokenDate = new Date(Date.now() + addedMs); + assert.equal(token.expiry.getTime(), tokenDate.getTime()); + }); + }); + }); + it('should fetch a new token if token expires', function(done) { conn.token = tokenExpired; conn.fetchToken = function() {