@@ -40,6 +40,7 @@ import {
4040 hasScopes ,
4141 scopesSsoAccountAccess ,
4242 isSsoConnection ,
43+ IamConnection ,
4344} from './connection'
4445import { Commands , placeholder } from '../shared/vscode/commands2'
4546import { 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+
343386export 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