Skip to content

Commit 4d3b938

Browse files
authored
feat: support sending requests with the 'external_idp' type (aws#2247)
1 parent debeb41 commit 4d3b938

File tree

8 files changed

+34
-17
lines changed

8 files changed

+34
-17
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/aws-lsp-codewhisperer/src/shared/amazonQServiceManager/AmazonQTokenServiceManager.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -236,23 +236,24 @@ export class AmazonQTokenServiceManager extends BaseAmazonQServiceManager<
236236
this.features.lsp.getClientInitializeParams()?.initializationOptions?.aws?.awsClientCapabilities
237237
?.textDocument?.inlineCompletionWithReferences?.endpointOverride
238238

239-
// Connection type changed to 'builderId'
240-
241-
if (newConnectionType === 'builderId') {
242-
this.log('Detected New connection type: builderId')
239+
// Connection type changed to 'builderId' | 'external_idp'
240+
// for now pretend External IdP is just a special case of Builder ID where the subscription has already been established
241+
// and user does not need a profile
242+
if (newConnectionType === 'builderId' || newConnectionType === 'external_idp') {
243+
this.log(`Detected New connection type: ${newConnectionType}`)
243244
this.resetCodewhispererService()
244245

245246
// For the builderId connection type regional endpoint discovery chain is:
246247
// region set by client -> runtime region -> default region
247248
const clientParams = this.features.lsp.getClientInitializeParams()
248249

249250
this.createCodewhispererServiceInstances(
250-
'builderId',
251+
newConnectionType,
251252
clientParams?.initializationOptions?.aws?.region,
252253
endpointOverride
253254
)
254255
this.state = 'INITIALIZED'
255-
this.log('Initialized Amazon Q service with builderId connection')
256+
this.log(`Initialized Amazon Q service with ${newConnectionType} connection`)
256257

257258
// Emit auth success event
258259
ProfileStatusMonitor.emitAuthSuccess()
@@ -506,7 +507,7 @@ export class AmazonQTokenServiceManager extends BaseAmazonQServiceManager<
506507
}
507508

508509
private createCodewhispererServiceInstances(
509-
connectionType: 'builderId' | 'identityCenter',
510+
connectionType: Exclude<SsoConnectionType, 'none'>,
510511
clientOrProfileRegion: string | undefined,
511512
endpointOverride: string | undefined
512513
) {

server/aws-lsp-codewhisperer/src/shared/amazonQServiceManager/qDeveloperProfiles.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as assert from 'assert'
22
import sinon, { StubbedInstance, stubInterface } from 'ts-sinon'
33
import { CodeWhispererServiceToken } from '../codeWhispererService'
4-
import { SsoConnectionType } from '../utils'
54
import {
65
AWSInitializationOptions,
76
CancellationTokenSource,
87
Logging,
8+
SsoConnectionType,
99
} from '@aws/language-server-runtimes/server-interface'
1010
import {
1111
AmazonQDeveloperProfile,

server/aws-lsp-codewhisperer/src/shared/amazonQServiceManager/qDeveloperProfiles.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import {
44
Logging,
55
LSPErrorCodes,
66
ResponseError,
7+
SsoConnectionType,
78
} from '@aws/language-server-runtimes/server-interface'
8-
import { isBool, isObject, SsoConnectionType } from '../utils'
9+
import { isBool, isObject } from '../utils'
910
import { AWS_Q_ENDPOINTS } from '../../shared/constants'
1011
import { CodeWhispererServiceToken } from '../codeWhispererService'
1112
import { AmazonQServiceProfileThrottlingError } from './errors'

server/aws-lsp-codewhisperer/src/shared/codeWhispererService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,10 @@ export class CodeWhispererServiceToken extends CodeWhispererServiceBase {
344344
if (!creds?.token) {
345345
throw new Error('Authorization failed, bearer token is not set')
346346
}
347+
if (credentialsProvider.getConnectionType() === 'external_idp') {
348+
httpRequest.headers['TokenType'] = 'EXTERNAL_IDP'
349+
}
350+
347351
httpRequest.headers['Authorization'] = `Bearer ${creds.token}`
348352
httpRequest.headers['x-amzn-codewhisperer-optout'] =
349353
`${!this.shareCodeWhispererContentWithAWS}`

server/aws-lsp-codewhisperer/src/shared/streamingClientService.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ export class StreamingClientServiceToken extends StreamingClientServiceBase {
8888
}),
8989
customUserAgent: customUserAgent,
9090
})
91+
92+
this.client.middlewareStack.add(
93+
(next, context) => args => {
94+
if (credentialsProvider.getConnectionType() === 'external_idp') {
95+
// @ts-ignore
96+
args.request.headers['TokenType'] = 'EXTERNAL_IDP'
97+
}
98+
return next(args)
99+
},
100+
{
101+
step: 'build',
102+
}
103+
)
91104
}
92105

93106
public async sendMessage(

server/aws-lsp-codewhisperer/src/shared/testUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { TextDocument } from 'vscode-languageserver-textdocument'
22
import { CodeWhispererServiceBase, ResponseContext, Suggestion } from './codeWhispererService'
33
import { TestFeatures } from '@aws/language-server-runtimes/testing'
4-
import { SsoConnectionType } from './utils'
54
import { stubInterface } from 'ts-sinon'
65
import { StreamingClientServiceBase } from './streamingClientService'
76
import { SessionData } from '../language-server/inline-completion/session/sessionManager'
87
import { WorkspaceFolder } from '@aws/language-server-runtimes/protocol'
8+
import { SsoConnectionType } from '@aws/language-server-runtimes/server-interface'
99

1010
export const HELLO_WORLD_IN_CSHARP = `class HelloWorld
1111
{

server/aws-lsp-codewhisperer/src/shared/utils.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
BearerCredentials,
44
CredentialsProvider,
55
Position,
6+
SsoConnectionType,
67
} from '@aws/language-server-runtimes/server-interface'
78
import { AWSError, Credentials } from 'aws-sdk'
89
import { distance } from 'fastest-levenshtein'
@@ -31,7 +32,6 @@ import { getAuthFollowUpType } from '../language-server/chat/utils'
3132
import ignore = require('ignore')
3233
import { InitializeParams } from '@aws/language-server-runtimes/server-interface'
3334
import { QClientCapabilities } from '../language-server/configuration/qConfigurationServer'
34-
export type SsoConnectionType = 'builderId' | 'identityCenter' | 'none'
3535

3636
export function isAwsError(error: unknown): error is AWSError {
3737
if (error === undefined) {
@@ -436,9 +436,7 @@ export const flattenMetric = (obj: any, prefix = '') => {
436436
}
437437

438438
export function getSsoConnectionType(credentialsProvider: CredentialsProvider): SsoConnectionType {
439-
const connectionMetadata = credentialsProvider.getConnectionMetadata()
440-
const startUrl = connectionMetadata?.sso?.startUrl
441-
return !startUrl ? 'none' : startUrl.includes(BUILDER_ID_START_URL) ? 'builderId' : 'identityCenter'
439+
return credentialsProvider.getConnectionType()
442440
}
443441

444442
// Port of implementation in AWS Toolkit for VSCode

0 commit comments

Comments
 (0)