Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking β€œSign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test preview #19597

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
TODO
  • Loading branch information
mustard-mh committed Jan 24, 2025
commit 29631b9775831200c3c10581d5dd270a047e6c52
6 changes: 3 additions & 3 deletions components/ide/jetbrains/toolbox/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -83,10 +83,10 @@ tasks.shadowJar {
"com.jetbrains.toolbox.gateway",
"com.jetbrains",
"org.jetbrains",
"com.squareup.okhttp3",
"org.slf4j",
// "com.squareup.okhttp3",
// "org.slf4j",
"org.jetbrains.intellij",
"com.squareup.okio",
// "com.squareup.okio",
"kotlin."
)

8 changes: 4 additions & 4 deletions components/ide/jetbrains/toolbox/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[versions]
toolbox-plugin-api = "0.2"
toolbox-plugin-api = "0.4"
kotlin = "2.0.10"
coroutines = "1.7.3"
serialization = "1.5.0"
coroutines = "1.9.0"
serialization = "1.7.3"
okhttp = "4.10.0"
slf4j = "2.0.3"
slf4j = "2.0.9"
dependency-license-report = "2.5"
marketplace-client = "2.0.38"
gradle-wrapper = "0.14.0"
Original file line number Diff line number Diff line change
@@ -10,10 +10,8 @@ import com.jetbrains.toolbox.api.core.auth.*
import io.gitpod.publicapi.experimental.v1.UserServiceClient
import io.gitpod.toolbox.service.GitpodPublicApiManager
import io.gitpod.toolbox.service.Utils
import io.gitpod.toolbox.utils.GitpodLogger
import kotlinx.coroutines.future.future
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
@@ -48,22 +46,22 @@ class GitpodAuthManager {
GitpodAccount::class.java,
{ it.encode() },
{ GitpodAccount.decode(it) },
{ oauthToken, authCfg -> getAuthenticatedUser(authCfg.baseUrl, oauthToken) },
{ oauthToken, authCfg -> getAuthenticatedUser(URI.create(authCfg.baseUrl).host, oauthToken) },
{ oauthToken, gpAccount -> getAuthenticatedUser(gpAccount.getHost(), oauthToken) },
{ gpLoginCfg ->
val authParams = mapOf(
"response_type" to "code",
"client_id" to "toolbox-gateway-gitpod-plugin",
"scope" to authScopesJetBrainsToolbox.joinToString(" "),
"scope" to authScopesJetBrainsToolbox.joinToString("%20"),
)
val tokenParams =
mapOf("grant_type" to "authorization_code", "client_id" to "toolbox-gateway-gitpod-plugin")
AuthConfiguration(
authParams,
tokenParams,
gpLoginCfg.host,
gpLoginCfg.host + "/api/oauth/authorize",
gpLoginCfg.host + "/api/oauth/token",
gpLoginCfg.hostUrl,
gpLoginCfg.hostUrl + "/api/oauth/authorize",
gpLoginCfg.hostUrl + "/api/oauth/token",
"code_challenge",
"S256",
"code_verifier",
@@ -76,13 +74,13 @@ class GitpodAuthManager {
manager.addEventListener {
when (it.type) {
AuthEvent.Type.LOGIN -> {
GitpodLogger.info(" user logged in ${it.accountId}")
Utils.logger.info(" user logged in ${it.accountId}")
resetCurrentAccount(it.accountId)
loginListeners.forEach { it() }
}

AuthEvent.Type.LOGOUT -> {
GitpodLogger.info("user logged out ${it.accountId}")
Utils.logger.info("user logged out ${it.accountId}")
resetCurrentAccount(it.accountId)
logoutListeners.forEach { it() }
}
@@ -92,7 +90,7 @@ class GitpodAuthManager {

private fun resetCurrentAccount(accountId: String) {
val account = manager.accountsWithStatus.find { it.account.id == accountId }?.account ?: return
GitpodLogger.debug("reset settings for ${account.getHost()}")
Utils.logger.debug("reset settings for ${account.getHost()}")
Utils.gitpodSettings.resetSettings(account.getHost())
}

@@ -132,8 +130,8 @@ class GitpodAuthManager {
}

fun getOAuthLoginUrl(gitpodHost: String): String {
GitpodLogger.info("get oauth url of $gitpodHost")
return manager.initiateLogin(GitpodLoginConfiguration(gitpodHost))
Utils.logger.info("get oauth url of https://$gitpodHost")
return manager.initiateLogin(GitpodLoginConfiguration("https://$gitpodHost"))
}

fun tryHandle(uri: URI): Boolean {
@@ -156,7 +154,7 @@ class GitpodAuthManager {
private fun getAuthenticatedUser(gitpodHost: String, oAuthToken: OAuthToken): Future<GitpodAccount> {
return Utils.coroutineScope.future {
val bearerToken = getBearerToken(oAuthToken)
val client = GitpodPublicApiManager.createClient(URI(gitpodHost).host, bearerToken)
val client = GitpodPublicApiManager.createClient(gitpodHost, bearerToken)
val user = GitpodPublicApiManager.tryGetAuthenticatedUser(UserServiceClient(client))
GitpodAccount(bearerToken, user.id, user.name, gitpodHost, authScopesJetBrainsToolbox)
}
@@ -178,7 +176,7 @@ class GitpodAuthManager {

}

class GitpodLoginConfiguration(val host: String)
class GitpodLoginConfiguration(val hostUrl: String)

@Serializable
class GitpodAccount : Account {
@@ -192,7 +190,7 @@ class GitpodAccount : Account {
this.credentials = credentials
this.id = id
this.name = name
this.host = URI(host).host
this.host = host
this.scopes = scopes
}

@@ -207,14 +205,9 @@ class GitpodAccount : Account {
}

suspend fun isValidate(): Boolean {
// TODO(hw): Align host formatting everywhere
val host = if (host.startsWith("http")) {
host
} else {
"https://$host"
}
val client = GitpodPublicApiManager.createClient(URI(host).host, credentials)
GitpodLogger.debug("validating account $host")
val hostUrl = "https://$host"
val client = GitpodPublicApiManager.createClient(URI(hostUrl).host, credentials)
Utils.logger.debug("validating account $hostUrl")
try {
GitpodPublicApiManager.tryGetAuthenticatedUser(UserServiceClient(client))
// TODO: Verify scopes
@@ -225,7 +218,7 @@ class GitpodAccount : Account {
"jsonrpc2: connection is closed"
))
) {
GitpodLogger.error("account $host is not valid")
Utils.logger.error("account $hostUrl is not valid")
return false
}
return true
Original file line number Diff line number Diff line change
@@ -14,16 +14,13 @@ import io.gitpod.toolbox.components.AbstractUiPage
import io.gitpod.toolbox.components.GitpodIcon
import io.gitpod.toolbox.components.SimpleButton
import io.gitpod.toolbox.service.Utils
import java.net.URI
import java.net.URL

class GitpodLoginPage(private val authManager: GitpodAuthManager) : AbstractUiPage() {
private val hostField = TextField("Host", "https://exp-migration.preview.gitpod-dev.com", null) {
if (it.isBlank()) {
ValidationResult.Invalid("Host should not be empty")
}
if (!it.startsWith("https://")) {
ValidationResult.Invalid("Host should start with https://")
}
ValidationResult.Valid
private val hostField = TextField("Host", "exp-migration.preview.gitpod-dev.com", null) {
val (result) = isValidHost(it)
result
}

override fun getFields(): MutableList<UiField> {
@@ -33,7 +30,12 @@ class GitpodLoginPage(private val authManager: GitpodAuthManager) : AbstractUiPa

override fun getActionButtons(): List<ActionDescription> {
return listOf(SimpleButton("Login") action@{
val host = getFieldValue<String>(hostField) ?: return@action
val hostString = getFieldValue<String>(hostField) ?: return@action
val (result, host) = isValidHost(hostString)
if (result != ValidationResult.Valid) {
Utils.toolboxUi.showErrorInfoPopup(IllegalArgumentException(result.errorMessage ?: "Invalid host value"))
return@action
}
val url = authManager.getOAuthLoginUrl(host)
Utils.openUrl(url)
})
@@ -46,4 +48,20 @@ class GitpodLoginPage(private val authManager: GitpodAuthManager) : AbstractUiPa
override fun getSvgIcon(): SvgIcon {
return GitpodIcon()
}

private fun isValidHost(it: String): Pair<ValidationResult, String> {
if (it.isBlank()) {
return ValidationResult.Invalid("Host cannot be empty") to ""
}
val host = try {
if (!it.startsWith("https://")) {
URI.create("https://$it").host
} else {
URI.create(it).host
}
} catch (e: Exception) {
return ValidationResult.Invalid("Invalid host value $e") to it
}
return ValidationResult.Valid to host
}
}
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ import io.gitpod.toolbox.auth.GitpodAuthManager
import io.gitpod.toolbox.service.ConnectParams
import io.gitpod.toolbox.service.GitpodPublicApiManager
import io.gitpod.toolbox.service.Utils
import io.gitpod.toolbox.utils.GitpodLogger
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.BufferOverflow
@@ -28,7 +27,6 @@ import kotlinx.coroutines.launch
import java.util.concurrent.CompletableFuture

class GitpodRemoteEnvironment(
private val authManager: GitpodAuthManager,
private val connectParams: ConnectParams,
private val publicApi: GitpodPublicApiManager, observablePropertiesFactory: ObservablePropertiesFactory?,
) : AbstractRemoteProviderEnvironment(observablePropertiesFactory), DisposableHandle {
@@ -53,10 +51,10 @@ class GitpodRemoteEnvironment(
}

Utils.coroutineScope.launch {
GitpodLogger.debug("watching workspace ${connectParams.workspaceId}")
Utils.logger.debug("watching workspace ${connectParams.workspaceId}")
watchWorkspaceJob = publicApi.watchWorkspaceStatus(connectParams.workspaceId) { _, status ->
lastPhase = status.phase
GitpodLogger.debug("${connectParams.workspaceId} status updated: $lastPhase")
Utils.logger.debug("${connectParams.workspaceId} status updated: $lastPhase")
lastWSEnvState.tryEmit(WorkspaceEnvState(status.phase))
Utils.coroutineScope.launch {
envContentsView.updateEnvironmentMeta(status)
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@ import io.gitpod.toolbox.components.EmptyUiPageWithTitle
import io.gitpod.toolbox.components.GitpodIcon
import io.gitpod.toolbox.components.SimpleButton
import io.gitpod.toolbox.service.*
import io.gitpod.toolbox.utils.GitpodLogger
import kotlinx.coroutines.launch
import java.net.URI
import java.util.concurrent.CompletableFuture
@@ -49,19 +48,18 @@ class GitpodRemoteProvider(

private suspend fun setEnvironmentVisibility(connectParams: ConnectParams) {
val workspaceId = connectParams.workspaceId
GitpodLogger.debug("setEnvironmentVisibility $workspaceId, $connectParams")
Utils.logger.debug("setEnvironmentVisibility $workspaceId, $connectParams")
val obj = environmentMap[connectParams.uniqueID]
var (workspace) = obj ?: Pair(null, null)
if (obj == null) {
workspace = publicApi.getWorkspace(workspaceId)
val env = GitpodRemoteEnvironment(
authManger,
connectParams,
publicApi,
Utils.observablePropertiesFactory
)
environmentMap[connectParams.uniqueID] = Pair(workspace, env)
consumer.consumeEnvironments(environmentMap.values.map { it.second })
consumer.consumeEnvironments(environmentMap.values.map { it.second }, false)
}
val joinLinkInfo = publicApi.fetchJoinLink2Info(workspaceId, workspace!!.getIDEUrl())
// TODO(hw): verify if it's working
@@ -77,13 +75,12 @@ class GitpodRemoteProvider(
Utils.coroutineScope.launch {
val workspaces = publicApi.listWorkspaces()
if (workspaces.isEmpty()) {
consumer.consumeEnvironments(emptyList())
consumer.consumeEnvironments(emptyList(), false)
return@launch
}
consumer.consumeEnvironments(workspaces.map {
val connectParams = it.getConnectParams()
val env = environmentMap[connectParams.uniqueID]?.second ?: GitpodRemoteEnvironment(
authManger,
connectParams,
publicApi,
Utils.observablePropertiesFactory
@@ -94,14 +91,14 @@ class GitpodRemoteProvider(
pendingConnectParams = null
}
env
})
}, false)
}
}

private fun startup() {
val account = authManger.getCurrentAccount() ?: return
publicApi.setup()
GitpodLogger.info("startup with ${account.getHost()} ${account.id}")
Utils.logger.info("startup with ${account.getHost()} ${account.id}")
showWorkspacesList()
}

@@ -169,7 +166,7 @@ class GitpodRemoteProvider(
}
when (uri.path) {
else -> {
GitpodLogger.warn("Unknown request: $uri")
Utils.logger.warn("Unknown request: $uri")
}
}
}
Original file line number Diff line number Diff line change
@@ -5,15 +5,14 @@
package io.gitpod.toolbox.gateway

import io.gitpod.toolbox.service.Utils
import io.gitpod.toolbox.utils.GitpodLogger

class GitpodSettings {
private val settingsChangedListeners: MutableList<(String, String) -> Unit> = mutableListOf()

private fun getStoreKey(key: SettingKey) = "GITPOD_SETTINGS:${key.name}"

private fun updateSetting(key: SettingKey, value: String) {
GitpodLogger.debug("updateSetting ${key.name}=$value")
Utils.logger.debug("updateSetting ${key.name}=$value")
Utils.settingStore[getStoreKey(key)] = value
settingsChangedListeners.forEach { it(key.name, value) }
}
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
package io.gitpod.toolbox.gateway

import io.gitpod.toolbox.service.ConnectParams
import io.gitpod.toolbox.utils.GitpodLogger
import io.gitpod.toolbox.service.Utils
import java.net.URI
import java.util.concurrent.Future

@@ -24,7 +24,7 @@ abstract class AbstractUriHandler<T> : UriHandler<T> {
handle(data)
true
} catch (e: Exception) {
GitpodLogger.warn(e, "cannot parse URI")
Utils.logger.warn(e, "cannot parse URI")
false
}
}
@@ -51,12 +51,11 @@ class GitpodOpenInToolboxUriHandler(val handler: (Pair<String, ConnectParams>) -
}

try {
URI.create(host)
URI.create("https://$host")
} catch (e: IllegalArgumentException) {
throw IllegalArgumentException("invalid host: $host")
}
GitpodLogger.debug("parsed URI: $host, $workspaceId, $debugWorkspace")
val gitpodHost = "https://$host"
return Pair(gitpodHost, ConnectParams(workspaceId, gitpodHost, debugWorkspace))
Utils.logger.debug("parsed URI: $host, $workspaceId, $debugWorkspace")
return Pair(host, ConnectParams(workspaceId, host, debugWorkspace))
}
}
Loading
Oops, something went wrong.