Skip to content

Commit 34e7f1b

Browse files
committed
Make sso quickpick option display profiles
1 parent 028f4f3 commit 34e7f1b

File tree

1 file changed

+56
-5
lines changed

1 file changed

+56
-5
lines changed

packages/core/src/auth/utils.ts

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
hasScopes,
4141
scopesSsoAccountAccess,
4242
isSsoConnection,
43+
IamConnection,
4344
} from './connection'
4445
import { Commands, placeholder } from '../shared/vscode/commands2'
4546
import { Auth } from './auth'
@@ -79,6 +80,18 @@ export async function promptForConnection(auth: Auth, type?: 'iam' | 'iam-only'
7980
return globals.awsContextCommands.onCommandEditCredentials()
8081
}
8182

83+
// If selected connection is SSO connection and has linked IAM profiles, show second quick pick with the linked IAM profiles
84+
if (isSsoConnection(resp)) {
85+
const linkedProfiles = await getLinkedIamProfiles(auth, resp)
86+
87+
if (linkedProfiles.length > 0) {
88+
const linkedResp = await showLinkedProfilePicker(linkedProfiles, resp)
89+
if (linkedResp) {
90+
return linkedResp
91+
}
92+
}
93+
}
94+
8295
return resp
8396
}
8497

@@ -340,6 +353,36 @@ export const createDeleteConnectionButton: () => vscode.QuickInputButton = () =>
340353
return { tooltip: deleteConnection, iconPath: getIcon('vscode-trash') }
341354
}
342355

356+
async function getLinkedIamProfiles(auth: Auth, ssoConnection: SsoConnection): Promise<IamConnection[]> {
357+
const allConnections = await auth.listAndTraverseConnections().promise()
358+
359+
return allConnections.filter(
360+
(conn) => isIamConnection(conn) && conn.id.startsWith(`sso:${ssoConnection.id}#`)
361+
) as IamConnection[]
362+
}
363+
364+
/**
365+
* Shows a quick pick with linked IAM profiles for a selected SSO connection
366+
*/
367+
async function showLinkedProfilePicker(
368+
linkedProfiles: IamConnection[],
369+
ssoConnection: SsoConnection
370+
): Promise<IamConnection | undefined> {
371+
const title = `Select an IAM Role for ${ssoConnection.label}`
372+
373+
const items: DataQuickPickItem<IamConnection>[] = linkedProfiles.map((profile) => ({
374+
label: codicon`${getIcon('vscode-key')} ${profile.label}`,
375+
description: 'IAM Credential, sourced from IAM Identity Center',
376+
data: profile,
377+
}))
378+
379+
return await showQuickPick(items, {
380+
title,
381+
placeholder: 'Select an IAM role',
382+
buttons: [createRefreshButton(), createExitButton()],
383+
})
384+
}
385+
343386
export function createConnectionPrompter(auth: Auth, type?: 'iam' | 'iam-only' | 'sso') {
344387
const addNewConnection = {
345388
label: codicon`${getIcon('vscode-plus')} Add New Connection`,
@@ -433,22 +476,22 @@ export function createConnectionPrompter(auth: Auth, type?: 'iam' | 'iam-only' |
433476
for await (const conn of connections) {
434477
if (conn.label.includes('profile:') && !hasShownEdit) {
435478
hasShownEdit = true
436-
yield [toPickerItem(conn), editCredentials]
479+
yield [await toPickerItem(conn), editCredentials]
437480
} else {
438-
yield [toPickerItem(conn)]
481+
yield [await toPickerItem(conn)]
439482
}
440483
}
441484
}
442485

443-
function toPickerItem(conn: Connection): DataQuickPickItem<Connection> {
486+
async function toPickerItem(conn: Connection): Promise<DataQuickPickItem<Connection>> {
444487
const state = auth.getConnectionState(conn)
445488
// Only allow SSO connections to be deleted
446489
const deleteButton: vscode.QuickInputButton[] = conn.type === 'sso' ? [createDeleteConnectionButton()] : []
447490
if (state === 'valid') {
448491
return {
449492
data: conn,
450493
label: codicon`${getConnectionIcon(conn)} ${conn.label}`,
451-
description: getConnectionDescription(conn),
494+
description: await getConnectionDescription(conn),
452495
buttons: [...deleteButton],
453496
}
454497
}
@@ -502,7 +545,7 @@ export function createConnectionPrompter(auth: Auth, type?: 'iam' | 'iam-only' |
502545
}
503546
}
504547

505-
function getConnectionDescription(conn: Connection) {
548+
async function getConnectionDescription(conn: Connection) {
506549
if (conn.type === 'iam') {
507550
// TODO: implement a proper `getConnectionSource` method to discover where a connection came from
508551
const descSuffix = conn.id.startsWith('profile:')
@@ -514,6 +557,14 @@ export function createConnectionPrompter(auth: Auth, type?: 'iam' | 'iam-only' |
514557
return `IAM Credential, ${descSuffix}`
515558
}
516559

560+
// If this is an SSO connection, check if it has linked IAM profiles
561+
if (isSsoConnection(conn)) {
562+
const linkedProfiles = await getLinkedIamProfiles(auth, conn)
563+
if (linkedProfiles.length > 0) {
564+
return `Has ${linkedProfiles.length} IAM role${linkedProfiles.length > 1 ? 's' : ''} (click to select)`
565+
}
566+
}
567+
517568
const toolAuths = getDependentAuths(conn)
518569
if (toolAuths.length === 0) {
519570
return undefined

0 commit comments

Comments
 (0)