Skip to content

Commit 0036234

Browse files
authored
Move off deprecated OAuth platform APIs and surface service authorization_grant errors (#4474)
1 parent 480bcc6 commit 0036234

File tree

1 file changed

+29
-9
lines changed
  • plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/pkce

1 file changed

+29
-9
lines changed

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/pkce/ToolkitOAuthService.kt

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package software.aws.toolkits.jetbrains.core.credentials.sso.pkce
66
import com.intellij.collaboration.auth.OAuthCallbackHandlerBase
77
import com.intellij.collaboration.auth.services.OAuthCredentialsAcquirer
88
import com.intellij.collaboration.auth.services.OAuthRequest
9+
import com.intellij.collaboration.auth.services.OAuthService
910
import com.intellij.collaboration.auth.services.OAuthServiceBase
1011
import com.intellij.collaboration.auth.services.PkceUtils
1112
import com.intellij.openapi.application.ApplicationNamesInfo
@@ -61,17 +62,23 @@ class ToolkitOAuthService : OAuthServiceBase<AccessToken>() {
6162
return authorize(ToolkitOAuthRequest(registration))
6263
}
6364

64-
override fun handleServerCallback(path: String, parameters: Map<String, List<String>>): Boolean {
65-
val request = currentRequest.get() ?: return false
66-
val toolkitRequest = request.request as? ToolkitOAuthRequest ?: return false
65+
override fun handleOAuthServerCallback(path: String, parameters: Map<String, List<String>>): OAuthService.OAuthResult<AccessToken>? {
66+
val request = currentRequest.get() ?: return OAuthService.OAuthResult(null, false)
67+
val toolkitRequest = request.request as? ToolkitOAuthRequest ?: return OAuthService.OAuthResult(request.request, false)
6768

6869
val callbackState = parameters["state"]?.firstOrNull()
6970
if (toolkitRequest.csrfToken != callbackState) {
7071
request.result.completeExceptionally(RuntimeException("Invalid CSRF token"))
71-
return false
72+
return OAuthService.OAuthResult(toolkitRequest, false)
73+
}
74+
75+
if (parameters["code"] == null) {
76+
val error = parameters["error"]?.firstOrNull()
77+
val errorDescription = parameters["error_description"]?.firstOrNull()
78+
toolkitRequest.error = OAuthError(error = error, errorDescription = errorDescription)
7279
}
7380

74-
return super.handleServerCallback(path, parameters)
81+
return super.handleOAuthServerCallback(path, parameters)
7582
}
7683

7784
override fun revokeToken(token: String) {
@@ -83,6 +90,11 @@ class ToolkitOAuthService : OAuthServiceBase<AccessToken>() {
8390
}
8491
}
8592

93+
private data class OAuthError(
94+
val error: String?,
95+
val errorDescription: String?
96+
)
97+
8698
private class ToolkitOAuthRequest(internal val registration: PKCEClientRegistration) : OAuthRequest<AccessToken> {
8799
private val port: Int get() = BuiltInServerManager.getInstance().port
88100
private val base64Encoder = Base64.getUrlEncoder().withoutPadding()
@@ -120,6 +132,8 @@ private class ToolkitOAuthRequest(internal val registration: PKCEClientRegistrat
120132
)
121133

122134
private fun randB64url(bits: Int): String = base64Encoder.encodeToString(BigInteger(bits, DigestUtil.random).toByteArray())
135+
136+
internal var error: OAuthError? = null
123137
}
124138

125139
// exchange for real token
@@ -157,7 +171,7 @@ internal class ToolkitOAuthCallbackHandler : OAuthCallbackHandlerBase() {
157171
override fun oauthService() = ToolkitOAuthService.getInstance()
158172

159173
// on success / fail
160-
override fun handleAcceptCode(isAccepted: Boolean): AcceptCodeHandleResult {
174+
override fun handleOAuthResult(oAuthResult: OAuthService.OAuthResult<*>): AcceptCodeHandleResult {
161175
// focus should be on requesting component?
162176
runInEdt {
163177
IdeFocusManager.getGlobalInstance().getLastFocusedIdeWindow()?.toFront()
@@ -166,16 +180,22 @@ internal class ToolkitOAuthCallbackHandler : OAuthCallbackHandlerBase() {
166180
val urlBase = newFromEncoded(
167181
"http://127.0.0.1:${BuiltInServerManager.getInstance().port}/api/${ToolkitOAuthCallbackResultService.SERVICE_NAME}/index.html"
168182
)
169-
val params = if (isAccepted) {
183+
val params = if (oAuthResult.isAccepted) {
170184
mapOf(
171185
"productName" to PKCE_CLIENT_NAME,
172186
// we don't have the request context to get the requested scopes in this callback until 233
173187
"scopes" to ApplicationNamesInfo.getInstance().fullProductName
174188
)
175189
} else {
190+
val (error, errorDescription) = (oAuthResult.request as? ToolkitOAuthRequest)?.error ?: OAuthError(null, null)
191+
val errorString = if (error != null && errorDescription != null) {
192+
"$error: $errorDescription"
193+
} else {
194+
errorDescription ?: error ?: message("general.unknown_error")
195+
}
196+
176197
mapOf(
177-
// when 233, check if we can retrieve the underlying error
178-
"error" to message("general.unknown_error")
198+
"error" to errorString
179199
)
180200
}
181201

0 commit comments

Comments
 (0)