Skip to content

Commit ce02aa8

Browse files
committed
feat: enable reading credentials from ibm-credentials.env file
1 parent 0354c5b commit ce02aa8

7 files changed

Lines changed: 2379 additions & 2224 deletions

File tree

lib/base_service.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import semver = require('semver');
2323
import vcapServices = require('vcap_services');
2424
import { IamTokenManagerV1 } from '../iam-token-manager/v1';
2525
import { stripTrailingSlash } from './helper';
26+
import { readCredentialsFile } from './read-credentials-file';
2627
import { sendRequest } from './requestwrapper';
2728

2829
// custom interfaces
@@ -308,7 +309,8 @@ export class BaseService {
308309
_options = extend(
309310
{},
310311
this.getCredentialsFromBluemix(this.name),
311-
this.getCredentialsFromEnvironment(this.name),
312+
this.getCredentialsFromEnvironment(process.env, this.name),
313+
this.getCredentialsFromEnvironment(readCredentialsFile(), this.name),
312314
options,
313315
_options
314316
);
@@ -352,24 +354,24 @@ export class BaseService {
352354
* @param {string} name - the service snake case name
353355
* @returns {Credentials}
354356
*/
355-
private getCredentialsFromEnvironment(name: string): Credentials {
357+
private getCredentialsFromEnvironment(envObj: any, name: string): Credentials {
356358
if (name === 'watson_vision_combined') {
357-
return this.getCredentialsFromEnvironment('visual_recognition');
359+
return this.getCredentialsFromEnvironment(envObj, 'visual_recognition');
358360
}
359361
// Case handling for assistant - should look for assistant env variables before conversation
360-
if (name === 'conversation' && (process.env[`ASSISTANT_USERNAME`] || process.env[`ASSISTANT_IAM_APIKEY`])) {
361-
return this.getCredentialsFromEnvironment('assistant');
362+
if (name === 'conversation' && (envObj[`ASSISTANT_USERNAME`] || envObj[`ASSISTANT_IAM_APIKEY`])) {
363+
return this.getCredentialsFromEnvironment(envObj, 'assistant');
362364
}
363365
const _name: string = name.toUpperCase();
364366
// https://github.com/watson-developer-cloud/node-sdk/issues/605
365367
const nameWithUnderscore: string = _name.replace(/-/g, '_');
366-
const username: string = process.env[`${_name}_USERNAME`] || process.env[`${nameWithUnderscore}_USERNAME`];
367-
const password: string = process.env[`${_name}_PASSWORD`] || process.env[`${nameWithUnderscore}_PASSWORD`];
368-
const apiKey: string = process.env[`${_name}_API_KEY`] || process.env[`${nameWithUnderscore}_API_KEY`];
369-
const url: string = process.env[`${_name}_URL`] || process.env[`${nameWithUnderscore}_URL`];
370-
const iamAccessToken: string = process.env[`${_name}_IAM_ACCESS_TOKEN`] || process.env[`${nameWithUnderscore}_IAM_ACCESS_TOKEN`];
371-
const iamApiKey: string = process.env[`${_name}_IAM_APIKEY`] || process.env[`${nameWithUnderscore}_IAM_APIKEY`];
372-
const iamUrl: string = process.env[`${_name}_IAM_URL`] || process.env[`${nameWithUnderscore}_IAM_URL`];
368+
const username: string = envObj[`${_name}_USERNAME`] || envObj[`${nameWithUnderscore}_USERNAME`];
369+
const password: string = envObj[`${_name}_PASSWORD`] || envObj[`${nameWithUnderscore}_PASSWORD`];
370+
const apiKey: string = envObj[`${_name}_API_KEY`] || envObj[`${nameWithUnderscore}_API_KEY`];
371+
const url: string = envObj[`${_name}_URL`] || envObj[`${nameWithUnderscore}_URL`];
372+
const iamAccessToken: string = envObj[`${_name}_IAM_ACCESS_TOKEN`] || envObj[`${nameWithUnderscore}_IAM_ACCESS_TOKEN`];
373+
const iamApiKey: string = envObj[`${_name}_IAM_APIKEY`] || envObj[`${nameWithUnderscore}_IAM_APIKEY`];
374+
const iamUrl: string = envObj[`${_name}_IAM_URL`] || envObj[`${nameWithUnderscore}_IAM_URL`];
373375

374376
return {
375377
username,

lib/read-credentials-file.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import dotenv = require('dotenv');
2+
import fs = require('fs');
3+
import os = require('os');
4+
import path = require('path');
5+
6+
const filename: string = 'ibm-credentials.env';
7+
8+
export function readCredentialsFile() {
9+
// first look for an env variable called IBM_CREDENTIALS_FILE
10+
// it should be the path to the file
11+
12+
const givenFilepath: string = process.env['IBM_CREDENTIALS_FILE'] || '';
13+
const homeDir: string = os.homedir();
14+
const workingDir: string = process.cwd();
15+
16+
let filepathToUse: string;
17+
18+
if (givenFilepath && fileExistsAtPath(givenFilepath)) {
19+
filepathToUse = givenFilepath;
20+
} else if (fileExistsAtPath(homeDir)) {
21+
filepathToUse = homeDir;
22+
} else if (fileExistsAtPath(workingDir)) {
23+
filepathToUse = workingDir;
24+
} else {
25+
// file does not exist anywhere, will not be used
26+
return {};
27+
}
28+
29+
const credsFile = fs.readFileSync(constructFilepath(filepathToUse));
30+
31+
return dotenv.parse(credsFile);
32+
}
33+
34+
export function fileExistsAtPath(filepath): boolean {
35+
filepath = constructFilepath(filepath);
36+
return fs.existsSync(filepath);
37+
}
38+
39+
export function constructFilepath(filepath): string {
40+
// ensure filepath includes the filename
41+
if (!filepath.endsWith(filename)) {
42+
filepath = path.join(filepath, filename);
43+
}
44+
45+
return filepath;
46+
}

0 commit comments

Comments
 (0)