Skip to content

Commit 3a8738c

Browse files
committed
refactor: expose typed settings and secrets store
- instead of the raw interfaces - this prepares the plugin for the next stage where some of the settings are read by the URI handling component.
1 parent 6a3491d commit 3a8738c

File tree

6 files changed

+59
-57
lines changed

6 files changed

+59
-57
lines changed

src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt

+12-16
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package com.coder.toolbox
33
import com.coder.toolbox.cli.CoderCLIManager
44
import com.coder.toolbox.sdk.CoderRestClient
55
import com.coder.toolbox.sdk.v2.models.WorkspaceStatus
6-
import com.coder.toolbox.services.CoderSecretsService
7-
import com.coder.toolbox.services.CoderSettingsService
86
import com.coder.toolbox.settings.CoderSettings
97
import com.coder.toolbox.settings.Source
108
import com.coder.toolbox.util.CoderProtocolHandler
@@ -47,10 +45,8 @@ class CoderRemoteProvider(
4745
private var lastEnvironments: Set<CoderRemoteEnvironment>? = null
4846

4947
// Create our services from the Toolbox ones.
50-
private val settingsService = CoderSettingsService(context.settingsStore)
51-
private val settings: CoderSettings = CoderSettings(settingsService, context.logger)
52-
private val secrets: CoderSecretsService = CoderSecretsService(context.secretsStore)
53-
private val settingsPage: CoderSettingsPage = CoderSettingsPage(context, settingsService)
48+
private val settings: CoderSettings = CoderSettings(context.settings, context.logger)
49+
private val settingsPage: CoderSettingsPage = CoderSettingsPage(context)
5450
private val dialogUi = DialogUi(context, settings)
5551

5652
// The REST client, if we are signed in
@@ -151,7 +147,7 @@ class CoderRemoteProvider(
151147
private fun logout() {
152148
// Keep the URL and token to make it easy to log back in, but set
153149
// rememberMe to false so we do not try to automatically log in.
154-
secrets.rememberMe = "false"
150+
context.secrets.rememberMe = "false"
155151
close()
156152
}
157153

@@ -272,8 +268,8 @@ class CoderRemoteProvider(
272268
// When coming back to the application, authenticate immediately.
273269
val autologin = shouldDoAutoLogin()
274270
var autologinEx: Exception? = null
275-
secrets.lastToken.let { lastToken ->
276-
secrets.lastDeploymentURL.let { lastDeploymentURL ->
271+
context.secrets.lastToken.let { lastToken ->
272+
context.secrets.lastDeploymentURL.let { lastDeploymentURL ->
277273
if (autologin && lastDeploymentURL.isNotBlank() && (lastToken.isNotBlank() || !settings.requireTokenAuth)) {
278274
try {
279275
return createConnectPage(URL(lastDeploymentURL), lastToken)
@@ -309,7 +305,7 @@ class CoderRemoteProvider(
309305
return null
310306
}
311307

312-
private fun shouldDoAutoLogin(): Boolean = firstRun && secrets.rememberMe == "true"
308+
private fun shouldDoAutoLogin(): Boolean = firstRun && context.secrets.rememberMe == "true"
313309

314310
/**
315311
* Create a connect page that starts polling and resets the UI on success.
@@ -323,10 +319,10 @@ class CoderRemoteProvider(
323319
::goToEnvironmentsPage,
324320
) { client, cli ->
325321
// Store the URL and token for use next time.
326-
secrets.lastDeploymentURL = client.url.toString()
327-
secrets.lastToken = client.token ?: ""
322+
context.secrets.lastDeploymentURL = client.url.toString()
323+
context.secrets.lastToken = client.token ?: ""
328324
// Currently we always remember, but this could be made an option.
329-
secrets.rememberMe = "true"
325+
context.secrets.rememberMe = "true"
330326
this.client = client
331327
pollError = null
332328
pollJob?.cancel()
@@ -343,8 +339,8 @@ class CoderRemoteProvider(
343339
* 2. Token on disk for this deployment.
344340
* 3. Global token for Coder, if it matches the deployment.
345341
*/
346-
private fun getToken(deploymentURL: URL): Pair<String, Source>? = secrets.lastToken.let {
347-
if (it.isNotBlank() && secrets.lastDeploymentURL == deploymentURL.toString()) {
342+
private fun getToken(deploymentURL: URL): Pair<String, Source>? = context.secrets.lastToken.let {
343+
if (it.isNotBlank() && context.secrets.lastDeploymentURL == deploymentURL.toString()) {
348344
it to Source.LAST_USED
349345
} else {
350346
settings.token(deploymentURL)
@@ -361,7 +357,7 @@ class CoderRemoteProvider(
361357
* 3. CODER_URL.
362358
* 4. URL in global cli config.
363359
*/
364-
private fun getDeploymentURL(): Pair<String, Source>? = secrets.lastDeploymentURL.let {
360+
private fun getDeploymentURL(): Pair<String, Source>? = context.secrets.lastDeploymentURL.let {
365361
if (it.isNotBlank()) {
366362
it to Source.LAST_USED
367363
} else {

src/main/kotlin/com/coder/toolbox/CoderToolboxContext.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.coder.toolbox
22

3-
import com.jetbrains.toolbox.api.core.PluginSecretStore
4-
import com.jetbrains.toolbox.api.core.PluginSettingsStore
3+
import com.coder.toolbox.services.CoderSecretsService
4+
import com.coder.toolbox.services.CoderSettingsService
55
import com.jetbrains.toolbox.api.core.diagnostics.Logger
66
import com.jetbrains.toolbox.api.localization.LocalizableStringFactory
77
import com.jetbrains.toolbox.api.remoteDev.connection.ClientHelper
@@ -18,6 +18,6 @@ data class CoderToolboxContext(
1818
val cs: CoroutineScope,
1919
val logger: Logger,
2020
val i18n: LocalizableStringFactory,
21-
val settingsStore: PluginSettingsStore,
22-
val secretsStore: PluginSecretStore
21+
val settings: CoderSettingsService,
22+
val secrets: CoderSecretsService
2323
)

src/main/kotlin/com/coder/toolbox/CoderToolboxExtension.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.coder.toolbox
22

3+
import com.coder.toolbox.services.CoderSecretsService
4+
import com.coder.toolbox.services.CoderSettingsService
35
import com.jetbrains.toolbox.api.core.PluginSecretStore
46
import com.jetbrains.toolbox.api.core.PluginSettingsStore
57
import com.jetbrains.toolbox.api.core.ServiceLocator
@@ -29,8 +31,8 @@ class CoderToolboxExtension : RemoteDevExtension {
2931
serviceLocator.getService(CoroutineScope::class.java),
3032
serviceLocator.getService(Logger::class.java),
3133
serviceLocator.getService(LocalizableStringFactory::class.java),
32-
serviceLocator.getService(PluginSettingsStore::class.java),
33-
serviceLocator.getService(PluginSecretStore::class.java),
34+
CoderSettingsService(serviceLocator.getService(PluginSettingsStore::class.java)),
35+
CoderSecretsService(serviceLocator.getService(PluginSecretStore::class.java)),
3436
),
3537
OkHttpClient(),
3638
)

src/main/kotlin/com/coder/toolbox/views/CoderSettingsPage.kt

+31-27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.coder.toolbox.views
22

33
import com.coder.toolbox.CoderToolboxContext
4-
import com.coder.toolbox.services.CoderSettingsService
54
import com.jetbrains.toolbox.api.ui.actions.RunnableActionDescription
65
import com.jetbrains.toolbox.api.ui.components.CheckboxField
76
import com.jetbrains.toolbox.api.ui.components.TextField
@@ -17,28 +16,33 @@ import kotlinx.coroutines.flow.StateFlow
1716
* TODO@JB: There is no scroll, and our settings do not fit. As a consequence,
1817
* I have not been able to test this page.
1918
*/
20-
class CoderSettingsPage(
21-
context: CoderToolboxContext,
22-
private val settings: CoderSettingsService,
23-
) : CoderPage(context, context.i18n.ptrl("Coder Settings"), false) {
19+
class CoderSettingsPage(context: CoderToolboxContext) : CoderPage(context, context.i18n.ptrl("Coder Settings"), false) {
2420
// TODO: Copy over the descriptions, holding until I can test this page.
2521
private val binarySourceField =
26-
TextField(context.i18n.ptrl("Binary source"), settings.binarySource, TextType.General)
22+
TextField(context.i18n.ptrl("Binary source"), context.settings.binarySource, TextType.General)
2723
private val binaryDirectoryField =
28-
TextField(context.i18n.ptrl("Binary directory"), settings.binaryDirectory, TextType.General)
24+
TextField(context.i18n.ptrl("Binary directory"), context.settings.binaryDirectory, TextType.General)
2925
private val dataDirectoryField =
30-
TextField(context.i18n.ptrl("Data directory"), settings.dataDirectory, TextType.General)
31-
private val enableDownloadsField = CheckboxField(settings.enableDownloads, context.i18n.ptrl("Enable downloads"))
26+
TextField(context.i18n.ptrl("Data directory"), context.settings.dataDirectory, TextType.General)
27+
private val enableDownloadsField =
28+
CheckboxField(context.settings.enableDownloads, context.i18n.ptrl("Enable downloads"))
3229
private val enableBinaryDirectoryFallbackField =
33-
CheckboxField(settings.enableBinaryDirectoryFallback, context.i18n.ptrl("Enable binary directory fallback"))
30+
CheckboxField(
31+
context.settings.enableBinaryDirectoryFallback,
32+
context.i18n.ptrl("Enable binary directory fallback")
33+
)
3434
private val headerCommandField =
35-
TextField(context.i18n.ptrl("Header command"), settings.headerCommand, TextType.General)
36-
private val tlsCertPathField = TextField(context.i18n.ptrl("TLS cert path"), settings.tlsCertPath, TextType.General)
37-
private val tlsKeyPathField = TextField(context.i18n.ptrl("TLS key path"), settings.tlsKeyPath, TextType.General)
38-
private val tlsCAPathField = TextField(context.i18n.ptrl("TLS CA path"), settings.tlsCAPath, TextType.General)
35+
TextField(context.i18n.ptrl("Header command"), context.settings.headerCommand, TextType.General)
36+
private val tlsCertPathField =
37+
TextField(context.i18n.ptrl("TLS cert path"), context.settings.tlsCertPath, TextType.General)
38+
private val tlsKeyPathField =
39+
TextField(context.i18n.ptrl("TLS key path"), context.settings.tlsKeyPath, TextType.General)
40+
private val tlsCAPathField =
41+
TextField(context.i18n.ptrl("TLS CA path"), context.settings.tlsCAPath, TextType.General)
3942
private val tlsAlternateHostnameField =
40-
TextField(context.i18n.ptrl("TLS alternate hostname"), settings.tlsAlternateHostname, TextType.General)
41-
private val disableAutostartField = CheckboxField(settings.disableAutostart, context.i18n.ptrl("Disable autostart"))
43+
TextField(context.i18n.ptrl("TLS alternate hostname"), context.settings.tlsAlternateHostname, TextType.General)
44+
private val disableAutostartField =
45+
CheckboxField(context.settings.disableAutostart, context.i18n.ptrl("Disable autostart"))
4246

4347
override val fields: StateFlow<List<UiField>> = MutableStateFlow(
4448
listOf(
@@ -59,17 +63,17 @@ class CoderSettingsPage(
5963
override val actionButtons: StateFlow<List<RunnableActionDescription>> = MutableStateFlow(
6064
listOf(
6165
Action(context.i18n.ptrl("Save"), closesPage = true) {
62-
settings.binarySource = binarySourceField.textState.value
63-
settings.binaryDirectory = binaryDirectoryField.textState.value
64-
settings.dataDirectory = dataDirectoryField.textState.value
65-
settings.enableDownloads = enableDownloadsField.checkedState.value
66-
settings.enableBinaryDirectoryFallback = enableBinaryDirectoryFallbackField.checkedState.value
67-
settings.headerCommand = headerCommandField.textState.value
68-
settings.tlsCertPath = tlsCertPathField.textState.value
69-
settings.tlsKeyPath = tlsKeyPathField.textState.value
70-
settings.tlsCAPath = tlsCAPathField.textState.value
71-
settings.tlsAlternateHostname = tlsAlternateHostnameField.textState.value
72-
settings.disableAutostart = disableAutostartField.checkedState.value
66+
context.settings.binarySource = binarySourceField.textState.value
67+
context.settings.binaryDirectory = binaryDirectoryField.textState.value
68+
context.settings.dataDirectory = dataDirectoryField.textState.value
69+
context.settings.enableDownloads = enableDownloadsField.checkedState.value
70+
context.settings.enableBinaryDirectoryFallback = enableBinaryDirectoryFallbackField.checkedState.value
71+
context.settings.headerCommand = headerCommandField.textState.value
72+
context.settings.tlsCertPath = tlsCertPathField.textState.value
73+
context.settings.tlsKeyPath = tlsKeyPathField.textState.value
74+
context.settings.tlsCAPath = tlsCAPathField.textState.value
75+
context.settings.tlsAlternateHostname = tlsAlternateHostnameField.textState.value
76+
context.settings.disableAutostart = disableAutostartField.checkedState.value
7377
},
7478
)
7579
)

src/test/kotlin/com/coder/toolbox/cli/CoderCLIManagerTest.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import com.coder.toolbox.CoderToolboxContext
44
import com.coder.toolbox.cli.ex.MissingVersionException
55
import com.coder.toolbox.cli.ex.ResponseException
66
import com.coder.toolbox.cli.ex.SSHConfigFormatException
7+
import com.coder.toolbox.services.CoderSecretsService
8+
import com.coder.toolbox.services.CoderSettingsService
79
import com.coder.toolbox.settings.CODER_SSH_CONFIG_OPTIONS
810
import com.coder.toolbox.settings.CoderSettings
911
import com.coder.toolbox.settings.CoderSettingsState
@@ -15,8 +17,6 @@ import com.coder.toolbox.util.escape
1517
import com.coder.toolbox.util.getOS
1618
import com.coder.toolbox.util.sha1
1719
import com.coder.toolbox.util.toURL
18-
import com.jetbrains.toolbox.api.core.PluginSecretStore
19-
import com.jetbrains.toolbox.api.core.PluginSettingsStore
2020
import com.jetbrains.toolbox.api.core.diagnostics.Logger
2121
import com.jetbrains.toolbox.api.localization.LocalizableStringFactory
2222
import com.jetbrains.toolbox.api.remoteDev.connection.ClientHelper
@@ -53,8 +53,8 @@ internal class CoderCLIManagerTest {
5353
mockk<CoroutineScope>(),
5454
mockk<Logger>(relaxed = true),
5555
mockk<LocalizableStringFactory>(),
56-
mockk<PluginSettingsStore>(),
57-
mockk<PluginSecretStore>()
56+
mockk<CoderSettingsService>(),
57+
mockk<CoderSecretsService>()
5858
)
5959

6060
/**

src/test/kotlin/com/coder/toolbox/sdk/CoderRestClientTest.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import com.coder.toolbox.sdk.v2.models.WorkspaceBuild
1313
import com.coder.toolbox.sdk.v2.models.WorkspaceResource
1414
import com.coder.toolbox.sdk.v2.models.WorkspaceTransition
1515
import com.coder.toolbox.sdk.v2.models.WorkspacesResponse
16+
import com.coder.toolbox.services.CoderSecretsService
17+
import com.coder.toolbox.services.CoderSettingsService
1618
import com.coder.toolbox.settings.CoderSettings
1719
import com.coder.toolbox.settings.CoderSettingsState
1820
import com.coder.toolbox.util.sslContextFromPEMs
19-
import com.jetbrains.toolbox.api.core.PluginSecretStore
20-
import com.jetbrains.toolbox.api.core.PluginSettingsStore
2121
import com.jetbrains.toolbox.api.core.diagnostics.Logger
2222
import com.jetbrains.toolbox.api.localization.LocalizableStringFactory
2323
import com.jetbrains.toolbox.api.remoteDev.connection.ClientHelper
@@ -100,8 +100,8 @@ class CoderRestClientTest {
100100
mockk<CoroutineScope>(),
101101
mockk<Logger>(relaxed = true),
102102
mockk<LocalizableStringFactory>(),
103-
mockk<PluginSettingsStore>(),
104-
mockk<PluginSecretStore>()
103+
mockk<CoderSettingsService>(),
104+
mockk<CoderSecretsService>()
105105
)
106106

107107
data class TestWorkspace(var workspace: Workspace, var resources: List<WorkspaceResource>? = emptyList())

0 commit comments

Comments
 (0)