Skip to content

Commit 66839bd

Browse files
authored
Prompt user when attempting to sign-in to multiple Builder IDs (#3519)
1 parent ed27047 commit 66839bd

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.intellij.openapi.application.ApplicationManager
77
import com.intellij.openapi.components.service
88
import com.intellij.openapi.extensions.ExtensionPointName
99
import com.intellij.openapi.project.Project
10+
import com.intellij.openapi.ui.MessageDialogBuilder
1011
import software.amazon.awssdk.services.ssooidc.model.SsoOidcException
1112
import software.aws.toolkits.core.ClientConnectionSettings
1213
import software.aws.toolkits.core.ConnectionSettings
@@ -16,10 +17,12 @@ import software.aws.toolkits.core.utils.getLogger
1617
import software.aws.toolkits.core.utils.info
1718
import software.aws.toolkits.jetbrains.core.credentials.pinning.FeatureWithPinnedConnection
1819
import software.aws.toolkits.jetbrains.core.credentials.sono.ALL_SONO_SCOPES
20+
import software.aws.toolkits.jetbrains.core.credentials.sono.isSono
1921
import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenAuthState
2022
import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenProvider
2123
import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenProviderListener
2224
import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.DEFAULT_SSO_REGION
25+
import software.aws.toolkits.jetbrains.utils.computeOnEdt
2326
import software.aws.toolkits.jetbrains.utils.runUnderProgressIfNeeded
2427
import software.aws.toolkits.resources.message
2528

@@ -101,23 +104,44 @@ fun loginSso(project: Project?, startUrl: String, scopes: List<String> = ALL_SON
101104
val manager = ToolkitAuthManager.getInstance()
102105

103106
return manager.getConnection(connectionId)?.let { connection ->
107+
val logger = getLogger<ToolkitAuthManager>()
108+
// requested Builder ID, but one already exists
109+
// TBD: do we do this for regular SSO too?
110+
if (connection.isSono()) {
111+
val signOut = computeOnEdt {
112+
MessageDialogBuilder.yesNo(
113+
message("toolkit.login.aws_builder_id.already_connected.title"),
114+
message("toolkit.login.aws_builder_id.already_connected.message")
115+
)
116+
.yesText(message("toolkit.login.aws_builder_id.already_connected.reconnect"))
117+
.noText(message("toolkit.login.aws_builder_id.already_connected.cancel"))
118+
.ask(project)
119+
}
120+
121+
if (signOut) {
122+
logger.info {
123+
"Forcing reauth on ${connection.id} since user requested Builder ID while already connected to Builder ID"
124+
}
125+
126+
logoutFromSsoConnection(project, connection as AwsBearerTokenConnection)
127+
return@let null
128+
}
129+
}
130+
104131
// There is an existing connection we can use
105132
if (connection is BearerSsoConnection && !scopes.all { it in connection.scopes }) {
106-
getLogger<ToolkitAuthManager>().info {
133+
logger.info {
107134
"Forcing reauth on ${connection.id} since requested scopes ($scopes) are not a complete subset of current scopes (${connection.scopes})"
108135
}
136+
109137
// can't reuse since requested scopes are not in current connection. forcing reauth
110138
manager.deleteConnection(connection)
111139
return@let null
112140
}
113141

114142
// For the case when the existing connection is in invalid state, we need to re-auth
115143
if (connection is AwsBearerTokenConnection) {
116-
val tokenProvider = reauthProviderIfNeeded(connection)
117-
118-
ToolkitConnectionManager.getInstance(project).switchConnection(connection)
119-
120-
return tokenProvider
144+
reauthConnection(project, connection)
121145
}
122146

123147
null
@@ -132,18 +156,22 @@ fun loginSso(project: Project?, startUrl: String, scopes: List<String> = ALL_SON
132156
)
133157

134158
try {
135-
val provider = reauthProviderIfNeeded(connection)
136-
137-
ToolkitConnectionManager.getInstance(project).switchConnection(connection)
138-
139-
provider
159+
reauthConnection(project, connection)
140160
} catch (e: Exception) {
141161
manager.deleteConnection(connection)
142162
throw e
143163
}
144164
}
145165
}
146166

167+
private fun reauthConnection(project: Project?, connection: ToolkitConnection): BearerTokenProvider {
168+
val provider = reauthProviderIfNeeded(connection)
169+
170+
ToolkitConnectionManager.getInstance(project).switchConnection(connection)
171+
172+
return provider
173+
}
174+
147175
fun logoutFromSsoConnection(project: Project?, connection: AwsBearerTokenConnection, callback: () -> Unit = {}) {
148176
try {
149177
ApplicationManager.getApplication().messageBus.syncPublisher(BearerTokenProviderListener.TOPIC).invalidate(connection.id)

resources/resources/software/aws/toolkits/resources/MessagesBundle.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,10 @@ sqs.subscribe.sns.validation.empty_topic=Topic must be specified.
13901390
sqs.toolwindow=SQS
13911391
sqs.url.parse_error=Error parsing SQS queue URL
13921392
tags.title=Tags
1393+
toolkit.login.aws_builder_id.already_connected.cancel=Use existing AWS Builder ID
1394+
toolkit.login.aws_builder_id.already_connected.message=You already signed in with an AWS Builder ID.\nSign out to add another?
1395+
toolkit.login.aws_builder_id.already_connected.reconnect=Sign out
1396+
toolkit.login.aws_builder_id.already_connected.title=Sign out of current AWS Builder ID?
13931397
toolkit.login.dialog.aws_builder_id.comment=AWS Builder ID is a new personal profile for builders. <a href='https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/codewhisperer.html'>Learn More</a>
13941398
toolkit.login.dialog.aws_builder_id.title=Use a personal email to sign up and sign in with AWS Builder ID
13951399
toolkit.login.dialog.connect_button=Connect

0 commit comments

Comments
 (0)