From 37558803960520abb46ff8fa026e5aa5dfdb31d6 Mon Sep 17 00:00:00 2001 From: Sam Stewart Date: Mon, 14 Oct 2024 17:24:34 -0700 Subject: [PATCH 1/2] Remove signout popup, stop credential deletion & remove scopes from config instead --- .../core/credentials/ConfigFilesFacade.kt | 26 +++++++++++++++++++ .../core/credentials/ToolkitAuthManager.kt | 4 ++- .../credentials/actions/SsoLogoutAction.kt | 12 --------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ConfigFilesFacade.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ConfigFilesFacade.kt index 6ab051dc72..5e5240ed65 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ConfigFilesFacade.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ConfigFilesFacade.kt @@ -41,6 +41,7 @@ interface ConfigFilesFacade { fun updateSectionInConfig(sectionName: String, profile: Profile) fun deleteSsoConnectionFromConfig(sessionName: String) + fun deleteSsoProfileScopesFromConfig(sessionName: String) } class DefaultConfigFilesFacade( @@ -197,6 +198,31 @@ class DefaultConfigFilesFacade( } } + override fun deleteSsoProfileScopesFromConfig(sessionName: String) { + val filePath = configPath + val lines = filePath.inputStreamIfExists()?.reader()?.readLines().orEmpty().toMutableList() + val ssoHeaderLine = lines.indexOfFirst { it.startsWith("[${SsoSessionConstants.SSO_SESSION_SECTION_NAME} $sessionName]") } + if (ssoHeaderLine == -1) return + val nextHeaderLine = lines.subList(ssoHeaderLine + 1, lines.size).indexOfFirst { it.startsWith("[") } + val endIndex = if (nextHeaderLine == -1) lines.size else ssoHeaderLine + nextHeaderLine + 1 + + // Find and remove the sso_registration_scopes line + for (i in ssoHeaderLine until endIndex) { + if (lines[i].trim().startsWith("sso_registration_scopes=")) { + lines.removeAt(i) + break + } + } + + filePath.writeText(lines.joinToString("\n")) + + val applicationManager = ApplicationManager.getApplication() + if (applicationManager != null && !applicationManager.isUnitTestMode) { + FileDocumentManager.getInstance().saveAllDocuments() + ProfileWatcher.getInstance().forceRefresh() + } + } + private fun getCorrespondingSsoSessionProfilePosition(updatedArray: List, sessionName: String): List { var content = updatedArray val finalContent = mutableListOf() diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt index 48b1639224..1f7973e8a4 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt @@ -20,6 +20,7 @@ import software.aws.toolkits.core.utils.info import software.aws.toolkits.core.utils.warn import software.aws.toolkits.jetbrains.core.credentials.pinning.FeatureWithPinnedConnection import software.aws.toolkits.jetbrains.core.credentials.profiles.ProfileCredentialsIdentifierSso +import software.aws.toolkits.jetbrains.core.credentials.profiles.ProfileWatcher import software.aws.toolkits.jetbrains.core.credentials.profiles.SsoSessionConstants.SSO_SESSION_SECTION_NAME import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenAuthState import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenProvider @@ -204,6 +205,7 @@ fun loginSso( fun logoutFromSsoConnection(project: Project?, connection: AwsBearerTokenConnection, callback: () -> Unit = {}) { try { ToolkitAuthManager.getInstance().deleteConnection(connection.id) + ProfileWatcher.getInstance().forceRefresh() if (connection is ProfileSsoManagedBearerSsoConnection) { deleteSsoConnection(connection) } @@ -338,7 +340,7 @@ fun deleteSsoConnection(connection: ProfileSsoManagedBearerSsoConnection) = fun deleteSsoConnection(connection: CredentialIdentifier) = deleteSsoConnection(getSsoSessionProfileNameFromCredentials(connection)) -fun deleteSsoConnection(sessionName: String) = DefaultConfigFilesFacade().deleteSsoConnectionFromConfig(sessionName) +fun deleteSsoConnection(sessionName: String) = DefaultConfigFilesFacade().deleteSsoProfileScopesFromConfig(sessionName) private fun getSsoSessionProfileNameFromCredentials(connection: CredentialIdentifier): String { connection as ProfileCredentialsIdentifierSso diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/actions/SsoLogoutAction.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/actions/SsoLogoutAction.kt index 49eb918a14..78b8749fd9 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/actions/SsoLogoutAction.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/actions/SsoLogoutAction.kt @@ -6,11 +6,8 @@ package software.aws.toolkits.jetbrains.core.credentials.actions import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.project.DumbAwareAction -import com.intellij.openapi.ui.MessageDialogBuilder import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection -import software.aws.toolkits.jetbrains.core.credentials.ProfileSsoManagedBearerSsoConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManagerListener -import software.aws.toolkits.jetbrains.core.credentials.deleteSsoConnection import software.aws.toolkits.jetbrains.core.credentials.logoutFromSsoConnection import software.aws.toolkits.resources.AwsCoreBundle import software.aws.toolkits.telemetry.UiTelemetry @@ -18,15 +15,6 @@ import software.aws.toolkits.telemetry.UiTelemetry class SsoLogoutAction(private val value: AwsBearerTokenConnection) : DumbAwareAction(AwsCoreBundle.message("credentials.individual_identity.signout")) { override fun actionPerformed(e: AnActionEvent) { UiTelemetry.click(e.project, "signOut") - if (value is ProfileSsoManagedBearerSsoConnection) { - val confirmDeletion = MessageDialogBuilder.okCancel( - AwsCoreBundle.message("gettingstarted.auth.idc.sign.out.confirmation.title"), - AwsCoreBundle.message("gettingstarted.auth.idc.sign.out.confirmation") - ).yesText(AwsCoreBundle.message("general.confirm")).ask(e.project) - if (confirmDeletion) { - deleteSsoConnection(value) - } - } logoutFromSsoConnection(e.project, value) ApplicationManager.getApplication().messageBus.syncPublisher( ToolkitConnectionManagerListener.TOPIC From 017a3a248c032b7582fc17f5c230441908e0b73a Mon Sep 17 00:00:00 2001 From: Sam Stewart Date: Tue, 15 Oct 2024 12:04:09 -0700 Subject: [PATCH 2/2] remove config file editing and stop Q window from switching views on unauthed connection selection. --- .../toolwindow/AmazonQToolWindowFactory.kt | 2 +- .../core/credentials/ConfigFilesFacade.kt | 26 ------------------- .../core/credentials/ToolkitAuthManager.kt | 14 +++------- 3 files changed, 5 insertions(+), 37 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/toolwindow/AmazonQToolWindowFactory.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/toolwindow/AmazonQToolWindowFactory.kt index 70cba14897..e6b787ae42 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/toolwindow/AmazonQToolWindowFactory.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/toolwindow/AmazonQToolWindowFactory.kt @@ -144,7 +144,7 @@ class AmazonQToolWindowFactory : ToolWindowFactory, DumbAware { QWebviewPanel.getInstance(project).browser?.prepareBrowser(BrowserState(FeatureId.Q)) // isQConnected alone is not robust and there is race condition (read/update connection states) - val component = if (isNewConnectionForQ || (isQConnected(project) && !isQExpired(project))) { + val component = if ((isQConnected(project) && !isQExpired(project))) { LOG.debug { "returning Q-chat window; isQConnection=$isNewConnectionForQ; hasPinnedConnection=$isNewConnectionForQ" } AmazonQToolWindow.getInstance(project).component } else { diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ConfigFilesFacade.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ConfigFilesFacade.kt index 5e5240ed65..6ab051dc72 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ConfigFilesFacade.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ConfigFilesFacade.kt @@ -41,7 +41,6 @@ interface ConfigFilesFacade { fun updateSectionInConfig(sectionName: String, profile: Profile) fun deleteSsoConnectionFromConfig(sessionName: String) - fun deleteSsoProfileScopesFromConfig(sessionName: String) } class DefaultConfigFilesFacade( @@ -198,31 +197,6 @@ class DefaultConfigFilesFacade( } } - override fun deleteSsoProfileScopesFromConfig(sessionName: String) { - val filePath = configPath - val lines = filePath.inputStreamIfExists()?.reader()?.readLines().orEmpty().toMutableList() - val ssoHeaderLine = lines.indexOfFirst { it.startsWith("[${SsoSessionConstants.SSO_SESSION_SECTION_NAME} $sessionName]") } - if (ssoHeaderLine == -1) return - val nextHeaderLine = lines.subList(ssoHeaderLine + 1, lines.size).indexOfFirst { it.startsWith("[") } - val endIndex = if (nextHeaderLine == -1) lines.size else ssoHeaderLine + nextHeaderLine + 1 - - // Find and remove the sso_registration_scopes line - for (i in ssoHeaderLine until endIndex) { - if (lines[i].trim().startsWith("sso_registration_scopes=")) { - lines.removeAt(i) - break - } - } - - filePath.writeText(lines.joinToString("\n")) - - val applicationManager = ApplicationManager.getApplication() - if (applicationManager != null && !applicationManager.isUnitTestMode) { - FileDocumentManager.getInstance().saveAllDocuments() - ProfileWatcher.getInstance().forceRefresh() - } - } - private fun getCorrespondingSsoSessionProfilePosition(updatedArray: List, sessionName: String): List { var content = updatedArray val finalContent = mutableListOf() diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt index 1f7973e8a4..be54977b2c 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/ToolkitAuthManager.kt @@ -203,15 +203,9 @@ fun loginSso( @Suppress("UnusedParameter") fun logoutFromSsoConnection(project: Project?, connection: AwsBearerTokenConnection, callback: () -> Unit = {}) { - try { - ToolkitAuthManager.getInstance().deleteConnection(connection.id) - ProfileWatcher.getInstance().forceRefresh() - if (connection is ProfileSsoManagedBearerSsoConnection) { - deleteSsoConnection(connection) - } - } finally { - callback() - } + ToolkitAuthManager.getInstance().deleteConnection(connection.id) + ProfileWatcher.getInstance().forceRefresh() + callback() } fun lazyGetUnauthedBearerConnections() = @@ -340,7 +334,7 @@ fun deleteSsoConnection(connection: ProfileSsoManagedBearerSsoConnection) = fun deleteSsoConnection(connection: CredentialIdentifier) = deleteSsoConnection(getSsoSessionProfileNameFromCredentials(connection)) -fun deleteSsoConnection(sessionName: String) = DefaultConfigFilesFacade().deleteSsoProfileScopesFromConfig(sessionName) +fun deleteSsoConnection(sessionName: String) = DefaultConfigFilesFacade().deleteSsoConnectionFromConfig(sessionName) private fun getSsoSessionProfileNameFromCredentials(connection: CredentialIdentifier): String { connection as ProfileCredentialsIdentifierSso