Skip to content

Commit decb082

Browse files
committed
refactor: simplify OAuth manager architecture and improve dependency injection
- remove ServiceLocator dependency from CoderToolboxContext - move OAuth manager creation to CoderToolboxExtension for cleaner separation - Refactor CoderOAuthManager to use configuration-based approach instead of constructor injection The idea behind these changes is that createRefreshConfig API does not receive a configuration object that can provide the client id and secret and even the refresh url. So initially we worked around the issue by passing the necessary data via the constructor. However this approach means a couple of things: - the actual auth manager can be created only at a very late stage, when a URL is provided by users - can't easily pass arround the auth manager without coupling the components - have to recreate a new auth manager instance if the user logs out and logs in to a different URL - service locator needs to be passed around because this is the actual factory of oauth managers in Toolbox Instead, we went with a differet approach, COderOAuthManager will derive and store the refresh configs once the authorization config is received. If the user logs out and logs in to a different URL the refresh data is also guaranteed to be updated. And on top of that - this approach allows us to get rid of all of the issues mentioned above.
1 parent 59d2abd commit decb082

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

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

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ package com.coder.toolbox
22

33
import com.coder.toolbox.oauth.CoderAccount
44
import com.coder.toolbox.oauth.CoderOAuthCfg
5-
import com.coder.toolbox.oauth.CoderOAuthManager
65
import com.coder.toolbox.store.CoderSecretsStore
76
import com.coder.toolbox.store.CoderSettingsStore
87
import com.coder.toolbox.util.toURL
9-
import com.jetbrains.toolbox.api.core.ServiceLocator
108
import com.jetbrains.toolbox.api.core.auth.PluginAuthManager
119
import com.jetbrains.toolbox.api.core.diagnostics.Logger
1210
import com.jetbrains.toolbox.api.core.os.LocalDesktopManager
@@ -23,7 +21,7 @@ import java.util.UUID
2321

2422
@Suppress("UnstableApiUsage")
2523
data class CoderToolboxContext(
26-
private val serviceLocator: ServiceLocator,
24+
val oauthManager: PluginAuthManager<CoderAccount, CoderOAuthCfg>,
2725
val ui: ToolboxUi,
2826
val envPageManager: EnvironmentUiPageManager,
2927
val envStateColorPalette: EnvironmentStateColorPalette,
@@ -53,14 +51,6 @@ data class CoderToolboxContext(
5351
?: settingsStore.defaultURL.toURL()
5452
}
5553

56-
fun getAuthManager(
57-
cfg: CoderOAuthCfg
58-
): PluginAuthManager<CoderAccount, CoderOAuthCfg> = serviceLocator.getAuthManager(
59-
accountClass = CoderAccount::class.java,
60-
displayName = "Coder Authentication",
61-
pluginAuthInterface = CoderOAuthManager(cfg)
62-
)
63-
6454
suspend fun logAndShowError(title: String, error: String) {
6555
logger.error(error)
6656
ui.showSnackbar(

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.coder.toolbox
22

3+
import com.coder.toolbox.oauth.CoderAccount
4+
import com.coder.toolbox.oauth.CoderOAuthManager
35
import com.coder.toolbox.settings.Environment
46
import com.coder.toolbox.store.CoderSecretsStore
57
import com.coder.toolbox.store.CoderSettingsStore
@@ -29,7 +31,11 @@ class CoderToolboxExtension : RemoteDevExtension {
2931
val logger = serviceLocator.getService(Logger::class.java)
3032
return CoderRemoteProvider(
3133
CoderToolboxContext(
32-
serviceLocator,
34+
serviceLocator.getAuthManager(
35+
CoderAccount::class.java,
36+
"Coder OAuth2 Manager",
37+
CoderOAuthManager()
38+
),
3339
serviceLocator.getService<ToolboxUi>(),
3440
serviceLocator.getService<EnvironmentUiPageManager>(),
3541
serviceLocator.getService<EnvironmentStateColorPalette>(),

src/main/kotlin/com/coder/toolbox/oauth/CoderOAuthManager.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import com.jetbrains.toolbox.api.core.auth.OAuthToken
77
import com.jetbrains.toolbox.api.core.auth.PluginAuthInterface
88
import com.jetbrains.toolbox.api.core.auth.RefreshConfiguration
99

10-
class CoderOAuthManager(private val cfg: CoderOAuthCfg) : PluginAuthInterface<CoderAccount, CoderOAuthCfg> {
10+
class CoderOAuthManager : PluginAuthInterface<CoderAccount, CoderOAuthCfg> {
11+
private lateinit var refreshConf: CoderRefreshConfig
12+
1113
override fun serialize(account: CoderAccount): String = "${account.id}|${account.fullName}"
1214

1315
override fun deserialize(string: String): CoderAccount = CoderAccount(
@@ -32,6 +34,7 @@ class CoderOAuthManager(private val cfg: CoderOAuthCfg) : PluginAuthInterface<Co
3234
override fun createAuthConfig(loginConfiguration: CoderOAuthCfg): AuthConfiguration {
3335
val codeVerifier = PKCEGenerator.generateCodeVerifier()
3436
val codeChallenge = PKCEGenerator.generateCodeChallenge(codeVerifier)
37+
refreshConf = loginConfiguration.toRefreshConf()
3538

3639
return AuthConfiguration(
3740
authParams = mapOf(
@@ -56,11 +59,11 @@ class CoderOAuthManager(private val cfg: CoderOAuthCfg) : PluginAuthInterface<Co
5659

5760
override fun createRefreshConfig(account: CoderAccount): RefreshConfiguration {
5861
return object : RefreshConfiguration {
59-
override val refreshUrl: String = cfg.tokenUrl
62+
override val refreshUrl: String = refreshConf.refreshUrl
6063
override val parameters: Map<String, String> = mapOf(
6164
"grant_type" to "refresh_token",
62-
"client_id" to cfg.clientId,
63-
"client_secret" to cfg.clientSecret
65+
"client_id" to refreshConf.clientId,
66+
"client_secret" to refreshConf.clientSecret
6467
)
6568
override val authorization: String? = null
6669
override val contentType: ContentType = FORM_URL_ENCODED
@@ -74,4 +77,16 @@ data class CoderOAuthCfg(
7477
val tokenUrl: String,
7578
val clientId: String,
7679
val clientSecret: String,
80+
)
81+
82+
private data class CoderRefreshConfig(
83+
val refreshUrl: String,
84+
val clientId: String,
85+
val clientSecret: String,
86+
)
87+
88+
private fun CoderOAuthCfg.toRefreshConf() = CoderRefreshConfig(
89+
refreshUrl = this.tokenUrl,
90+
clientId = this.clientId,
91+
this.clientSecret
7792
)

0 commit comments

Comments
 (0)