Skip to content

Commit 1179efa

Browse files
authored
fix(credentials): "Connect", "Choose Profile" treat empty credentials files as usable #2965
Problem: - If ~/.aws/config exists but doesn't have a usable credentials profile, the Connect to AWS and Choose AWS Profile actions open ~/.aws/config immediately instead of starting the Create Credentials Profile wizard. Solution: - Check for `aws_access_key_id` and `aws_secret_access_key` in the credentials files to decide if any usable credentials files exist.
1 parent bb0c9cc commit 1179efa

File tree

4 files changed

+51
-24
lines changed

4 files changed

+51
-24
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "\"Connect\" and \"Choose Profile\" open create credentials wizard/profile selector when credentials aren't present in aws configs"
4+
}

src/shared/awsContextCommands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export class AwsContextCommands {
170170
* editing their credentials file.
171171
*/
172172
private async getProfileNameFromUser(): Promise<string | undefined> {
173-
const credentialsFiles: string[] = await UserCredentialsUtils.findExistingCredentialsFilenames()
173+
const credentialsFiles: string[] = await UserCredentialsUtils.findExistingCredentialsFilenames(true)
174174
const providerMap = await CredentialsProviderManager.getInstance().getCredentialProviderNames()
175175
const profileNames = Object.keys(providerMap)
176176
if (profileNames.length > 0) {

src/shared/credentials/userCredentialsUtils.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,18 @@ export class UserCredentialsUtils {
5757
*
5858
* @returns array of filenames for files found.
5959
*/
60-
public static async findExistingCredentialsFilenames(): Promise<string[]> {
60+
public static async findExistingCredentialsFilenames(isCredentialsRequired = false): Promise<string[]> {
6161
const candidateFiles: string[] = [getCredentialsFilename(), getConfigFilename()]
6262

6363
const existsResults: boolean[] = await Promise.all(
64-
candidateFiles.map(async filename => await SystemUtilities.fileExists(filename))
64+
candidateFiles.map(async filename => {
65+
const exists = await SystemUtilities.fileExists(filename)
66+
if (!exists || !isCredentialsRequired) {
67+
return exists
68+
}
69+
const contents = await SystemUtilities.readFile(filename)
70+
return /aws_access_key_id|aws_secret_access_key|aws_session_token/i.test(contents)
71+
})
6572
)
6673

6774
return candidateFiles.filter((filename, index) => existsResults[index])

src/test/shared/credentials/userCredentialsUtils.test.ts

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import * as assert from 'assert'
77
import * as fs from 'fs-extra'
88
import * as path from 'path'
9+
import * as sinon from 'sinon'
910

1011
import { Uri } from 'vscode'
1112
import { loadSharedConfigFiles } from '../../../shared/credentials/credentialsFile'
@@ -23,9 +24,7 @@ describe('UserCredentialsUtils', function () {
2324
})
2425

2526
afterEach(async function () {
26-
const env = process.env as EnvironmentVariables
27-
delete env.AWS_SHARED_CREDENTIALS_FILE
28-
delete env.AWS_CONFIG_FILE
27+
sinon.restore()
2928
})
3029

3130
after(async function () {
@@ -37,30 +36,30 @@ describe('UserCredentialsUtils', function () {
3736
const credentialsFilename = path.join(tempFolder, 'credentials-both-exist-test')
3837
const configFilename = path.join(tempFolder, 'config-both-exist-test')
3938

40-
const env = process.env as EnvironmentVariables
41-
env.AWS_SHARED_CREDENTIALS_FILE = credentialsFilename
42-
env.AWS_CONFIG_FILE = configFilename
39+
sinon.stub(process, 'env').value({
40+
AWS_SHARED_CREDENTIALS_FILE: credentialsFilename,
41+
AWS_CONFIG_FILE: configFilename,
42+
} as EnvironmentVariables)
4343

4444
createCredentialsFile(credentialsFilename, ['default'])
4545
createCredentialsFile(configFilename, ['default'])
4646

4747
const foundFiles: string[] = await UserCredentialsUtils.findExistingCredentialsFilenames()
48-
assert(foundFiles)
4948
assert.strictEqual(foundFiles.length, 2)
5049
})
5150

5251
it('returns credentials file if it exists and config file does not exist', async function () {
5352
const credentialsFilename = path.join(tempFolder, 'credentials-exist-test')
5453
const configFilename = path.join(tempFolder, 'config-not-exist-test')
5554

56-
const env = process.env as EnvironmentVariables
57-
env.AWS_SHARED_CREDENTIALS_FILE = credentialsFilename
58-
env.AWS_CONFIG_FILE = configFilename
55+
sinon.stub(process, 'env').value({
56+
AWS_SHARED_CREDENTIALS_FILE: credentialsFilename,
57+
AWS_CONFIG_FILE: configFilename,
58+
} as EnvironmentVariables)
5959

6060
createCredentialsFile(credentialsFilename, ['default'])
6161

6262
const foundFiles: string[] = await UserCredentialsUtils.findExistingCredentialsFilenames()
63-
assert(foundFiles)
6463
assert.strictEqual(foundFiles.length, 1)
6564
assert.strictEqual(foundFiles[0], credentialsFilename)
6665
})
@@ -69,14 +68,14 @@ describe('UserCredentialsUtils', function () {
6968
const credentialsFilename = path.join(tempFolder, 'credentials-not-exist-test')
7069
const configFilename = path.join(tempFolder, 'config-exist-test')
7170

72-
const env = process.env as EnvironmentVariables
73-
env.AWS_SHARED_CREDENTIALS_FILE = credentialsFilename
74-
env.AWS_CONFIG_FILE = configFilename
71+
sinon.stub(process, 'env').value({
72+
AWS_SHARED_CREDENTIALS_FILE: credentialsFilename,
73+
AWS_CONFIG_FILE: configFilename,
74+
} as EnvironmentVariables)
7575

7676
createCredentialsFile(configFilename, ['default'])
7777

7878
const foundFiles: string[] = await UserCredentialsUtils.findExistingCredentialsFilenames()
79-
assert(foundFiles)
8079
assert.strictEqual(foundFiles.length, 1)
8180
assert.strictEqual(foundFiles[0], configFilename)
8281
})
@@ -85,12 +84,28 @@ describe('UserCredentialsUtils', function () {
8584
const credentialsFilename = path.join(tempFolder, 'credentials-not-exist-test')
8685
const configFilename = path.join(tempFolder, 'config-not-exist-test')
8786

88-
const env = process.env as EnvironmentVariables
89-
env.AWS_SHARED_CREDENTIALS_FILE = credentialsFilename
90-
env.AWS_CONFIG_FILE = configFilename
87+
sinon.stub(process, 'env').value({
88+
AWS_SHARED_CREDENTIALS_FILE: credentialsFilename,
89+
AWS_CONFIG_FILE: configFilename,
90+
} as EnvironmentVariables)
9191

9292
const foundFiles: string[] = await UserCredentialsUtils.findExistingCredentialsFilenames()
93-
assert(foundFiles)
93+
assert.strictEqual(foundFiles.length, 0)
94+
})
95+
96+
it('returns empty result if files dont contain credentials', async function () {
97+
const credentialsFilename = path.join(tempFolder, 'credentials-both-exist-but-no-credentials-test')
98+
const configFilename = path.join(tempFolder, 'config-both-exist-but-no-credentials-test')
99+
100+
sinon.stub(process, 'env').value({
101+
AWS_SHARED_CREDENTIALS_FILE: credentialsFilename,
102+
AWS_CONFIG_FILE: configFilename,
103+
} as EnvironmentVariables)
104+
105+
createCredentialsFile(credentialsFilename, [])
106+
createCredentialsFile(configFilename, [])
107+
108+
const foundFiles: string[] = await UserCredentialsUtils.findExistingCredentialsFilenames(true)
94109
assert.strictEqual(foundFiles.length, 0)
95110
})
96111
})
@@ -100,8 +115,9 @@ describe('UserCredentialsUtils', function () {
100115
const credentialsFilename = path.join(tempFolder, 'credentials-generation-test')
101116
const profileName = 'someRandomProfileName'
102117

103-
const env = process.env as EnvironmentVariables
104-
env.AWS_SHARED_CREDENTIALS_FILE = credentialsFilename
118+
sinon.stub(process, 'env').value({
119+
AWS_SHARED_CREDENTIALS_FILE: credentialsFilename,
120+
} as EnvironmentVariables)
105121
const creds = {
106122
accessKey: '123',
107123
profileName: profileName,

0 commit comments

Comments
 (0)