3
3
4
4
package software.aws.toolkits.jetbrains.services.amazonq
5
5
6
- import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
7
6
import com.intellij.openapi.Disposable
8
7
import com.intellij.openapi.actionSystem.AnActionEvent
9
8
import com.intellij.openapi.actionSystem.DataContext
@@ -18,31 +17,27 @@ import com.intellij.ui.dsl.gridLayout.VerticalAlign
18
17
import com.intellij.ui.jcef.JBCefApp
19
18
import com.intellij.ui.jcef.JBCefJSQuery
20
19
import org.cef.CefApp
21
- import software.aws.toolkits.core.utils.debug
22
20
import software.aws.toolkits.core.utils.error
23
21
import software.aws.toolkits.core.utils.getLogger
24
22
import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection
25
- import software.aws.toolkits.jetbrains.core.credentials.ManagedBearerSsoConnection
26
23
import software.aws.toolkits.jetbrains.core.credentials.ToolkitAuthManager
27
24
import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager
28
25
import software.aws.toolkits.jetbrains.core.credentials.actions.SsoLogoutAction
29
26
import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection
30
- import software.aws.toolkits.jetbrains.core.credentials.reauthConnectionIfNeeded
31
27
import software.aws.toolkits.jetbrains.core.credentials.sono.Q_SCOPES
32
28
import software.aws.toolkits.jetbrains.core.credentials.sono.isSono
33
29
import software.aws.toolkits.jetbrains.core.region.AwsRegionProvider
30
+ import software.aws.toolkits.jetbrains.core.webview.BrowserMessage
34
31
import software.aws.toolkits.jetbrains.core.webview.BrowserState
35
32
import software.aws.toolkits.jetbrains.core.webview.LoginBrowser
36
33
import software.aws.toolkits.jetbrains.core.webview.WebviewResourceHandlerFactory
37
34
import software.aws.toolkits.jetbrains.isDeveloperMode
38
35
import software.aws.toolkits.jetbrains.services.amazonq.util.createBrowser
39
36
import software.aws.toolkits.jetbrains.utils.isQConnected
40
37
import software.aws.toolkits.jetbrains.utils.isQExpired
41
- import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread
42
38
import software.aws.toolkits.telemetry.FeatureId
43
39
import software.aws.toolkits.telemetry.WebviewTelemetry
44
40
import java.awt.event.ActionListener
45
- import java.util.function.Function
46
41
import javax.swing.JButton
47
42
import javax.swing.JComponent
48
43
@@ -104,49 +99,59 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
104
99
// TODO: confirm if we need such configuration or the default is fine
105
100
override val jcefBrowser = createBrowser(parentDisposable)
106
101
private val query = JBCefJSQuery .create(jcefBrowser)
107
- private val objectMapper = jacksonObjectMapper()
108
102
109
- private val handler = Function <String , JBCefJSQuery .Response > {
110
- val jsonTree = objectMapper.readTree(it)
111
- val command = jsonTree.get(" command" ).asText()
112
- LOG .debug { " Data received from Q browser: ${jsonTree.asText()} " }
103
+ init {
104
+ CefApp .getInstance()
105
+ .registerSchemeHandlerFactory(
106
+ " http" ,
107
+ domain,
108
+ WebviewResourceHandlerFactory (
109
+ domain = " http://$domain /" ,
110
+ assetUri = " /webview/assets/"
111
+ ),
112
+ )
113
113
114
- when (command) {
115
- " prepareUi" -> {
114
+ loadWebView(query)
115
+
116
+ query.addHandler(jcefHandler)
117
+ }
118
+
119
+ fun component (): JComponent ? = jcefBrowser.component
120
+
121
+ override fun handleBrowserMessage (message : BrowserMessage ? ) {
122
+ if (message == null ) {
123
+ return
124
+ }
125
+
126
+ when (message) {
127
+ is BrowserMessage .PrepareUi -> {
116
128
this .prepareBrowser(BrowserState (FeatureId .Q , false ))
117
129
WebviewTelemetry .amazonqSignInOpened(
118
130
project,
119
131
reAuth = isQExpired(project)
120
132
)
121
133
}
122
134
123
- " selectConnection" -> {
124
- val connId = jsonTree.get(" connectionId" ).asText()
125
- this .selectionSettings[connId]?.let { settings ->
135
+ is BrowserMessage .SelectConnection -> {
136
+ this .selectionSettings[message.connectionId]?.let { settings ->
126
137
settings.onChange(settings.currentSelection)
127
138
}
128
139
}
129
140
130
- " loginBuilderId " -> {
141
+ is BrowserMessage . LoginBuilderId -> {
131
142
loginBuilderId(Q_SCOPES )
132
143
}
133
144
134
- " loginIdC" -> {
135
- // TODO: make it type safe, maybe (de)serialize into a data class
136
- val url = jsonTree.get(" url" ).asText()
137
- val region = jsonTree.get(" region" ).asText()
138
- val awsRegion = AwsRegionProvider .getInstance()[region] ? : error(" unknown region returned from Q browser" )
139
-
140
- val scopes = Q_SCOPES
141
-
142
- loginIdC(url, awsRegion, scopes)
145
+ is BrowserMessage .LoginIdC -> {
146
+ val awsRegion = AwsRegionProvider .getInstance()[message.region] ? : error(" unknown region returned from Q browser" )
147
+ loginIdC(message.url, awsRegion, Q_SCOPES )
143
148
}
144
149
145
- " cancelLogin " -> {
150
+ is BrowserMessage . CancelLogin -> {
146
151
cancelLogin()
147
152
}
148
153
149
- " signout " -> {
154
+ is BrowserMessage . Signout -> {
150
155
(
151
156
ToolkitConnectionManager .getInstance(project)
152
157
.activeConnectionForFeature(QConnection .getInstance()) as ? AwsBearerTokenConnection
@@ -161,42 +166,16 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
161
166
}
162
167
}
163
168
164
- " reauth" -> {
165
- ToolkitConnectionManager .getInstance(project).activeConnectionForFeature(QConnection .getInstance())?.let { conn ->
166
- if (conn is ManagedBearerSsoConnection ) {
167
- pluginAwareExecuteOnPooledThread {
168
- reauthConnectionIfNeeded(project, conn, onPendingToken)
169
- }
170
- }
171
- }
169
+ is BrowserMessage .Reauth -> {
170
+ reauth(ToolkitConnectionManager .getInstance(project).activeConnectionForFeature(QConnection .getInstance()))
172
171
}
173
172
174
- else -> {
175
- error(" received unknown command from Q browser: $command " )
173
+ is BrowserMessage . LoginIAM , is BrowserMessage . ToggleBrowser -> {
174
+ error(" QBrowser doesn't support the provided command ${message:: class .simpleName} " )
176
175
}
177
176
}
178
-
179
- null
180
- }
181
-
182
- init {
183
- CefApp .getInstance()
184
- .registerSchemeHandlerFactory(
185
- " http" ,
186
- domain,
187
- WebviewResourceHandlerFactory (
188
- domain = " http://$domain /" ,
189
- assetUri = " /webview/assets/"
190
- ),
191
- )
192
-
193
- loadWebView(query)
194
-
195
- query.addHandler(handler)
196
177
}
197
178
198
- fun component (): JComponent ? = jcefBrowser.component
199
-
200
179
override fun prepareBrowser (state : BrowserState ) {
201
180
// TODO: duplicate code in ToolkitLoginWebview
202
181
selectionSettings.clear()
@@ -230,7 +209,7 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
230
209
231
210
// available regions
232
211
val regions = AwsRegionProvider .getInstance().allRegionsForService(" sso" ).values.let {
233
- objectMapper. writeValueAsString(it)
212
+ writeValueAsString(it)
234
213
}
235
214
236
215
// TODO: pass "REAUTH" if connection expires
@@ -251,7 +230,7 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
251
230
},
252
231
cancellable: ${state.browserCancellable} ,
253
232
feature: '${state.feature} ',
254
- existConnections: ${objectMapper. writeValueAsString(selectionSettings.values.map { it.currentSelection }.toList())}
233
+ existConnections: ${writeValueAsString(selectionSettings.values.map { it.currentSelection }.toList())}
255
234
}
256
235
""" .trimIndent()
257
236
executeJS(" window.ideClient.prepareUi($jsonData )" )
0 commit comments