Skip to content

Commit

Permalink
Show actual error in token dialog
Browse files Browse the repository at this point in the history
Technically we only retried on auth failure so the hardcoded error
message should be correct, but seems better to relay the actual error
message.
  • Loading branch information
code-asher committed Sep 10, 2024
1 parent 4f4a1f6 commit ac91ba5
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 30 deletions.
27 changes: 12 additions & 15 deletions src/main/kotlin/com/coder/gateway/util/Dialogs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ class DialogUi(
* Open a dialog for providing the token. Show any existing token so
* the user can validate it if a previous connection failed.
*
* If we are not retrying and the user has not checked the existing
* token box then also open a browser to the auth page.
* If we have not already tried once (no error) and the user has not checked
* the existing token box then also open a browser to the auth page.
*
* If the user has checked the existing token box then return the token
* on disk immediately and skip the dialog (this will overwrite any
Expand All @@ -182,16 +182,16 @@ class DialogUi(
fun askToken(
url: URL,
token: Pair<String, Source>?,
isRetry: Boolean,
useExisting: Boolean,
error: String?,
): Pair<String, Source>? {
val getTokenUrl = url.withPath("/login?redirect=%2Fcli-auth")

// On the first run either open a browser to generate a new token
// or, if using an existing token, use the token on disk if it
// exists otherwise assume the user already copied an existing
// token and they will paste in.
if (!isRetry) {
// On the first run (no error) either open a browser to generate a new
// token or, if using an existing token, use the token on disk if it
// exists otherwise assume the user already copied an existing token and
// they will paste in.
if (error == null) {
if (!useExisting) {
openUrl(getTokenUrl)
} else {
Expand All @@ -209,15 +209,12 @@ class DialogUi(
val tokenFromUser =
ask(
title = "Session Token",
description = if (isRetry) {
"This token was rejected by ${url.host}."
} else {
token?.second?.description("token", url)
?: "No existing token for ${url.host} found."
},
description = error
?: token?.second?.description("token", url)
?: "No existing token for ${url.host} found.",
placeholder = token?.first,
link = Pair("Session Token:", getTokenUrl.toString()),
isError = isRetry,
isError = error != null,
)
if (tokenFromUser.isNullOrBlank()) {
return null
Expand Down
17 changes: 9 additions & 8 deletions src/main/kotlin/com/coder/gateway/util/LinkHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,20 @@ open class LinkHandler(
private fun authenticate(
deploymentURL: String,
tryToken: Pair<String, Source>?,
lastToken: Pair<String, Source>? = null,
error: String? = null,
): CoderRestClient {
val token =
if (settings.requireTokenAuth) {
// Try the provided token, unless we already did.
val isRetry = lastToken != null
if (tryToken != null && !isRetry) {
// Try the provided token immediately on the first attempt.
if (tryToken != null && error == null) {
tryToken
} else {
// Otherwise ask for a new token, showing the previous token.
dialogUi.askToken(
deploymentURL.toURL(),
lastToken,
isRetry,
true,
tryToken,
useExisting = true,
error,
)
}
} else {
Expand All @@ -175,7 +175,8 @@ open class LinkHandler(
} catch (ex: APIResponseException) {
// If doing token auth we can ask and try again.
if (settings.requireTokenAuth && ex.isUnauthorized) {
authenticate(deploymentURL, tryToken, token)
val msg = humanizeConnectionError(client.url, true, ex)
authenticate(deploymentURL, token, msg)
} else {
throw ex
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -508,10 +508,10 @@ class CoderWorkspacesStepView :
* Ask for a new token if token auth is required (regardless of whether we
* already have a token), place it in the local fields model, then connect.
*
* If the token is invalid abort and start over from askTokenAndConnect()
* unless retry is false.
* If the token is invalid try again until the user aborts or we get a valid
* token. Any other error will not be retried.
*/
private fun maybeAskTokenThenConnect(isRetry: Boolean = false) {
private fun maybeAskTokenThenConnect(error: String? = null) {
val oldURL = fields.coderURL
component.apply() // Force bindings to be filled.
val newURL = fields.coderURL.toURL()
Expand All @@ -522,12 +522,12 @@ class CoderWorkspacesStepView :
// If this is a new URL there is no point in trying to use the same
// token.
if (oldURL == newURL.toString()) fields.token else null,
isRetry,
fields.useExistingToken,
error,
) ?: return // User aborted.
fields.token = pastedToken
connect(newURL, pastedToken.first) {
maybeAskTokenThenConnect(true)
maybeAskTokenThenConnect(it)
}
} else {
connect(newURL, null)
Expand All @@ -551,7 +551,7 @@ class CoderWorkspacesStepView :
private fun connect(
deploymentURL: URL,
token: String?,
onAuthFailure: (() -> Unit)? = null,
onAuthFailure: ((error: String) -> Unit)? = null,
): Job {
tfUrlComment?.foreground = UIUtil.getContextHelpForeground()
tfUrlComment?.text =
Expand Down Expand Up @@ -640,7 +640,7 @@ class CoderWorkspacesStepView :
logger.error(msg, e)

if (e is APIResponseException && e.isUnauthorized && onAuthFailure != null) {
onAuthFailure.invoke()
onAuthFailure.invoke(msg)
}
}
}
Expand Down

0 comments on commit ac91ba5

Please sign in to comment.