Merge branch 'svn_18_3'

This commit is contained in:
Konstantin Kolosovsky
2014-10-17 14:48:51 +04:00
10 changed files with 62 additions and 46 deletions
@@ -201,6 +201,10 @@ dialog.edit.http.proxies.settings.test.connection.succes.title=Connection test s
confirmation.text.delete.stored.authentication.information=You are about to delete all stored Subversion authentication information.\nWould you like to proceed with deletion?
confirmation.title.clear.authentication.cache=Clear Authentication Cache
command.line.interactive.mode.title=Interactive mode
command.line.interactive.mode.description=<html>Emulates behaviour as if Subversion commands were executed directly from terminal (in interactive mode).<br>\
Primarily intended to be used for handling password/passphrase prompts for svn+ssh repositories and trusting invalid server certificates for https repositories.</html>
ssh.settings.title=SSH Settings
ssh.settings.executable.label=SSH executable\:
ssh.settings.browse.executable.dialog.title=SSH executable
@@ -18,7 +18,7 @@
<properties/>
<border type="none"/>
<children>
<grid id="2ae3a" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="2ae3a" layout-manager="GridLayoutManager" row-count="7" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<tabbedpane title="General"/>
@@ -29,7 +29,7 @@
<grid id="a4729" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -87,7 +87,7 @@
</grid>
<component id="df054" class="javax.swing.JCheckBox" binding="myUseDefaultCheckBox">
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="org/jetbrains/idea/svn/SvnBundle" key="checkbox.configure.use.system.default.configuration.directory"/>
@@ -96,7 +96,7 @@
<grid id="137aa" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="5" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="6" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -123,12 +123,12 @@
</grid>
<hspacer id="e8f24">
<constraints>
<grid row="5" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="6" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="aa6b2">
<constraints>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="12735" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -162,7 +162,15 @@
</constraints>
<properties>
<margin top="2" left="-2" bottom="2" right="3"/>
<text value="Run under terminal"/>
<text resource-bundle="org/jetbrains/idea/svn/SvnBundle" key="command.line.interactive.mode.title"/>
</properties>
</component>
<component id="40f21" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="3" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="org/jetbrains/idea/svn/SvnBundle" key="command.line.interactive.mode.description"/>
</properties>
</component>
</children>
@@ -153,7 +153,7 @@ public class AuthenticationService {
public String requestSshCredentials(@NotNull final String realm,
@NotNull final SimpleCredentialsDialog.Mode mode,
@NotNull final String key) {
return requestCredentials(realm, ISVNAuthenticationManager.SSH, new Getter<String>() {
return requestCredentials(realm, StringUtil.toLowerCase(mode.toString()), new Getter<String>() {
@Override
public String get() {
final Ref<String> answer = new Ref<String>();
@@ -184,7 +184,7 @@ public class AuthenticationService {
@NotNull
public AcceptResult acceptCertificate(@NotNull final SVNURL url, @NotNull final String certificateInfo) {
// TODO: Probably explicitly construct server url for realm here - like in CertificateTrustManager.
String kind = "svn.ssl.server";
String kind = "terminal.ssl.server";
String realm = url.toDecodedString();
Object data = SvnConfiguration.RUNTIME_AUTH_CACHE.getDataWithLowerCheck(kind, realm);
AcceptResult result;
@@ -113,7 +113,7 @@ public class CertificateTrustManager extends ClientOnlyTrustManager {
}
private void acknowledge(@NotNull X509Certificate certificate) throws CertificateEncodingException {
myAuthenticationService.getVcs().getSvnConfiguration().acknowledge("svn.ssl.server", myRealm, certificate);
myAuthenticationService.getVcs().getSvnConfiguration().acknowledge("cmd.ssl.server", myRealm, certificate);
}
@Override
@@ -80,6 +80,6 @@ public abstract class BaseTerminalModule extends LineCommandAdapter implements C
}
protected void cancelAuthentication() {
myExecutor.destroyProcess("Authentication canceled for repository: " + myExecutor.getCommand().getRepositoryUrl());
myExecutor.destroyProcess("Authentication canceled for repository: " + myExecutor.getCommand().requireRepositoryUrl());
}
}
@@ -79,6 +79,14 @@ public class Command {
return myRepositoryUrl;
}
@NotNull
public SVNURL requireRepositoryUrl() {
SVNURL result = getRepositoryUrl();
assert result != null;
return result;
}
@NotNull
public SvnTarget getTarget() {
return myTarget;
@@ -126,7 +126,7 @@ public class CommandRuntime {
private boolean handleErrorText(CommandExecutor executor, Command command) throws SvnBindException {
final String errText = executor.getErrorOutput().trim();
final AuthCallbackCase callback = executor instanceof TerminalExecutor ? null : createCallback(errText, command.getRepositoryUrl());
final AuthCallbackCase callback = createCallback(errText, command.getRepositoryUrl(), executor instanceof TerminalExecutor);
// do not handle possible authentication errors if command was manually cancelled
// force checking if command is cancelled and not just use corresponding value from executor - as there could be cases when command
// finishes quickly but with some auth error - this way checkCancelled() is not called by executor itself and so command is repeated
@@ -166,13 +166,25 @@ public class CommandRuntime {
}
@Nullable
private AuthCallbackCase createCallback(@NotNull final String errText, @Nullable final SVNURL url) {
private AuthCallbackCase createCallback(@NotNull final String errText, @Nullable final SVNURL url, boolean isUnderTerminal) {
List<AuthCallbackCase> authCases = ContainerUtil.newArrayList();
authCases.add(new CertificateCallbackCase(myAuthenticationService, url));
authCases.add(new ProxyCallback(myAuthenticationService, url));
authCases.add(new TwoWaySslCallback(myAuthenticationService, url));
authCases.add(new UsernamePasswordCallback(myAuthenticationService, url));
if (isUnderTerminal) {
// Subversion client does not prompt for proxy credentials (just fails with error) even in terminal mode. So we handle this case the
// same way as in non-terminal mode - repeat command with new credentials.
// NOTE: We could also try getting proxy credentials from user in advance (by issuing separate request and asking for credentials if
// NOTE: required) - not to execute same command several times like it is currently for all other cases in terminal mode. But such
// NOTE: behaviour is not mandatory for now - so we just use "repeat command" logic.
authCases.add(new ProxyCallback(myAuthenticationService, url));
// Same situation (described above) as with proxy settings is here.
authCases.add(new TwoWaySslCallback(myAuthenticationService, url));
}
else {
authCases.add(new CertificateCallbackCase(myAuthenticationService, url));
authCases.add(new ProxyCallback(myAuthenticationService, url));
authCases.add(new TwoWaySslCallback(myAuthenticationService, url));
authCases.add(new UsernamePasswordCallback(myAuthenticationService, url));
}
return ContainerUtil.find(authCases, new Condition<AuthCallbackCase>() {
@Override
@@ -15,7 +15,6 @@
*/
package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.IdeaSVNConfigFile;
@@ -31,38 +30,29 @@ import java.net.Proxy;
*/
public class ProxyModule extends BaseCommandRuntimeModule {
private static final Logger LOG = Logger.getInstance(ProxyModule.class);
public ProxyModule(@NotNull CommandRuntime runtime) {
super(runtime);
}
@Override
public void onStart(@NotNull Command command) throws SvnBindException {
if (myAuthenticationService.haveDataForTmpConfig()) {
if (myAuthenticationService.haveDataForTmpConfig() && !CommandRuntime.isLocal(command)) {
setupProxy(command);
}
}
private void setupProxy(@NotNull Command command) {
// TODO: We assume that if repository url is null - command is local and do not require repository access
// TODO: Check if this is correct for all cases
SVNURL repositoryUrl = command.getRepositoryUrl();
SVNURL repositoryUrl = command.requireRepositoryUrl();
Proxy proxy = AuthenticationService.getIdeaDefinedProxy(repositoryUrl);
if (repositoryUrl != null) {
Proxy proxy = AuthenticationService.getIdeaDefinedProxy(repositoryUrl);
if (proxy != null) {
String hostGroup = ensureGroupForHost(command, repositoryUrl.getHost());
InetSocketAddress address = (InetSocketAddress)proxy.address();
if (proxy != null) {
String hostGroup = ensureGroupForHost(command, repositoryUrl.getHost());
InetSocketAddress address = (InetSocketAddress)proxy.address();
command.put("--config-option");
command.put(String.format("servers:%s:http-proxy-host=%s", hostGroup, address.getHostName()));
command.put("--config-option");
command.put(String.format("servers:%s:http-proxy-port=%s", hostGroup, address.getPort()));
}
} else {
LOG.info("Configured proxy should be used, but repository url is null for command - " + command.getText());
command.put("--config-option");
command.put(String.format("servers:%s:http-proxy-host=%s", hostGroup, address.getHostName()));
command.put("--config-option");
command.put(String.format("servers:%s:http-proxy-port=%s", hostGroup, address.getPort()));
}
}
@@ -112,13 +112,8 @@ public class TerminalSshModule extends BaseTerminalModule {
}
private boolean handleAuthPrompt(@NotNull final SimpleCredentialsDialog.Mode mode, @NotNull final String key) {
final SVNURL repositoryUrl = myExecutor.getCommand().getRepositoryUrl();
// TODO: repositoryUrl could be null for some cases, for instance for info command for file is invoked that requires
// TODO: authentication (like "svn info <file> -r HEAD"), if it is invoked before all working copy roots are resolved.
// TODO: resolving repositoryUrl logic should be updated so that repositoryUrl is not null here.
String auth =
myRuntime.getAuthenticationService().requestSshCredentials(repositoryUrl != null ? repositoryUrl.toDecodedString() : "", mode, key);
SVNURL repositoryUrl = myExecutor.getCommand().requireRepositoryUrl();
String auth = myRuntime.getAuthenticationService().requestSshCredentials(repositoryUrl.toDecodedString(), mode, key);
if (!StringUtil.isEmpty(auth)) {
sendData(auth);
@@ -79,8 +79,7 @@ public class TerminalUserNamePasswordModule extends BaseTerminalModule {
* (before any user name prompt) for pre-configured/system user name.
*/
private boolean handleAuthPrompt(boolean isUserName) {
// TODO: check command is not local and get @NotNull url - also make same for for ssh module
SVNURL repositoryUrl = myExecutor.getCommand().getRepositoryUrl();
SVNURL repositoryUrl = myExecutor.getCommand().requireRepositoryUrl();
if (needAskAuthentication(isUserName)) {
// TODO: Probably pass real realm to dialog