Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitec7753b

Browse files
authored
impl: support for using proxies to access Coder REST API (#89)
- proxy credentials are not yet supported as they were not exposed inToolbox settings- system and manual proxy configuration supported.- manual tests included system wide settings and manual http settings.-resolves#39
1 parent1792901 commitec7753b

File tree

10 files changed

+118
-66
lines changed

10 files changed

+118
-66
lines changed

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
##Unreleased
44

5+
###Added
6+
7+
- support for using proxies. Proxy authentication is not yet supported.
8+
59
##0.1.5 - 2025-04-14
610

711
###Fixed

‎README.md‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,42 @@ If `ide_product_code` and `ide_build_number` is missing, Toolbox will only open
101101
page. Coder Toolbox will attempt to start the workspace if it’s not already running; however, for the most reliable
102102
experience, it’s recommended to ensure the workspace is running prior to initiating the connection.
103103

104+
##Configuring and Testing workspace polling with HTTP & SOCKS5 Proxy
105+
106+
This section explains how to set up a local proxy (without authentication which is not yet supported) and verify that
107+
the plugin’s REST client works correctly when routed through it.
108+
109+
We’ll use[mitmproxy](https://mitmproxy.org/) for this — it can act as both an HTTP and SOCKS5 proxy with SSL
110+
interception.
111+
112+
###Install mitmproxy
113+
114+
1. Follow the[mitmproxy Install Guide](https://docs.mitmproxy.org/stable/overview-installation/) steps for your OS.
115+
2. Start the proxy:
116+
117+
```bash
118+
119+
mitmweb --ssl-insecure --set stream_large_bodies="10m"
120+
```
121+
122+
###Configure Mitmproxy
123+
124+
mitmproxy can do HTTP and SOCKS5 proxying. To configure one or the other:
125+
126+
1. Openhttp://127.0.0.1:8081 in browser;
127+
2. Navigate to`Options -> Edit Options`
128+
3. Update the`Mode` field to`regular` in order to activate HTTP/HTTPS or to`socks5`
129+
4. Proxy authentication can be enabled by updating the`proxyauth` to`username:password`
130+
131+
###Configure Proxy in Toolbox
132+
133+
1. Start Toolbox
134+
2. From Toolbox hexagonal menu icon go to`Settings -> Proxy`
135+
3. There are two options, to use system proxy settings or to manually configure the proxy details.
136+
4. If we go manually, add`127.0.0.1` to the host and port`8080` for HTTP/HTTPS or`1080` for SOCKS5.
137+
5. Before authenticating to the Coder deployment we need to tell the plugin where can we find mitmproxy
138+
certificates. In Coder's Settings page, set the`TLS CA path` to`~/.mitmproxy/mitmproxy-ca-cert.pem`
139+
104140
##Releasing
105141

106142
1. Check that the changelog lists all the important changes.

‎gradle.properties‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
version=0.1.5
1+
version=0.2.0
22
group=com.coder.toolbox
33
name=coder-toolbox

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.coder.toolbox.util.toURL
77
importcom.jetbrains.toolbox.api.core.diagnostics.Logger
88
importcom.jetbrains.toolbox.api.localization.LocalizableStringFactory
99
importcom.jetbrains.toolbox.api.remoteDev.connection.ClientHelper
10+
importcom.jetbrains.toolbox.api.remoteDev.connection.ToolboxProxySettings
1011
importcom.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateColorPalette
1112
importcom.jetbrains.toolbox.api.remoteDev.ui.EnvironmentUiPageManager
1213
importcom.jetbrains.toolbox.api.ui.ToolboxUi
@@ -21,7 +22,8 @@ data class CoderToolboxContext(
2122
vallogger:Logger,
2223
vali18n:LocalizableStringFactory,
2324
valsettingsStore:CoderSettingsStore,
24-
valsecrets:CoderSecretsStore
25+
valsecrets:CoderSecretsStore,
26+
valproxySettings:ToolboxProxySettings,
2527
) {
2628
/**
2729
* Try to find a URL.

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import com.jetbrains.toolbox.api.core.PluginSecretStore
77
importcom.jetbrains.toolbox.api.core.PluginSettingsStore
88
importcom.jetbrains.toolbox.api.core.ServiceLocator
99
importcom.jetbrains.toolbox.api.core.diagnostics.Logger
10+
importcom.jetbrains.toolbox.api.core.getService
1011
importcom.jetbrains.toolbox.api.localization.LocalizableStringFactory
1112
importcom.jetbrains.toolbox.api.remoteDev.RemoteDevExtension
1213
importcom.jetbrains.toolbox.api.remoteDev.RemoteProvider
1314
importcom.jetbrains.toolbox.api.remoteDev.connection.ClientHelper
15+
importcom.jetbrains.toolbox.api.remoteDev.connection.ToolboxProxySettings
1416
importcom.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateColorPalette
1517
importcom.jetbrains.toolbox.api.remoteDev.ui.EnvironmentUiPageManager
1618
importcom.jetbrains.toolbox.api.ui.ToolboxUi
@@ -25,15 +27,16 @@ class CoderToolboxExtension : RemoteDevExtension {
2527
val logger= serviceLocator.getService(Logger::class.java)
2628
returnCoderRemoteProvider(
2729
CoderToolboxContext(
28-
serviceLocator.getService(ToolboxUi::class.java),
29-
serviceLocator.getService(EnvironmentUiPageManager::class.java),
30-
serviceLocator.getService(EnvironmentStateColorPalette::class.java),
31-
serviceLocator.getService(ClientHelper::class.java),
32-
serviceLocator.getService(CoroutineScope::class.java),
33-
serviceLocator.getService(Logger::class.java),
34-
serviceLocator.getService(LocalizableStringFactory::class.java),
35-
CoderSettingsStore(serviceLocator.getService(PluginSettingsStore::class.java),Environment(), logger),
36-
CoderSecretsStore(serviceLocator.getService(PluginSecretStore::class.java)),
30+
serviceLocator.getService<ToolboxUi>(),
31+
serviceLocator.getService<EnvironmentUiPageManager>(),
32+
serviceLocator.getService<EnvironmentStateColorPalette>(),
33+
serviceLocator.getService<ClientHelper>(),
34+
serviceLocator.getService<CoroutineScope>(),
35+
serviceLocator.getService<Logger>(),
36+
serviceLocator.getService<LocalizableStringFactory>(),
37+
CoderSettingsStore(serviceLocator.getService<PluginSettingsStore>(),Environment(), logger),
38+
CoderSecretsStore(serviceLocator.getService<PluginSecretStore>()),
39+
serviceLocator.getService<ToolboxProxySettings>()
3740
)
3841
)
3942
}

‎src/main/kotlin/com/coder/toolbox/sdk/CoderRestClient.kt‎

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,24 @@ import com.coder.toolbox.util.getArch
2323
importcom.coder.toolbox.util.getHeaders
2424
importcom.coder.toolbox.util.getOS
2525
importcom.squareup.moshi.Moshi
26-
importokhttp3.Credentials
2726
importokhttp3.OkHttpClient
2827
importretrofit2.Response
2928
importretrofit2.Retrofit
3029
importretrofit2.converter.moshi.MoshiConverterFactory
3130
importjava.net.HttpURLConnection
32-
importjava.net.ProxySelector
3331
importjava.net.URL
3432
importjava.util.UUID
3533
importjavax.net.ssl.X509TrustManager
3634

37-
/**
38-
* Holds proxy information.
39-
*/
40-
data classProxyValues(
41-
valusername:String?,
42-
valpassword:String?,
43-
valuseAuth:Boolean,
44-
valselector:ProxySelector,
45-
)
46-
4735
/**
4836
* An HTTP client that can make requests to the Coder API.
4937
*
5038
* The token can be omitted if some other authentication mechanism is in use.
5139
*/
5240
openclassCoderRestClient(
53-
context:CoderToolboxContext,
41+
privatevalcontext:CoderToolboxContext,
5442
valurl:URL,
5543
valtoken:String?,
56-
privatevalproxyValues:ProxyValues? =null,
5744
privatevalpluginVersion:String ="development",
5845
) {
5946
privateval settings= context.settingsStore.readOnly()
@@ -81,22 +68,27 @@ open class CoderRestClient(
8168
val trustManagers= coderTrustManagers(settings.tls.caPath)
8269
var builder=OkHttpClient.Builder()
8370

84-
if (proxyValues!=null) {
85-
builder=
86-
builder
87-
.proxySelector(proxyValues.selector)
88-
.proxyAuthenticator { _, response->
89-
if (proxyValues.useAuth&& proxyValues.username!=null&& proxyValues.password!=null) {
90-
val credentials=Credentials.basic(proxyValues.username, proxyValues.password)
91-
response.request.newBuilder()
92-
.header("Proxy-Authorization", credentials)
93-
.build()
94-
}else {
95-
null
96-
}
97-
}
71+
if (context.proxySettings.getProxy()!=null) {
72+
context.logger.debug("proxy:${context.proxySettings.getProxy()}")
73+
builder.proxy(context.proxySettings.getProxy())
74+
}elseif (context.proxySettings.getProxySelector()!=null) {
75+
context.logger.debug("proxy selector:${context.proxySettings.getProxySelector()}")
76+
builder.proxySelector(context.proxySettings.getProxySelector()!!)
9877
}
9978

79+
//TODO - add support for proxy auth. when Toolbox exposes them
80+
// builder.proxyAuthenticator { _, response ->
81+
// if (proxyValues.useAuth && proxyValues.username != null && proxyValues.password != null) {
82+
// val credentials = Credentials.basic(proxyValues.username, proxyValues.password)
83+
// response.request.newBuilder()
84+
// .header("Proxy-Authorization", credentials)
85+
// .build()
86+
// } else {
87+
// null
88+
// }
89+
// }
90+
// }
91+
10092
if (token!=null) {
10193
builder= builder.addInterceptor {
10294
it.proceed(

‎src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,10 @@ open class CoderProtocolHandler(
238238
if (settings.requireTokenAuth&& token==null) {// User aborted.
239239
throwMissingArgumentException("Token is required")
240240
}
241-
// The http client Toolbox gives us is already set up with the
242-
// proxy config, so we do net need to explicitly add it.
243241
val client=CoderRestClient(
244242
context,
245243
deploymentURL.toURL(),
246244
token,
247-
proxyValues=null,// TODO - not sure the above comment applies as we are creating our own http client
248245
PluginManager.pluginInfo.version
249246
)
250247
client.authenticate()

‎src/main/kotlin/com/coder/toolbox/views/ConnectStep.kt‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,10 @@ class ConnectStep(
7474
signInJob= context.cs.launch {
7575
try {
7676
statusField.textState.update { (context.i18n.ptrl("Authenticating to${url.host}...")) }
77-
// The http client Toolbox gives us is already set up with the
78-
// proxy config, so we do net need to explicitly add it.
7977
val client=CoderRestClient(
8078
context,
8179
url,
8280
token,
83-
proxyValues=null,
8481
PluginManager.pluginInfo.version,
8582
)
8683
// allows interleaving with the back/cancel action

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import com.coder.toolbox.util.toURL
3030
importcom.jetbrains.toolbox.api.core.diagnostics.Logger
3131
importcom.jetbrains.toolbox.api.localization.LocalizableStringFactory
3232
importcom.jetbrains.toolbox.api.remoteDev.connection.ClientHelper
33+
importcom.jetbrains.toolbox.api.remoteDev.connection.ToolboxProxySettings
3334
importcom.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateColorPalette
3435
importcom.jetbrains.toolbox.api.remoteDev.ui.EnvironmentUiPageManager
3536
importcom.jetbrains.toolbox.api.ui.ToolboxUi
@@ -68,7 +69,8 @@ internal class CoderCLIManagerTest {
6869
Environment(),
6970
mockk<Logger>(relaxed=true)
7071
),
71-
mockk<CoderSecretsStore>()
72+
mockk<CoderSecretsStore>(),
73+
mockk<ToolboxProxySettings>()
7274
)
7375

7476
/**

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

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.coder.toolbox.util.sslContextFromPEMs
2323
importcom.jetbrains.toolbox.api.core.diagnostics.Logger
2424
importcom.jetbrains.toolbox.api.localization.LocalizableStringFactory
2525
importcom.jetbrains.toolbox.api.remoteDev.connection.ClientHelper
26+
importcom.jetbrains.toolbox.api.remoteDev.connection.ToolboxProxySettings
2627
importcom.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateColorPalette
2728
importcom.jetbrains.toolbox.api.remoteDev.ui.EnvironmentUiPageManager
2829
importcom.jetbrains.toolbox.api.ui.ToolboxUi
@@ -51,6 +52,7 @@ import java.nio.file.Path
5152
importjava.util.UUID
5253
importjavax.net.ssl.SSLHandshakeException
5354
importjavax.net.ssl.SSLPeerUnverifiedException
55+
importkotlin.test.Ignore
5456
importkotlin.test.Test
5557
importkotlin.test.assertContains
5658
importkotlin.test.assertEquals
@@ -104,8 +106,17 @@ class CoderRestClientTest {
104106
mockk<Logger>(relaxed=true),
105107
mockk<LocalizableStringFactory>(),
106108
CoderSettingsStore(pluginTestSettingsStore(),Environment(), mockk<Logger>(relaxed=true)),
107-
mockk<CoderSecretsStore>()
108-
)
109+
mockk<CoderSecretsStore>(),
110+
object:ToolboxProxySettings {
111+
overridefungetProxy():Proxy?=null
112+
overridefungetProxySelector():ProxySelector?=null
113+
overridefunaddProxyChangeListener(listener:Runnable) {
114+
}
115+
116+
overridefunremoveProxyChangeListener(listener:Runnable) {
117+
}
118+
})
119+
109120

110121
data classTestWorkspace(varworkspace:Workspace,varresources:List<WorkspaceResource>? = emptyList())
111122

@@ -529,6 +540,7 @@ class CoderRestClientTest {
529540
}
530541

531542
@Test
543+
@Ignore("Until proxy authentication is supported")
532544
funusesProxy() {
533545
val settings=CoderSettingsStore(pluginTestSettingsStore(),Environment(), context.logger)
534546
val workspaces=listOf(DataGen.workspace("ws1"))
@@ -545,26 +557,33 @@ class CoderRestClientTest {
545557
val srv2= mockProxy()
546558
val client=
547559
CoderRestClient(
548-
context.copy(settingsStore= settings),
560+
context.copy(settingsStore= settings, proxySettings=object:ToolboxProxySettings {
561+
overridefungetProxy():Proxy?=null
562+
563+
overridefungetProxySelector():ProxySelector? {
564+
returnobject:ProxySelector() {
565+
overridefunselect(uri:URI):List<Proxy>=
566+
listOf(Proxy(Proxy.Type.HTTP,InetSocketAddress("localhost", srv2.address.port)))
567+
568+
overridefunconnectFailed(
569+
uri:URI,
570+
sa:SocketAddress,
571+
ioe:IOException,
572+
) {
573+
getDefault().connectFailed(uri, sa, ioe)
574+
}
575+
}
576+
}
577+
578+
overridefunaddProxyChangeListener(listener:Runnable) {
579+
}
580+
581+
overridefunremoveProxyChangeListener(listener:Runnable) {
582+
}
583+
584+
}),
549585
URL(url1),
550586
"token",
551-
ProxyValues(
552-
"foo",
553-
"bar",
554-
true,
555-
object:ProxySelector() {
556-
overridefunselect(uri:URI):List<Proxy>=
557-
listOf(Proxy(Proxy.Type.HTTP,InetSocketAddress("localhost", srv2.address.port)))
558-
559-
overridefunconnectFailed(
560-
uri:URI,
561-
sa:SocketAddress,
562-
ioe:IOException,
563-
) {
564-
getDefault().connectFailed(uri, sa, ioe)
565-
}
566-
},
567-
),
568587
)
569588

570589
assertEquals(workspaces.map { ws-> ws.name }, runBlocking { client.workspaces() }.map { ws-> ws.name })

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp