Skip to content

Commit f88193d

Browse files
authored
Fix getting credentials possibly deadlocking (#2961)
* Move SSO to jetbrains-core so we get access to ProgressIndicator * Fetch credentials under a modal progress indicator * Make SSO token pending respect ProgressIndicator cancel * Throw ProcessCanceledException when user prompts are canceled * Remove some coroutines usage that led to losing track of the ProgressIndicator
1 parent 1eb5c18 commit f88193d

21 files changed

+298
-159
lines changed

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

Lines changed: 0 additions & 18 deletions
This file was deleted.

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import software.aws.toolkits.core.credentials.ToolkitCredentialsProvider
1919
import software.aws.toolkits.core.region.AwsRegion
2020
import software.aws.toolkits.core.utils.getLogger
2121
import software.aws.toolkits.core.utils.tryOrNull
22+
import software.aws.toolkits.jetbrains.utils.runUnderProgressIfNeeded
23+
import software.aws.toolkits.resources.message
2224
import software.aws.toolkits.telemetry.AwsTelemetry
2325
import java.util.concurrent.ConcurrentHashMap
2426
import java.util.concurrent.atomic.AtomicInteger
@@ -68,7 +70,9 @@ abstract class CredentialManager : SimpleModificationTracker() {
6870
* as loading from disk when new values.
6971
*/
7072
private inner class AwsCredentialProviderProxy(private val providerId: String, private val region: AwsRegion) : AwsCredentialsProvider {
71-
override fun resolveCredentials(): AwsCredentials = getOrCreateAwsCredentialsProvider(providerId, region).resolveCredentials()
73+
override fun resolveCredentials(): AwsCredentials = runUnderProgressIfNeeded(null, message("credentials.retrieving"), cancelable = true) {
74+
getOrCreateAwsCredentialsProvider(providerId, region).resolveCredentials()
75+
}
7276

7377
private fun getOrCreateAwsCredentialsProvider(providerId: String, region: AwsRegion): AwsCredentialsProvider {
7478
// Validate that the provider ID is still valid and get the latest copy

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

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
package software.aws.toolkits.jetbrains.core.credentials
55

66
import com.intellij.openapi.actionSystem.AnAction
7+
import com.intellij.openapi.progress.ProcessCanceledException
78
import com.intellij.openapi.ui.Messages
8-
import kotlinx.coroutines.runBlocking
9-
import kotlinx.coroutines.withContext
10-
import software.aws.toolkits.jetbrains.core.coroutines.getCoroutineUiContext
9+
import software.aws.toolkits.jetbrains.utils.computeOnEdt
1110
import software.aws.toolkits.resources.message
1211

1312
interface MfaRequiredInteractiveCredentials : InteractiveCredential {
@@ -19,12 +18,10 @@ interface MfaRequiredInteractiveCredentials : InteractiveCredential {
1918
override fun userActionRequired(): Boolean = true
2019
}
2120

22-
fun promptForMfaToken(name: String, mfaSerial: String): String = runBlocking {
23-
withContext(getCoroutineUiContext()) {
24-
Messages.showInputDialog(
25-
message("credentials.mfa.message", mfaSerial),
26-
message("credentials.mfa.title", name),
27-
null
28-
) ?: throw IllegalStateException("MFA challenge is required")
29-
}
21+
fun promptForMfaToken(name: String, mfaSerial: String): String = computeOnEdt {
22+
Messages.showInputDialog(
23+
message("credentials.mfa.message", mfaSerial),
24+
message("credentials.mfa.title", name),
25+
null
26+
) ?: throw ProcessCanceledException(IllegalStateException("MFA challenge is required"))
3027
}

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ package software.aws.toolkits.jetbrains.core.credentials
55

66
import com.intellij.ide.BrowserUtil
77
import com.intellij.openapi.actionSystem.AnAction
8+
import com.intellij.openapi.progress.ProcessCanceledException
89
import com.intellij.openapi.ui.Messages
9-
import kotlinx.coroutines.withContext
10-
import software.aws.toolkits.core.credentials.sso.Authorization
11-
import software.aws.toolkits.core.credentials.sso.DiskCache
12-
import software.aws.toolkits.core.credentials.sso.SsoCache
13-
import software.aws.toolkits.core.credentials.sso.SsoLoginCallback
14-
import software.aws.toolkits.jetbrains.core.coroutines.getCoroutineUiContext
10+
import software.aws.toolkits.jetbrains.core.credentials.sso.Authorization
11+
import software.aws.toolkits.jetbrains.core.credentials.sso.DiskCache
12+
import software.aws.toolkits.jetbrains.core.credentials.sso.SsoCache
13+
import software.aws.toolkits.jetbrains.core.credentials.sso.SsoLoginCallback
14+
import software.aws.toolkits.jetbrains.utils.computeOnEdt
1515
import software.aws.toolkits.jetbrains.utils.notifyError
1616
import software.aws.toolkits.resources.message
1717

@@ -21,8 +21,8 @@ import software.aws.toolkits.resources.message
2121
val diskCache by lazy { DiskCache() }
2222

2323
object SsoPrompt : SsoLoginCallback {
24-
override suspend fun tokenPending(authorization: Authorization) {
25-
withContext(getCoroutineUiContext()) {
24+
override fun tokenPending(authorization: Authorization) {
25+
computeOnEdt {
2626
val result = Messages.showOkCancelDialog(
2727
message("credentials.sso.login.message", authorization.verificationUri, authorization.userCode),
2828
message("credentials.sso.login.title"),
@@ -34,7 +34,7 @@ object SsoPrompt : SsoLoginCallback {
3434
if (result == Messages.OK) {
3535
BrowserUtil.browse(authorization.verificationUriComplete)
3636
} else {
37-
throw IllegalStateException(message("credentials.sso.login.cancelled"))
37+
throw ProcessCanceledException(IllegalStateException(message("credentials.sso.login.cancelled")))
3838
}
3939
}
4040
}

jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/profiles/ProfileCredentialProviderFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import software.aws.toolkits.core.credentials.CredentialSourceId
1919
import software.aws.toolkits.core.credentials.CredentialType
2020
import software.aws.toolkits.core.credentials.CredentialsChangeEvent
2121
import software.aws.toolkits.core.credentials.CredentialsChangeListener
22-
import software.aws.toolkits.core.credentials.sso.SsoCache
2322
import software.aws.toolkits.core.region.AwsRegion
2423
import software.aws.toolkits.jetbrains.core.credentials.MfaRequiredInteractiveCredentials
2524
import software.aws.toolkits.jetbrains.core.credentials.SsoRequiredInteractiveCredentials
2625
import software.aws.toolkits.jetbrains.core.credentials.ToolkitCredentialProcessProvider
2726
import software.aws.toolkits.jetbrains.core.credentials.diskCache
27+
import software.aws.toolkits.jetbrains.core.credentials.sso.SsoCache
2828
import software.aws.toolkits.jetbrains.settings.AwsSettings
2929
import software.aws.toolkits.jetbrains.settings.ProfilesNotification
3030
import software.aws.toolkits.jetbrains.utils.createNotificationExpiringAction

jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/profiles/ProfileSsoProvider.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import software.amazon.awssdk.regions.Region
1212
import software.amazon.awssdk.services.sso.SsoClient
1313
import software.amazon.awssdk.services.ssooidc.SsoOidcClient
1414
import software.amazon.awssdk.utils.SdkAutoCloseable
15-
import software.aws.toolkits.core.credentials.sso.SsoAccessTokenProvider
16-
import software.aws.toolkits.core.credentials.sso.SsoCredentialProvider
1715
import software.aws.toolkits.jetbrains.core.AwsClientManager
1816
import software.aws.toolkits.jetbrains.core.credentials.SsoPrompt
1917
import software.aws.toolkits.jetbrains.core.credentials.diskCache
18+
import software.aws.toolkits.jetbrains.core.credentials.sso.SsoAccessTokenProvider
19+
import software.aws.toolkits.jetbrains.core.credentials.sso.SsoCredentialProvider
2020

2121
class ProfileSsoProvider(profile: Profile) : AwsCredentialsProvider, SdkAutoCloseable {
2222
private val ssoClient: SsoClient

core/src/software/aws/toolkits/core/credentials/sso/AccessToken.kt renamed to jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/AccessToken.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
1+
// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
package software.aws.toolkits.core.credentials.sso
4+
package software.aws.toolkits.jetbrains.core.credentials.sso
55

66
import software.amazon.awssdk.services.sso.SsoClient
77
import software.amazon.awssdk.services.ssooidc.SsoOidcClient

core/src/software/aws/toolkits/core/credentials/sso/Authorization.kt renamed to jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/Authorization.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
package software.aws.toolkits.core.credentials.sso
4+
package software.aws.toolkits.jetbrains.core.credentials.sso
55

66
import software.amazon.awssdk.services.ssooidc.SsoOidcClient
77
import java.time.Instant

core/src/software/aws/toolkits/core/credentials/sso/ClientRegistration.kt renamed to jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/ClientRegistration.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
package software.aws.toolkits.core.credentials.sso
4+
package software.aws.toolkits.jetbrains.core.credentials.sso
55

66
import software.amazon.awssdk.services.ssooidc.SsoOidcClient
77
import java.time.Instant

core/src/software/aws/toolkits/core/credentials/sso/DiskCache.kt renamed to jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/DiskCache.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
1+
// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
package software.aws.toolkits.core.credentials.sso
4+
package software.aws.toolkits.jetbrains.core.credentials.sso
55

66
import com.fasterxml.jackson.core.JsonParser
77
import com.fasterxml.jackson.databind.DeserializationContext

0 commit comments

Comments
 (0)