11package  com.coder.toolbox.views 
22
33import  com.coder.toolbox.CoderToolboxContext 
4+ import  com.coder.toolbox.browser.browse 
5+ import  com.coder.toolbox.oauth.ClientRegistrationRequest 
6+ import  com.coder.toolbox.oauth.CoderAuthorizationApi 
7+ import  com.coder.toolbox.oauth.CoderOAuthCfg 
8+ import  com.coder.toolbox.plugin.PluginManager 
9+ import  com.coder.toolbox.sdk.CoderHttpClientBuilder 
10+ import  com.coder.toolbox.sdk.convertors.LoggingConverterFactory 
11+ import  com.coder.toolbox.sdk.interceptors.Interceptors 
412import  com.coder.toolbox.util.WebUrlValidationResult.Invalid 
513import  com.coder.toolbox.util.toURL 
614import  com.coder.toolbox.util.validateStrictWebUrl 
@@ -14,8 +22,12 @@ import com.jetbrains.toolbox.api.ui.components.RowGroup
1422import  com.jetbrains.toolbox.api.ui.components.TextField 
1523import  com.jetbrains.toolbox.api.ui.components.TextType 
1624import  com.jetbrains.toolbox.api.ui.components.ValidationErrorField 
25+ import  com.squareup.moshi.Moshi 
1726import  kotlinx.coroutines.flow.StateFlow 
1827import  kotlinx.coroutines.flow.update 
28+ import  kotlinx.coroutines.launch 
29+ import  retrofit2.Retrofit 
30+ import  retrofit2.converter.moshi.MoshiConverterFactory 
1931import  java.net.MalformedURLException 
2032import  java.net.URL 
2133
@@ -42,6 +54,16 @@ class DeploymentUrlStep(
4254
4355    private  val  errorField =  ValidationErrorField (context.i18n.pnotr(" " 
4456
57+     val  interceptors =  buildList {
58+         add((Interceptors .userAgent(PluginManager .pluginInfo.version)))
59+         add(Interceptors .logging(context))
60+     }
61+     val  okHttpClient =  CoderHttpClientBuilder .build(
62+         context,
63+         interceptors
64+     )
65+ 
66+ 
4567    override  val  panel:  RowGroup 
4668        get() {
4769            if  (! context.settingsStore.disableSignatureVerification) {
@@ -86,6 +108,61 @@ class DeploymentUrlStep(
86108            errorReporter.report(" URL is invalid" 
87109            return  false 
88110        }
111+         val  service =  Retrofit .Builder ()
112+             .baseUrl(CoderCliSetupContext .url!! )
113+             .client(okHttpClient)
114+             .addConverterFactory(
115+                 LoggingConverterFactory .wrap(
116+                     context,
117+                     MoshiConverterFactory .create(Moshi .Builder ().build())
118+                 )
119+             )
120+             .build()
121+             .create(CoderAuthorizationApi ::class .java)
122+         context.cs.launch {
123+             context.logger.info(" >> checking if Coder supports OAuth2" 
124+             val  response =  service.discoveryMetadata()
125+             if  (response.isSuccessful) {
126+                 val  authServer =  requireNotNull(response.body()) {
127+                     " Successful response returned null body or oauth server discovery metadata" 
128+                 }
129+                 context.logger.info(" >> registering coder-jetbrains-toolbox as client app $response " 
130+                 val  clientResponse =  service.registerClient(
131+                     ClientRegistrationRequest (
132+                         clientName =  " coder-jetbrains-toolbox" 
133+                         redirectUris =  listOf (" jetbrains://gateway/com.coder.toolbox/auth" // URLEncoder.encode("jetbrains://gateway/com.coder.toolbox/oauth", StandardCharsets.UTF_8.toString())),
134+                         grantTypes =  listOf (" authorization_code" " refresh_token" 
135+                         responseTypes =  authServer.supportedResponseTypes,
136+                         scope =  " coder:workspaces.operate coder:workspaces.delete coder:workspaces.access user:read" 
137+                         tokenEndpointAuthMethod =  " client_secret_post" 
138+                     )
139+                 )
140+                 if  (clientResponse.isSuccessful) {
141+                     val  clientResponse = 
142+                         requireNotNull(clientResponse.body()) { " Successful response returned null body or client registration metadata" 
143+                     context.logger.info(" >> initiating oauth login with $clientResponse " 
144+ 
145+                     val  oauthCfg =  CoderOAuthCfg (
146+                         baseUrl =  CoderCliSetupContext .url!! .toString(),
147+                         authUrl =  authServer.authorizationEndpoint,
148+                         tokenUrl =  authServer.tokenEndpoint,
149+                         clientId =  clientResponse.clientId,
150+                         clientSecret =  clientResponse.clientSecret,
151+                     )
152+ 
153+                     val  loginUrl =  context.oauthManager.initiateLogin(oauthCfg)
154+                     context.logger.info(" >> retrieving token" 
155+                     context.desktop.browse(loginUrl) {
156+                         context.ui.showErrorInfoPopup(it)
157+                     }
158+                     val  token =  context.oauthManager.getToken(" coder" =  false )
159+                     context.logger.info(" >> token is $token " 
160+                 } else  {
161+                     context.logger.error(" >> ${clientResponse.code()}  ${clientResponse.message()}  || ${clientResponse.errorBody()} " 
162+                 }
163+             }
164+         }
165+ 
89166        if  (context.settingsStore.requireTokenAuth) {
90167            CoderCliSetupWizardState .goToNextStep()
91168        } else  {
0 commit comments