Skip to content

Commit 2daf856

Browse files
committed
Load credentials file from path specified in AWS_SHARED_CREDENTIALS_FILE if AWS_SDK_LOAD_CONFIG is set
1 parent b480c5f commit 2daf856

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"type": "feature",
33
"category": "EnvironmentVariable",
4-
"description": "Add AWS_CREDENTIAL_PROFILES_FILE Environment Variable as defined in the Java AWS_SDK"
5-
}
4+
"description": "Add support for the AWS_SHARED_CREDENTIALS_FILE environment variable if AWS_SDK_LOAD_CONFIG is set"
5+
}

lib/credentials/shared_ini_file_credentials.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ var AWS = require('../core');
22
var path = require('path');
33
var STS = require('../../clients/sts');
44

5+
var configOptInEnv = 'AWS_SDK_LOAD_CONFIG';
6+
var defaultProfile = 'default';
7+
58
/**
69
* Represents credentials loaded from shared credentials file
710
* (defaulting to ~/.aws/credentials or defined by the
@@ -52,9 +55,9 @@ AWS.SharedIniFileCredentials = AWS.util.inherit(AWS.Credentials, {
5255

5356
options = options || {};
5457

55-
this.filename = options.filename || process.env.AWS_CREDENTIAL_PROFILES_FILE;
56-
this.profile = options.profile || process.env.AWS_PROFILE || 'default';
57-
this.disableAssumeRole = !!options.disableAssumeRole;
58+
this.filename = options.filename;
59+
this.profile = options.profile || process.env.AWS_PROFILE || defaultProfile;
60+
this.disableAssumeRole = Boolean(options.disableAssumeRole);
5861
this.get(function() {});
5962
},
6063

@@ -73,10 +76,18 @@ AWS.SharedIniFileCredentials = AWS.util.inherit(AWS.Credentials, {
7376
if (!callback) callback = function(err) { if (err) throw err; };
7477
try {
7578
if (!this.filename) this.loadDefaultFilename();
79+
var profile = {};
80+
if (process.env[configOptInEnv]) {
81+
var configProfileName = this.profile === defaultProfile ?
82+
'default' : 'profile ' + this.profile;
83+
var config = AWS.util.ini
84+
.parse(AWS.util.readFileSync(this.configFilename));
85+
profile = AWS.util.merge(profile, config[configProfileName]);
86+
}
7687
var creds = AWS.util.ini.parse(AWS.util.readFileSync(this.filename));
77-
var profile = creds[this.profile];
88+
profile = AWS.util.merge(profile, creds[this.profile]);
7889

79-
if (typeof profile !== 'object') {
90+
if (Object.keys(profile).length === 0) {
8091
throw AWS.util.error(
8192
new Error('Profile ' + this.profile + ' not found in ' + this.filename),
8293
{ code: 'SharedIniFileCredentialsProviderFailure' }
@@ -193,6 +204,7 @@ AWS.SharedIniFileCredentials = AWS.util.inherit(AWS.Credentials, {
193204
*/
194205
loadDefaultFilename: function loadDefaultFilename() {
195206
var env = process.env;
207+
196208
var home = env.HOME ||
197209
env.USERPROFILE ||
198210
(env.HOMEPATH ? ((env.HOMEDRIVE || 'C:/') + env.HOMEPATH) : null);
@@ -204,5 +216,11 @@ AWS.SharedIniFileCredentials = AWS.util.inherit(AWS.Credentials, {
204216
}
205217

206218
this.filename = path.join(home, '.aws', 'credentials');
219+
220+
if (env[configOptInEnv]) {
221+
this.filename = env.AWS_SHARED_CREDENTIALS_FILE || this.filename;
222+
this.configFilename = env.AWS_CONFIG_FILE ||
223+
path.join(home, '.aws', 'config');
224+
}
207225
}
208226
});

test/credentials.spec.coffee

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ if AWS.util.isNode()
158158
describe 'AWS.SharedIniFileCredentials', ->
159159
beforeEach ->
160160
delete process.env.AWS_PROFILE
161-
delete process.env.AWS_CREDENTIAL_PROFILES_FILE
161+
delete process.env.AWS_SDK_LOAD_CONFIG
162+
delete process.env.AWS_SHARED_CREDENTIALS_FILE
162163
delete process.env.HOME
163164
delete process.env.HOMEPATH
164165
delete process.env.HOMEDRIVE
@@ -210,8 +211,9 @@ if AWS.util.isNode()
210211
validateCredentials(creds)
211212
expect(AWS.util.readFileSync.calls[0].arguments[0]).to.match(/[\/\\]home[\/\\]user[\/\\].aws[\/\\]credentials/)
212213

213-
it 'loads credentials from path defined in AWS_CREDENTIAL_PROFILES_FILE', ->
214-
process.env.AWS_CREDENTIAL_PROFILES_FILE = '/path/to/aws/credentials'
214+
it 'loads credentials from path defined in AWS_SHARED_CREDENTIALS_FILE if AWS_SDK_LOAD_CONFIG is set', ->
215+
process.env.AWS_SDK_LOAD_CONFIG = '1'
216+
process.env.AWS_SHARED_CREDENTIALS_FILE = '/path/to/aws/credentials'
215217
mock = '''
216218
[default]
217219
aws_access_key_id = akid
@@ -223,7 +225,23 @@ if AWS.util.isNode()
223225
creds = new AWS.SharedIniFileCredentials()
224226
creds.get();
225227
validateCredentials(creds)
226-
expect(AWS.util.readFileSync.calls[0].arguments[0]).to.equal('/path/to/aws/credentials')
228+
expect(AWS.util.readFileSync.calls[0].arguments[0]).to.match(/[\/\\]home[\/\\]user[\/\\].aws[\/\\]config/)
229+
expect(AWS.util.readFileSync.calls[1].arguments[0]).to.equal(process.env.AWS_SHARED_CREDENTIALS_FILE)
230+
231+
it 'loads credentials from ~/.aws/credentials if AWS_SDK_LOAD_CONFIG is not set', ->
232+
process.env.AWS_SHARED_CREDENTIALS_FILE = '/path/to/aws/credentials'
233+
mock = '''
234+
[default]
235+
aws_access_key_id = akid
236+
aws_secret_access_key = secret
237+
aws_session_token = session
238+
'''
239+
helpers.spyOn(AWS.util, 'readFileSync').andReturn(mock)
240+
241+
creds = new AWS.SharedIniFileCredentials()
242+
creds.get();
243+
validateCredentials(creds)
244+
expect(AWS.util.readFileSync.calls[0].arguments[0]).to.match(/[\/\\]home[\/\\]user[\/\\].aws[\/\\]credentials/)
227245

228246
it 'loads the default profile if AWS_PROFILE is empty', ->
229247
process.env.AWS_PROFILE = ''

0 commit comments

Comments
 (0)