@@ -75,6 +75,7 @@ import java.awt.event.MouseListener
75
75
import java.awt.event.MouseMotionListener
76
76
import java.awt.font.TextAttribute
77
77
import java.awt.font.TextAttribute.UNDERLINE_ON
78
+ import java.net.SocketTimeoutException
78
79
import javax.swing.Icon
79
80
import javax.swing.JTable
80
81
import javax.swing.JTextField
@@ -214,12 +215,12 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
214
215
tfUrl = textField().resizableColumn().horizontalAlign(HorizontalAlign .FILL ).gap(RightGap .SMALL ).bindText(localWizardModel::coderURL).applyToComponent {
215
216
addActionListener {
216
217
poller?.cancel()
217
- askTokenAndOpenSession()
218
+ askTokenAndOpenSession(true )
218
219
}
219
220
}.component
220
221
button(CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.connect.text" )) {
221
222
poller?.cancel()
222
- askTokenAndOpenSession()
223
+ askTokenAndOpenSession(true )
223
224
}.applyToComponent {
224
225
background = WelcomeScreenUIManager .getMainAssociatedComponentBackground()
225
226
}
@@ -316,25 +317,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
316
317
localWizardModel.coderURL = url
317
318
localWizardModel.token = token
318
319
tfUrl?.text = url
319
-
320
- poller?.cancel()
321
- try {
322
- coderClient.initClientSession(url.toURL(), token)
323
- loginAndLoadWorkspace(token)
324
- } catch (e: Exception ) {
325
- when (e) {
326
- is AuthenticationResponseException -> {
327
- // probably the token is expired
328
- askTokenAndOpenSession()
329
- }
330
-
331
- else -> {
332
- logger.warn(" An exception was encountered while opening ${localWizardModel.coderURL} . Reason: ${e.message} " )
333
- localWizardModel.token = " "
334
- }
335
- }
336
-
337
- }
320
+ loginAndLoadWorkspace(token, true )
338
321
}
339
322
}
340
323
updateWorkspaceActions()
@@ -372,49 +355,44 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
372
355
ActivityTracker .getInstance().inc()
373
356
}
374
357
375
- private fun askTokenAndOpenSession () {
358
+ private fun askTokenAndOpenSession (openBrowser : Boolean ) {
376
359
// force bindings to be filled
377
360
component.apply ()
378
361
379
- val pastedToken = askToken()
362
+ val pastedToken = askToken(openBrowser )
380
363
if (pastedToken.isNullOrBlank()) {
381
364
return
382
365
}
383
- loginAndLoadWorkspace(pastedToken)
366
+ // False so that subsequent authentication failures do not keep opening
367
+ // the browser as it was already opened earlier.
368
+ loginAndLoadWorkspace(pastedToken, false )
384
369
}
385
370
386
- private fun loginAndLoadWorkspace (token : String ) {
387
- try {
388
- coderClient.initClientSession(localWizardModel.coderURL.toURL(), token)
389
- if (! CoderSemVer .isValidVersion(coderClient.buildVersion)) {
390
- notificationBanner.apply {
391
- component.isVisible = true
392
- showWarning(CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.invalid.coder.version" , coderClient.buildVersion))
393
- }
394
- } else {
395
- val coderVersion = CoderSemVer .parse(coderClient.buildVersion)
396
- if (! coderVersion.isInClosedRange(CoderSupportedVersions .minCompatibleCoderVersion, CoderSupportedVersions .maxCompatibleCoderVersion)) {
397
- notificationBanner.apply {
398
- component.isVisible = true
399
- showWarning(CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.unsupported.coder.version" , coderClient.buildVersion))
400
- }
401
- }
371
+ private fun loginAndLoadWorkspace (token : String , openBrowser : Boolean ) {
372
+ LifetimeDefinition ().launchUnderBackgroundProgress(CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.cli.downloader.dialog.title" ), canBeCancelled = false , isIndeterminate = true ) {
373
+ this .indicator.apply {
374
+ text = " Authenticating..."
402
375
}
403
- } catch (e: AuthenticationResponseException ) {
404
- logger.error(" Could not authenticate on ${localWizardModel.coderURL} . Reason $e " )
405
- return
406
- }
407
- appPropertiesService.setValue(CODER_URL_KEY , localWizardModel.coderURL)
408
- appPropertiesService.setValue(SESSION_TOKEN , token)
409
- val cliManager = CoderCLIManager (localWizardModel.coderURL.toURL(), coderClient.buildVersion)
410
376
411
- localWizardModel.apply {
412
- this .token = token
413
- buildVersion = coderClient.buildVersion
414
- localCliPath = cliManager.localCli.toAbsolutePath().toString()
415
- }
377
+ try {
378
+ authenticate(token)
379
+ } catch (e: AuthenticationResponseException ) {
380
+ logger.error(" Unable to authenticate to ${localWizardModel.coderURL} ; has your token expired?" , e)
381
+ askTokenAndOpenSession(openBrowser)
382
+ return @launchUnderBackgroundProgress
383
+ } catch (e: SocketTimeoutException ) {
384
+ logger.error(" Unable to connect to ${localWizardModel.coderURL} ; is it up?" , e)
385
+ return @launchUnderBackgroundProgress
386
+ }
387
+
388
+ val cliManager = CoderCLIManager (localWizardModel.coderURL.toURL(), coderClient.buildVersion)
389
+
390
+ localWizardModel.apply {
391
+ this .token = token
392
+ buildVersion = coderClient.buildVersion
393
+ localCliPath = cliManager.localCli.toAbsolutePath().toString()
394
+ }
416
395
417
- LifetimeDefinition ().launchUnderBackgroundProgress(CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.cli.downloader.dialog.title" ), canBeCancelled = false , isIndeterminate = true ) {
418
396
this .indicator.apply {
419
397
isIndeterminate = false
420
398
text = " Retrieving Workspaces..."
@@ -458,15 +436,18 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
458
436
}
459
437
}
460
438
461
- private fun askToken (): String? {
462
- BrowserUtil .browse(localWizardModel.coderURL.toURL().withPath(" /login?redirect=%2Fcli-auth" ))
439
+ private fun askToken (openBrowser : Boolean ): String? {
440
+ val getTokenUrl = localWizardModel.coderURL.toURL().withPath(" /login?redirect=%2Fcli-auth" )
441
+ if (openBrowser) {
442
+ BrowserUtil .browse(getTokenUrl)
443
+ }
463
444
return invokeAndWaitIfNeeded(ModalityState .any()) {
464
445
lateinit var sessionTokenTextField: JBTextField
465
446
466
447
val panel = panel {
467
448
row {
468
- label (CoderGatewayBundle .message(" gateway.connector.view.login.token.label" ))
469
- sessionTokenTextField = textField().applyToComponent {
449
+ browserLink (CoderGatewayBundle .message(" gateway.connector.view.login.token.label" ), getTokenUrl.toString( ))
450
+ sessionTokenTextField = textField().bindText(localWizardModel::token). applyToComponent {
470
451
minimumSize = Dimension (320 , - 1 )
471
452
}.component
472
453
}
@@ -491,6 +472,33 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
491
472
}
492
473
}
493
474
475
+ /* *
476
+ * Check that the token is valid for the URL in the wizard and throw if not.
477
+ * On success store the URL and token and display warning banners if
478
+ * versions do not match.
479
+ */
480
+ private fun authenticate (token : String ) {
481
+ coderClient.initClientSession(localWizardModel.coderURL.toURL(), token)
482
+
483
+ if (! CoderSemVer .isValidVersion(coderClient.buildVersion)) {
484
+ notificationBanner.apply {
485
+ component.isVisible = true
486
+ showWarning(CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.invalid.coder.version" , coderClient.buildVersion))
487
+ }
488
+ } else {
489
+ val coderVersion = CoderSemVer .parse(coderClient.buildVersion)
490
+ if (! coderVersion.isInClosedRange(CoderSupportedVersions .minCompatibleCoderVersion, CoderSupportedVersions .maxCompatibleCoderVersion)) {
491
+ notificationBanner.apply {
492
+ component.isVisible = true
493
+ showWarning(CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.unsupported.coder.version" , coderClient.buildVersion))
494
+ }
495
+ }
496
+ }
497
+
498
+ appPropertiesService.setValue(CODER_URL_KEY , localWizardModel.coderURL)
499
+ appPropertiesService.setValue(SESSION_TOKEN , token)
500
+ }
501
+
494
502
private suspend fun loadWorkspaces () {
495
503
val ws = withContext(Dispatchers .IO ) {
496
504
val timeBeforeRequestingWorkspaces = System .currentTimeMillis()
@@ -809,4 +817,4 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
809
817
companion object {
810
818
val logger = Logger .getInstance(CoderWorkspacesStepView ::class .java.simpleName)
811
819
}
812
- }
820
+ }
0 commit comments