Skip to content

Commit

Permalink
Merge pull request #65 from proppy/jwt
Browse files Browse the repository at this point in the history
auth: draft jwt support using gapitoken
  • Loading branch information
Burcu Dogan committed Aug 14, 2013
2 parents 9c43e2d + 8cd3265 commit 35ea229
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 1 deletion.
90 changes: 90 additions & 0 deletions lib/auth/jwtclient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Copyright 2013 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var Auth2Client = require('./oauth2client.js');
var util = require('util');
var GAPI = require('gapitoken');

/**
* @constructor
* JWT service account credentials.
*
* Retrieve access token using gapitoken.
*
* @param {string=} email service account email address.
* @param {string=} keyFile path to private key file.
* @param {array=} scopes list of requested scopes.
*
*/
function JWT(email, keyFile, scopes) {
JWT.super_.call(this);
this.email = email;
this.keyFile = keyFile;
this.scopes = scopes;
this.GAPI = GAPI;
}

/**
* Inherit from Auth2Client.
*/
util.inherits(JWT, Auth2Client);

/**
* Get the initial access token using gapitoken.
* @param {function=} opt_callback Optional callback.
*/
JWT.prototype.authorize = function(opt_callback) {
var that = this;
that.gapi = new that.GAPI({
iss: that.email,
scope: that.scopes.join(' '),
keyFile: that.keyFile
}, function(err) {
if (err) {
opt_callback && opt_callback(err, null);
} else {
that.refreshToken_(null, function(err, result) {
if (!err) {
that.credentials = result;
that.credentials.refresh_token = 'jwt-placeholder';
}
opt_callback && opt_callback(err, result);
});
}
});
};

/**
* @private
* Refreshes the access token.
* @param {object=} ignored_
* @param {function=} opt_callback Optional callback.
*/
JWT.prototype.refreshToken_ = function(ignored_, opt_callback) {
var that = this;
that.gapi.getToken(function(err, token) {
opt_callback && opt_callback(err, {
access_token: token,
token_type: 'Bearer',
expires_in: that.gapi.token_expires
});
});
};

/**
* Export Compute.
*/
module.exports = JWT;
1 change: 1 addition & 0 deletions lib/googleapis.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ googleapis.OAuth2Client = require('./auth/oauth2client.js');
*/
googleapis.auth = {
Compute: require('./auth/computeclient.js'),
JWT: require('./auth/jwtclient.js'),
OAuth2Client: googleapis.OAuth2Client
};

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
],
"dependencies" : {
"request": "~2.25.0",
"async": "0.2.6"
"async": "0.2.6",
"gapitoken": "0.0.3"
},
"devDependencies" : {
"mocha": "1.8.1",
Expand Down
71 changes: 71 additions & 0 deletions tests/test.jwt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright 2013 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var assert = require('assert');

var googleapis = require('../lib/googleapis.js');

describe('JWT auth client', function() {
it('should get an initial access token', function(done) {
var jwt = new googleapis.auth.JWT(
'foo@serviceaccount.com',
'/path/to/key.pem',
['http://bar', 'http://foo']);
jwt.GAPI = function(opts, callback) {
assert.equal('foo@serviceaccount.com', opts.iss);
assert.equal('/path/to/key.pem', opts.keyFile);
assert.equal('http://bar http://foo', opts.scope);
setTimeout(function() {
callback(null);
}, 0);
return {
getToken: function(opt_callback) {
opt_callback(null, 'initial-access-token');
}
}
};
jwt.authorize(function() {
assert.equal('initial-access-token', jwt.credentials.access_token);
assert.equal('jwt-placeholder', jwt.credentials.refresh_token);
done();
});
});
it('should refresh token when request fails', function(done) {
var jwt = new googleapis.auth.JWT(
'foo@serviceaccount.com',
'/path/to/key.pem',
['http://bar', 'http://foo']);
jwt.credentials = {
access_token: 'initial-access-token',
refresh_token: 'jwt-placeholder'
};
jwt.transporter = {
request: function(opts, opt_callback) {
opt_callback(null, null, {statusCode: 401});
}
};
jwt.refreshToken_ = function(token, callback) {
callback(null, {
'access_token': 'another-access-token',
'token_type': 'Bearer'
});
};
jwt.request({}, function() {
assert.equal('another-access-token', jwt.credentials.access_token);
done();
});
});
});

0 comments on commit 35ea229

Please sign in to comment.