diff --git a/lib/common/connection.js b/lib/common/connection.js index 4fdd46e4678e..a943b66c1c37 100644 --- a/lib/common/connection.js +++ b/lib/common/connection.js @@ -36,6 +36,12 @@ var METADATA_TOKEN_URL = /** @const {object} gcloud-node's package.json file. */ var PKG = require('../../package.json'); +/** @const {array} Required properties for a complete `credentials` object. */ +var REQUIRED_CREDENTIALS = [ + 'client_email', + 'private_key' +]; + /** @const {string} User agent. */ var USER_AGENT = 'gcloud-node/' + PKG.version; @@ -75,8 +81,13 @@ module.exports.Token = Token; * Create a connection object. * * @param {object} opts - Configuration options. - * @param {array} opts.scopes - Scopes required for access. - * @param {object} opts.credentials - Credentials object. + * @param {array=} opts.scopes - Scopes required for access. + * @param {string=} opts.keyFilename - Full path to the JSON key downloaded + * from the Google Developers Console. Alternatively, you may provide a + * `credentials` object. + * @param {object=} opts.credentials - Credentials object. + * @param {string} opts.credentials.client_email + * @param {string} opts.credentials.private_key * * @example * var SCOPES = [ @@ -95,9 +106,16 @@ function Connection(opts) { this.isConnecting = false; this.waitQueue = []; - if (opts.credentials && opts.credentials.private_key && - opts.credentials.client_email) { - this.credentials = opts.credentials; + if (opts.credentials) { + var hasRequiredProperties = REQUIRED_CREDENTIALS.every(function(cred) { + return !!opts.credentials[cred]; + }); + if (hasRequiredProperties) { + this.credentials = opts.credentials; + } else { + throw new Error('A credentials object must contain the following keys: ' + + REQUIRED_CREDENTIALS.join(' ')); + } } } diff --git a/test/common/connection.js b/test/common/connection.js index 6cf34e0850eb..73e903982f8c 100644 --- a/test/common/connection.js +++ b/test/common/connection.js @@ -45,13 +45,24 @@ describe('Connection', function() { }); }); - it('should accept and assign credentials object', function() { - var credConnection = new connection.Connection({ - credentials: privateKeyFileJson + describe('credentials object', function() { + it('should accept and assign a complete credentials object', function() { + var credConnection = new connection.Connection({ + credentials: privateKeyFileJson + }); + assert.deepEqual(credConnection.credentials, privateKeyFileJson); + }); + + it('should reject an incomplete credentials object', function() { + assert.throws(function() { + new connection.Connection({ + credentials: {} + }); + }, /must contain/); }); - assert.deepEqual(credConnection.credentials, privateKeyFileJson); }); + describe('Token', function() { var tokenNeverExpires = new connection.Token('token', new Date(3000, 0, 0)); var tokenExpired = new connection.Token('token', new Date(2011, 0, 0));