Skip to content

Commit 6f5b848

Browse files
authored
Merge branch 'aws:master' into master
2 parents aedffcd + 6ac1207 commit 6f5b848

File tree

3 files changed

+111
-8
lines changed

3 files changed

+111
-8
lines changed

packages/amazonq/src/lsp/client.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
getClientId,
4040
extensionVersion,
4141
isSageMaker,
42+
DevSettings,
4243
} from 'aws-core-vscode/shared'
4344
import { processUtils } from 'aws-core-vscode/shared'
4445
import { activate } from './chat/activation'
@@ -129,6 +130,15 @@ export async function startLanguageServer(
129130

130131
await validateNodeExe(executable, resourcePaths.lsp, argv, logger)
131132

133+
const endpointOverride = DevSettings.instance.get('codewhispererService', {}).endpoint ?? undefined
134+
const textDocSection = {
135+
inlineEditSupport: Experiments.instance.get('amazonqLSPNEP', true),
136+
} as any
137+
138+
if (endpointOverride) {
139+
textDocSection.endpointOverride = endpointOverride
140+
}
141+
132142
// Options to control the language client
133143
const clientOptions: LanguageClientOptions = {
134144
// Register the server for json documents
@@ -177,9 +187,7 @@ export async function startLanguageServer(
177187
showLogs: true,
178188
},
179189
textDocument: {
180-
inlineCompletionWithReferences: {
181-
inlineEditSupport: Experiments.instance.get('amazonqLSPNEP', true),
182-
},
190+
inlineCompletionWithReferences: textDocSection,
183191
},
184192
},
185193
contextConfiguration: {

packages/core/src/auth/providers/sharedCredentialsProvider.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,28 @@ export class SharedCredentialsProvider implements CredentialsProvider {
406406
`auth: Profile ${this.profileName} is missing source_profile for role assumption`
407407
)
408408
}
409-
// Use source profile to assume IAM role based on role ARN provided.
409+
410+
// Check if we already have resolved credentials from patchSourceCredentials
410411
const sourceProfile = iniData[profile.source_profile!]
411-
const stsClient = new DefaultStsClient(this.getDefaultRegion() ?? 'us-east-1', {
412-
accessKeyId: sourceProfile.aws_access_key_id!,
413-
secretAccessKey: sourceProfile.aws_secret_access_key!,
414-
})
412+
let sourceCredentials: AWS.Credentials
413+
414+
if (sourceProfile.aws_access_key_id && sourceProfile.aws_secret_access_key) {
415+
// Source credentials have already been resolved
416+
sourceCredentials = {
417+
accessKeyId: sourceProfile.aws_access_key_id,
418+
secretAccessKey: sourceProfile.aws_secret_access_key,
419+
sessionToken: sourceProfile.aws_session_token,
420+
}
421+
} else {
422+
// Source profile needs credential resolution - this should have been handled by patchSourceCredentials
423+
// but if not, we need to resolve it here
424+
const sourceProvider = new SharedCredentialsProvider(profile.source_profile!, this.sections)
425+
sourceCredentials = await sourceProvider.getCredentials()
426+
}
427+
428+
// Use source credentials to assume IAM role based on role ARN provided.
429+
const stsClient = new DefaultStsClient(this.getDefaultRegion() ?? 'us-east-1', sourceCredentials)
430+
415431
// Prompt for MFA Token if needed.
416432
const assumeRoleReq = {
417433
RoleArn: profile.role_arn,
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import assert from 'assert'
7+
import { SharedCredentialsProvider } from '../../../auth/providers/sharedCredentialsProvider'
8+
import { createTestSections } from '../../credentials/testUtil'
9+
import { DefaultStsClient } from '../../../shared/clients/stsClient'
10+
import { oneDay } from '../../../shared/datetime'
11+
import sinon from 'sinon'
12+
import { SsoAccessTokenProvider } from '../../../auth/sso/ssoAccessTokenProvider'
13+
import { SsoClient } from '../../../auth/sso/clients'
14+
15+
describe('SharedCredentialsProvider - Role Chaining with SSO', function () {
16+
let sandbox: sinon.SinonSandbox
17+
18+
beforeEach(function () {
19+
sandbox = sinon.createSandbox()
20+
})
21+
22+
afterEach(function () {
23+
sandbox.restore()
24+
})
25+
26+
it('should handle role chaining from SSO profile', async function () {
27+
// Mock the SSO authentication
28+
sandbox.stub(SsoAccessTokenProvider.prototype, 'getToken').resolves({
29+
accessToken: 'test-token',
30+
expiresAt: new Date(Date.now() + oneDay),
31+
})
32+
33+
// Mock SSO getRoleCredentials
34+
sandbox.stub(SsoClient.prototype, 'getRoleCredentials').resolves({
35+
accessKeyId: 'sso-access-key',
36+
secretAccessKey: 'sso-secret-key',
37+
sessionToken: 'sso-session-token',
38+
expiration: new Date(Date.now() + oneDay),
39+
})
40+
41+
// Mock STS assumeRole
42+
sandbox.stub(DefaultStsClient.prototype, 'assumeRole').callsFake(async (request) => {
43+
assert.strictEqual(request.RoleArn, 'arn:aws:iam::123456789012:role/dev')
44+
return {
45+
Credentials: {
46+
AccessKeyId: 'assumed-access-key',
47+
SecretAccessKey: 'assumed-secret-key',
48+
SessionToken: 'assumed-session-token',
49+
Expiration: new Date(Date.now() + oneDay),
50+
},
51+
}
52+
})
53+
54+
const sections = await createTestSections(`
55+
[sso-session aws1_session]
56+
sso_start_url = https://example.awsapps.com/start
57+
sso_region = us-east-1
58+
sso_registration_scopes = sso:account:access
59+
60+
[profile Landing]
61+
sso_session = aws1_session
62+
sso_account_id = 111111111111
63+
sso_role_name = Landing
64+
region = us-east-1
65+
66+
[profile dev]
67+
region = us-east-1
68+
role_arn = arn:aws:iam::123456789012:role/dev
69+
source_profile = Landing
70+
`)
71+
72+
const provider = new SharedCredentialsProvider('dev', sections)
73+
const credentials = await provider.getCredentials()
74+
75+
assert.strictEqual(credentials.accessKeyId, 'assumed-access-key')
76+
assert.strictEqual(credentials.secretAccessKey, 'assumed-secret-key')
77+
assert.strictEqual(credentials.sessionToken, 'assumed-session-token')
78+
})
79+
})

0 commit comments

Comments
 (0)