Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow iam client id and secret to be read from constructor #17

Merged
merged 2 commits into from
Apr 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions iam-token-manager/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@
import extend = require('extend');
import { sendRequest } from '../lib/requestwrapper';

/**
* Check for only one of two elements being defined.
* Returns true if a is defined and b is undefined,
* or vice versa. Returns false if both are defined
* or both are undefined.
*
* @param {any} a - The first object
* @param {any} b - The second object
* @returns {boolean}
*/
function onlyOne(a: any, b: any): boolean {
return Boolean((a && !b) || (b && !a));
}

const CLIENT_ID_SECRET_WARNING = 'Warning: Client ID and Secret must BOTH be given, or the defaults will be used.';

export type Options = {
iamApikey?: string;
iamAccessToken?: string;
Expand Down Expand Up @@ -72,6 +88,10 @@ export class IamTokenManagerV1 {
if (options.iamSecret) {
this.iamSecret = options.iamSecret;
}
if (onlyOne(options.iamClientId, options.iamSecret)) {
// tslint:disable-next-line
console.log(CLIENT_ID_SECRET_WARNING);
}
}

/**
Expand Down Expand Up @@ -120,6 +140,10 @@ export class IamTokenManagerV1 {
public setIamAuthorizationInfo(iamClientId: string, iamSecret: string): void {
this.iamClientId = iamClientId;
this.iamSecret = iamSecret;
if (onlyOne(iamClientId, iamSecret)) {
// tslint:disable-next-line
console.log(CLIENT_ID_SECRET_WARNING);
}
}

/**
Expand Down
15 changes: 13 additions & 2 deletions lib/base_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export interface UserOptions {
iam_access_token?: string;
iam_apikey?: string;
iam_url?: string;
iam_client_id?: string;
iam_secret?: string;
disable_ssl_verification?: boolean;
}

Expand Down Expand Up @@ -121,6 +123,11 @@ export class BaseService {
/**
* Internal base class that other services inherit from
* @param {UserOptions} options
* @param {string} [options.iam_apikey] - api key used to retrieve an iam access token
* @param {string} [options.iam_access_token] - iam access token provided and managed by user
* @param {string} [options.iam_url] - url for iam service api, needed for services in staging
* @param {string} [options.iam_client_id] - client id (username) for request to iam service
* @param {string} [options.iam_secret] - secret (password) for request to iam service
* @param {string} [options.username] - required unless use_unauthenticated is set
* @param {string} [options.password] - required unless use_unauthenticated is set
* @param {boolean} [options.use_unauthenticated] - skip credential requirement
Expand Down Expand Up @@ -158,12 +165,16 @@ export class BaseService {
this.tokenManager = new IamTokenManagerV1({
iamApikey: _options.iam_apikey,
iamAccessToken: _options.iam_access_token,
iamUrl: _options.iam_url
iamUrl: _options.iam_url,
iamClientId: _options.iam_client_id,
iamSecret: _options.iam_secret
});
} else if (usesBasicForIam(_options)) {
this.tokenManager = new IamTokenManagerV1({
iamApikey: _options.password,
iamUrl: _options.iam_url
iamUrl: _options.iam_url,
iamClientId: _options.iam_client_id,
iamSecret: _options.iam_secret
});
} else {
this.tokenManager = null;
Expand Down
35 changes: 35 additions & 0 deletions test/unit/baseService.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,41 @@ describe('BaseService', function() {
});
});

it('should pass all credentials to token manager when given iam creds', function() {
const instance = new TestService({
iam_apikey: 'key1234',
iam_access_token: 'real-token-84',
iam_url: 'iam.com/api',
iam_client_id: 'abc',
iam_secret: 'abc',
});

expect(instance.tokenManager).toBeDefined();
expect(instance.tokenManager).not.toBeNull();
expect(instance.tokenManager.iamApikey).toBeDefined();
expect(instance.tokenManager.userAccessToken).toBeDefined();
expect(instance.tokenManager.iamUrl).toBeDefined();
expect(instance.tokenManager.iamClientId).toBeDefined();
expect(instance.tokenManager.iamSecret).toBeDefined();
});

it('should pass all credentials to token manager when given iam with basic', function() {
const instance = new TestService({
username: 'apikey',
password: 'key1234',
iam_url: 'iam.com/api',
iam_client_id: 'abc',
iam_secret: 'abc',
});

expect(instance.tokenManager).toBeDefined();
expect(instance.tokenManager).not.toBeNull();
expect(instance.tokenManager.iamApikey).toBeDefined();
expect(instance.tokenManager.iamUrl).toBeDefined();
expect(instance.tokenManager.iamClientId).toBeDefined();
expect(instance.tokenManager.iamSecret).toBeDefined();
});

it('should not fail if setAccessToken is called and token manager is null', function() {
const instance = new TestService({ username: 'user', password: 'pass' });
expect(instance.tokenManager).toBeNull();
Expand Down
35 changes: 32 additions & 3 deletions test/unit/iamTokenManager.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
/* eslint-disable no-alert, no-console */
'use strict';

const requestWrapper = require('../../lib/requestwrapper');
requestWrapper.sendRequest = jest.fn();

const IamTokenManagerV1 = require('../../iam-token-manager/v1').IamTokenManagerV1;

const CLIENT_ID_SECRET_WARNING =
'Warning: Client ID and Secret must BOTH be given, or the defaults will be used.';

describe('iam_token_manager_v1', function() {
beforeEach(() => {
requestWrapper.sendRequest.mockReset();
Expand Down Expand Up @@ -235,11 +239,18 @@ describe('iam_token_manager_v1', function() {
});

it('should use the default Authorization header - clientid only via ctor', function(done) {
jest.spyOn(console, 'log').mockImplementation(() => {});

const instance = new IamTokenManagerV1({
iamApikey: 'abcd-1234',
iamClientId: 'foo',
});

// verify warning was triggered
expect(console.log).toHaveBeenCalled();
expect(console.log.mock.calls[0][0]).toBe(CLIENT_ID_SECRET_WARNING);
console.log.mockRestore();

requestWrapper.sendRequest.mockImplementation((parameters, _callback) => {
_callback();
});
Expand All @@ -253,11 +264,17 @@ describe('iam_token_manager_v1', function() {
});

it('should use the default Authorization header, secret only via ctor', function(done) {
jest.spyOn(console, 'log').mockImplementation(() => {});
const instance = new IamTokenManagerV1({
iamApikey: 'abcd-1234',
iamSecret: 'bar',
});

// verify warning was triggered
expect(console.log).toHaveBeenCalled();
expect(console.log.mock.calls[0][0]).toBe(CLIENT_ID_SECRET_WARNING);
console.log.mockRestore();

requestWrapper.sendRequest.mockImplementation((parameters, _callback) => {
_callback();
});
Expand Down Expand Up @@ -294,8 +311,15 @@ describe('iam_token_manager_v1', function() {
iamApikey: 'abcd-1234',
});

jest.spyOn(console, 'log').mockImplementation(() => {});

instance.setIamAuthorizationInfo('foo', null);

// verify warning was triggered
expect(console.log).toHaveBeenCalled();
expect(console.log.mock.calls[0][0]).toBe(CLIENT_ID_SECRET_WARNING);
console.log.mockRestore();

requestWrapper.sendRequest.mockImplementation((parameters, _callback) => {
_callback();
});
Expand All @@ -308,14 +332,20 @@ describe('iam_token_manager_v1', function() {
});
});

it('should use the default Authorization header, secret only via ctor', function(done) {
it('should use the default Authorization header, secret only via setter', function(done) {
const instance = new IamTokenManagerV1({
iamApikey: 'abcd-1234',
iamSecret: 'bar',
});

jest.spyOn(console, 'log').mockImplementation(() => {});

instance.setIamAuthorizationInfo(null, 'bar');

// verify warning was triggered
expect(console.log).toHaveBeenCalled();
expect(console.log.mock.calls[0][0]).toBe(CLIENT_ID_SECRET_WARNING);
console.log.mockRestore();

requestWrapper.sendRequest.mockImplementation((parameters, _callback) => {
_callback();
});
Expand All @@ -331,7 +361,6 @@ describe('iam_token_manager_v1', function() {
it('should use the default Authorization header, nulls passed to setter', function(done) {
const instance = new IamTokenManagerV1({
iamApikey: 'abcd-1234',
iamSecret: 'bar',
});

instance.setIamAuthorizationInfo(null, null);
Expand Down