[project] moving SSHUtil to a more appropriate module

GitOrigin-RevId: 11bb97575b52914743114e64cbecc327ec1ec402
This commit is contained in:
Roman Shevchenko
2024-06-07 00:16:23 +02:00
committed by intellij-monorepo-bot
parent 48663a58c9
commit dffc787d4c
9 changed files with 60 additions and 72 deletions

View File

@@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="com.intellij" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" packagePrefix="com.intellij" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
@@ -18,5 +19,6 @@
<orderEntry type="module" module-name="intellij.platform.ide.util.netty" exported="" />
<orderEntry type="library" name="netty-codec-http" level="project" />
<orderEntry type="library" name="netty-buffer" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit5" level="project" />
</component>
</module>

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.externalProcessAuthHelper
import com.intellij.credentialStore.CredentialAttributes
@@ -12,7 +12,6 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.NlsSafe
import com.intellij.openapi.util.text.StringUtil
import com.intellij.ssh.SSHUtil
import externalApp.nativessh.NativeSshAskPassAppHandler
import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.NonNls
@@ -59,10 +58,10 @@ class NativeSshGuiAuthenticator(private val project: Project,
override val title: String = ExternalProcessAuthHelperBundle.message("ssh.ask.passphrase.title")
override val serviceName: String = ExternalProcessAuthHelperBundle.message("label.credential.store.key.ssh.passphrase")
override fun parseDescription(description: String): Prompt? {
val matcher = SSHUtil.PASSPHRASE_PROMPT.matcher(description)
val matcher = SshPrompts.PASSPHRASE_PROMPT.matcher(description)
if (!matcher.matches()) return null
val keyPath = SSHUtil.extractKeyPath(matcher)
val keyPath = SshPrompts.extractKeyPath(matcher)
val promptMessage = ExternalProcessAuthHelperBundle.message("ssh.ask.passphrase.message", keyPath)
return Prompt(keyPath, promptMessage)
}
@@ -72,10 +71,10 @@ class NativeSshGuiAuthenticator(private val project: Project,
override val title: String = ExternalProcessAuthHelperBundle.message("ssh.password.title")
override val serviceName: String = ExternalProcessAuthHelperBundle.message("label.credential.store.key.ssh.password")
override fun parseDescription(description: String): Prompt? {
val matcher = SSHUtil.PASSWORD_PROMPT.matcher(description)
val matcher = SshPrompts.PASSWORD_PROMPT.matcher(description)
if (!matcher.matches()) return null
val username = SSHUtil.extractUsername(matcher)
val username = SshPrompts.extractUsername(matcher)
val promptMessage = ExternalProcessAuthHelperBundle.message("ssh.password.message", username)
return Prompt(username, promptMessage)
}
@@ -85,10 +84,10 @@ class NativeSshGuiAuthenticator(private val project: Project,
override val title: String = ExternalProcessAuthHelperBundle.message("ssh.ask.pin.title")
override val serviceName: String = ExternalProcessAuthHelperBundle.message("label.credential.store.key.ssh.pin")
override fun parseDescription(description: String): Prompt? {
val matcher = SSHUtil.PKCS_PIN_TOKEN_PROMPT.matcher(description)
val matcher = SshPrompts.PKCS_PIN_TOKEN_PROMPT.matcher(description)
if (!matcher.matches()) return null
val username = SSHUtil.extractPkcsTokenLabel(matcher)
val username = SshPrompts.extractPkcsTokenLabel(matcher)
val promptMessage = ExternalProcessAuthHelperBundle.message("ssh.ask.pin.message", username)
return Prompt(username, promptMessage)
}
@@ -142,7 +141,7 @@ class NativeSshGuiAuthenticator(private val project: Project,
private var lastAskedConfirmationInput: String? = null
override fun handleInput(description: String): PromptAnswer {
if (!description.contains(SSHUtil.CONFIRM_CONNECTION_PROMPT)) {
if (!description.contains(SshPrompts.CONFIRM_CONNECTION_PROMPT)) {
return PromptAnswer.NotHandled
}
@@ -170,8 +169,8 @@ class NativeSshGuiAuthenticator(private val project: Project,
private fun stripYesNoSuffix(description: String): @NlsSafe String {
return StringUtil.replace(description,
SSHUtil.CONFIRM_CONNECTION_PROMPT + " (yes/no)?",
SSHUtil.CONFIRM_CONNECTION_PROMPT + "?")
SshPrompts.CONFIRM_CONNECTION_PROMPT + " (yes/no)?",
SshPrompts.CONFIRM_CONNECTION_PROMPT + "?")
}
}

View File

@@ -0,0 +1,30 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.externalProcessAuthHelper;
import org.jetbrains.annotations.ApiStatus;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ApiStatus.Internal
public final class SshPrompts {
public static final Pattern PASSPHRASE_PROMPT = Pattern.compile("\\r?Enter passphrase for( key)? '?(?<keyfile>[^']*)'?:\\s?");
public static final Pattern PASSWORD_PROMPT = Pattern.compile("(?<username>.*)'s password:\\s?");
public static final Pattern PKCS_PIN_TOKEN_PROMPT = Pattern.compile("\\r?Enter PIN for '?(?<tokenLabel>[^']*)'?:\\s?");
public static final String PASSWORD_PROMPT_PREFIX = "password for";
public static final String PASSWORD_PROMPT_SUFFIX = "password:";
public static final String CONFIRM_CONNECTION_PROMPT = "Are you sure you want to continue connecting";
public static final String REMOTE_HOST_IDENTIFICATION_HAS_CHANGED = "remote host identification has changed";
public static String extractKeyPath(Matcher matcher) {
return matcher.group("keyfile");
}
public static String extractPkcsTokenLabel(Matcher matcher) {
return matcher.group("tokenLabel");
}
public static String extractUsername(Matcher matcher) {
return matcher.group("username");
}
}

View File

@@ -1,13 +1,15 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ssh
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.externalProcessAuthHelper
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.util.regex.Matcher
import java.util.regex.Pattern
class SSHUtilTest {
class SshPromptsTest {
@Test
@Suppress("NonAsciiCharacters")
fun testPassphraseRegex() {
passphraseRegexShouldMatch("Enter passphrase for key 'С:\\test\\dir\\.ssh\\id.rsa':", "С:\\test\\dir\\.ssh\\id.rsa")
passphraseRegexShouldMatch("Enter passphrase for 'С:\\test\\dir\\.ssh\\id.rsa':", "С:\\test\\dir\\.ssh\\id.rsa")
@@ -20,20 +22,17 @@ class SSHUtilTest {
@Test
fun testPasswordRegex() {
passwordRegexShouldMatch("User1's password:", "User1")
regexShouldMatch(SshPrompts.PASSWORD_PROMPT, "User1's password:", "User1") { SshPrompts.extractUsername(it) }
}
private fun passphraseRegexShouldMatch(input: String, expected: String) {
return regexShouldMatch(SSHUtil.PASSPHRASE_PROMPT, input, expected) { SSHUtil.extractKeyPath(it) }
regexShouldMatch(SshPrompts.PASSPHRASE_PROMPT, input, expected) { SshPrompts.extractKeyPath(it) }
}
private fun passwordRegexShouldMatch(input: String, expected: String) {
return regexShouldMatch(SSHUtil.PASSWORD_PROMPT, input, expected) { SSHUtil.extractUsername(it) }
}
private fun regexShouldMatch(pattern: Pattern, input: String, expected: String, resultProvider: (Matcher) -> String) {
val matcher = pattern.matcher(input)
Assertions.assertTrue(matcher.matches())
assertTrue(matcher.matches())
val result = resultProvider(matcher)
Assertions.assertEquals(expected, result)
assertEquals(expected, result)
}
}
}

View File

@@ -515,15 +515,3 @@ c:com.intellij.remote.ext.UnknownTypeRemoteCredentialHandler
- getPresentableDetails(java.lang.String):java.lang.String
- load(org.jdom.Element):V
- save(org.jdom.Element):V
f:com.intellij.ssh.SSHUtil
- sf:CONFIRM_CONNECTION_PROMPT:java.lang.String
- sf:PASSPHRASE_PROMPT:java.util.regex.Pattern
- sf:PASSWORD_PROMPT:java.util.regex.Pattern
- sf:PASSWORD_PROMPT_PREFIX:java.lang.String
- sf:PASSWORD_PROMPT_SUFFIX:java.lang.String
- sf:PKCS_PIN_TOKEN_PROMPT:java.util.regex.Pattern
- sf:REMOTE_HOST_IDENTIFICATION_HAS_CHANGED:java.lang.String
- <init>():V
- s:extractKeyPath(java.util.regex.Matcher):java.lang.String
- s:extractPkcsTokenLabel(java.util.regex.Matcher):java.lang.String
- s:extractUsername(java.util.regex.Matcher):java.lang.String

View File

@@ -5,7 +5,6 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="com.intellij" />
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
@@ -19,6 +18,5 @@
<orderEntry type="module" module-name="intellij.platform.util.jdom" />
<orderEntry type="module" module-name="intellij.platform.ide.util.io" />
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="library" scope="TEST" name="JUnit5" level="project" />
</component>
</module>

View File

@@ -1,29 +0,0 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ssh;
import org.jetbrains.annotations.NonNls;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class SSHUtil {
public static final @NonNls Pattern PASSPHRASE_PROMPT = Pattern.compile("\\r?Enter passphrase for( key)? '?(?<keyfile>[^']*)'?:\\s?");
public static final @NonNls Pattern PASSWORD_PROMPT = Pattern.compile("(?<username>.*)'s password:\\s?");
public static final @NonNls Pattern PKCS_PIN_TOKEN_PROMPT = Pattern.compile("\\r?Enter PIN for '?(?<tokenLabel>[^']*)'?:\\s?");
public static final @NonNls String PASSWORD_PROMPT_PREFIX = "password for";
public static final @NonNls String PASSWORD_PROMPT_SUFFIX = "password:";
public static final @NonNls String CONFIRM_CONNECTION_PROMPT = "Are you sure you want to continue connecting";
public static final @NonNls String REMOTE_HOST_IDENTIFICATION_HAS_CHANGED = "remote host identification has changed";
public static String extractKeyPath(Matcher matcher) {
return matcher.group("keyfile");
}
public static String extractPkcsTokenLabel(Matcher matcher) {
return matcher.group("tokenLabel");
}
public static String extractUsername(Matcher matcher) {
return matcher.group("username");
}
}

View File

@@ -29,5 +29,6 @@
<orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="library" scope="RUNTIME" name="sqlite" level="project" />
<orderEntry type="module" module-name="intellij.platform.ide.util.io" />
<orderEntry type="module" module-name="intellij.platform.externalProcessAuthHelper" />
</component>
</module>

View File

@@ -1,12 +1,12 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.idea.svn.commandLine;
import com.intellij.externalProcessAuthHelper.SshPrompts;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ssh.SSHUtil;
import com.intellij.util.WaitForProgressToShow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.api.Url;
@@ -17,8 +17,8 @@ import org.jetbrains.idea.svn.dialogs.SimpleCredentialsDialog;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.intellij.ssh.SSHUtil.PASSPHRASE_PROMPT;
import static com.intellij.ssh.SSHUtil.PASSWORD_PROMPT;
import static com.intellij.externalProcessAuthHelper.SshPrompts.PASSPHRASE_PROMPT;
import static com.intellij.externalProcessAuthHelper.SshPrompts.PASSWORD_PROMPT;
public class TerminalSshModule extends BaseTerminalModule {
private static final Pattern UNKNOWN_HOST_MESSAGE =
@@ -42,13 +42,13 @@ public class TerminalSshModule extends BaseTerminalModule {
private boolean checkPassphrase(@NotNull String line) {
Matcher matcher = PASSPHRASE_PROMPT.matcher(line);
return matcher.matches() && handleAuthPrompt(SimpleCredentialsDialog.Mode.SSH_PASSPHRASE, SSHUtil.extractKeyPath(matcher));
return matcher.matches() && handleAuthPrompt(SimpleCredentialsDialog.Mode.SSH_PASSPHRASE, SshPrompts.extractKeyPath(matcher));
}
private boolean checkPassword(@NotNull String line) {
Matcher matcher = PASSWORD_PROMPT.matcher(line);
return matcher.matches() && handleAuthPrompt(SimpleCredentialsDialog.Mode.SSH_PASSWORD, SSHUtil.extractUsername(matcher));
return matcher.matches() && handleAuthPrompt(SimpleCredentialsDialog.Mode.SSH_PASSWORD, SshPrompts.extractUsername(matcher));
}
private boolean checkUnknownHost(@NotNull String line) {