mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SVN: prompt if any of "config" or "servers" files properties prevent authentication credentials from being stored
(cherry picked from commit f458405c00f76bda6659f077a55c46bd69baa562)
This commit is contained in:
@@ -18,17 +18,20 @@ package org.jetbrains.idea.svn;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
|
||||
import com.intellij.util.containers.SoftHashMap;
|
||||
import com.intellij.util.net.HttpConfigurable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
|
||||
import org.tmatesoft.svn.core.auth.ISVNProxyManager;
|
||||
import org.tmatesoft.svn.core.auth.SVNAuthentication;
|
||||
import org.tmatesoft.svn.core.auth.*;
|
||||
import org.tmatesoft.svn.core.internal.wc.DefaultSVNAuthenticationManager;
|
||||
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNConfigFile;
|
||||
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
|
||||
import java.io.File;
|
||||
@@ -41,13 +44,15 @@ import java.util.StringTokenizer;
|
||||
*/
|
||||
public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager {
|
||||
private final Project myProject;
|
||||
private final File myConfigDirectory;
|
||||
private PersistentAuthenticationProviderProxy myPersistentAuthenticationProviderProxy;
|
||||
private SvnConfiguration myConfig;
|
||||
|
||||
public SvnAuthenticationManager(final Project project, final File configDirectory) {
|
||||
super(configDirectory, true, null, null);
|
||||
myProject = project;
|
||||
myConfig = SvnConfiguration.getInstance(myProject);
|
||||
myConfigDirectory = configDirectory;
|
||||
myConfig = SvnConfiguration.getInstance(myProject);
|
||||
if (myPersistentAuthenticationProviderProxy != null) {
|
||||
myPersistentAuthenticationProviderProxy.setProject(myProject);
|
||||
}
|
||||
@@ -317,4 +322,115 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager {
|
||||
return SvnAuthEquals.hashCode(getT());
|
||||
}
|
||||
}
|
||||
|
||||
private void setPropertyForHost(final String host, final String property, final String value) {
|
||||
final SVNConfigFile userConfig = new SVNConfigFile(new File(myConfigDirectory, "servers"));
|
||||
|
||||
String groupName = getGroupName(userConfig.getProperties("groups"), host);
|
||||
if (groupName != null) {
|
||||
userConfig.setPropertyValue(groupName, property, value, true);
|
||||
} else {
|
||||
final SVNConfigFile systemConfig = new SVNConfigFile(new File(SVNFileUtil.getSystemConfigurationDirectory(), "servers"));
|
||||
final String systemGroupName = getGroupName(systemConfig.getProperties("groups"), host);
|
||||
if (systemGroupName != null) {
|
||||
systemConfig.setPropertyValue(systemGroupName, property, value, true);
|
||||
} else {
|
||||
// global
|
||||
userConfig.setPropertyValue("global", property, value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default = yes
|
||||
private boolean isTurned(final String value) {
|
||||
return value == null || "yes".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Boolean isAuthStorageEnabledMy(SVNURL url) {
|
||||
String host = url != null ? url.getHost() : null;
|
||||
Map properties = getHostProperties(host);
|
||||
String storeAuthCreds = (String) properties.get("store-auth-creds");
|
||||
if (storeAuthCreds == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return "yes".equalsIgnoreCase(storeAuthCreds) || "on".equalsIgnoreCase(storeAuthCreds) || "true".equalsIgnoreCase(storeAuthCreds);
|
||||
}
|
||||
|
||||
public boolean checkContinueSaveCredentials(final SVNAuthentication auth, final String kind, final String realm) {
|
||||
final SVNURL url = auth.getURL();
|
||||
|
||||
//final SVNConfigFile userConfig = new SVNConfigFile(new File(myConfigDirectory, "config"));
|
||||
final boolean authStorageEnabled = isAuthStorageEnabled(url);
|
||||
final String storeCredentials = getConfigFile().getPropertyValue("auth", "store-auth-creds");
|
||||
if ((Boolean.FALSE.equals(isAuthStorageEnabledMy(url))) || (! isTurned(storeCredentials))) {
|
||||
//userConfig.setPropertyValue("auth", "store-auth-creds", "yes", true);
|
||||
ChangesViewBalloonProblemNotifier.showMe(myProject, "Cannot store credentials: forbidden by \"store-auth-creds\"=\"no\"", MessageType.ERROR);
|
||||
return false;
|
||||
}
|
||||
final boolean passwordStorageEnabled = isStorePasswords(url);
|
||||
// check can store
|
||||
final String storePasswords = getConfigFile().getPropertyValue("auth", "store-passwords");
|
||||
if ((! ISVNAuthenticationManager.SSL.equals(kind)) && (! passwordStorageEnabled)) {
|
||||
// but it should be
|
||||
//userConfig.setPropertyValue("auth", "store-passwords", "yes", true);
|
||||
ChangesViewBalloonProblemNotifier.showMe(myProject, "Cannot store password: forbidden by \"store-passwords\"=\"no\"", MessageType.ERROR);
|
||||
return false;
|
||||
}
|
||||
if (ISVNAuthenticationManager.SSL.equals(kind) && (! isStoreSSLClientCertificatePassphrases(url))) {
|
||||
//setPropertyForHost(url.getHost(), "store-ssl-client-cert-pp", "yes");
|
||||
ChangesViewBalloonProblemNotifier.showMe(myProject, "Cannot store passphrase: forbidden by \"store-ssl-client-cert-pp\"=\"no\"", MessageType.ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check can encrypt
|
||||
if (! SystemInfo.isWindows) {
|
||||
if (ISVNAuthenticationManager.SSL.equals(kind)) {
|
||||
try {
|
||||
if (! isStorePlainTextPassphrases(realm, auth)) {
|
||||
final SVNSSLAuthentication svnsslAuthentication = (SVNSSLAuthentication)auth;
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showWarningDialog(myProject, "Your passphrase for client certificate:\n\n" +
|
||||
svnsslAuthentication.getCertificateFile().getPath() +
|
||||
"\n\ncan only be stored to disk unencrypted. (Encryption is not supported)\n\n" +
|
||||
"But storage in plain text is not allowed.\nTo allow plain text passphrases caching, set \"store-ssl-client-cert-pp-plaintext\"=\"yes\"",
|
||||
"Cannot save passphrase");
|
||||
}
|
||||
});
|
||||
/*ChangesViewBalloonProblemNotifier.showMe(myProject, "Your passphrase for client certificate:\n" +
|
||||
svnsslAuthentication.getCertificateFile().getPath() +
|
||||
"\ncan only be stored to disk unencrypted! (Encryption is not supported)\n" +
|
||||
"But storage in plain text is not allowed.\nTo allow plain text passphrases caching, set \"store-ssl-client-cert-pp-plaintext\"=\"yes\"", MessageType.ERROR);*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (SVNException e) {
|
||||
// should not occur, anyway means not allowed
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (! isStorePlainTextPasswords(realm, auth)) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showWarningDialog(myProject, "Your password for authentication realm:\n\n" + realm +
|
||||
"\n\ncan only be stored to disk unencrypted. (Encryption is not supported)\n\n" +
|
||||
"But storage in plain text is not allowed.\nTo allow plain text passwords caching, set \"store-plaintext-passwords\"=\"yes\"",
|
||||
"Cannot save password");
|
||||
}
|
||||
});
|
||||
/*ChangesViewBalloonProblemNotifier.showMe(myProject, "Your password for authentication realm:\n" + realm +
|
||||
"\ncan only be stored to disk unencrypted! (Encryption is not supported)\n" +
|
||||
"But storage in plain text is not allowed.\nTo allow plain text passwords caching, set \"store-plaintext-passwords\"=\"yes\"", MessageType.ERROR);*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (SVNException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,11 +216,11 @@ public class SvnConfiguration implements ProjectComponent, JDOMExternalizable {
|
||||
return myOptions;
|
||||
}
|
||||
|
||||
public ISVNAuthenticationManager getAuthenticationManager(final SvnVcs svnVcs) {
|
||||
public SvnAuthenticationManager getAuthenticationManager(final SvnVcs svnVcs) {
|
||||
if (myAuthManager == null) {
|
||||
// reloaded when configuration directory changes
|
||||
myAuthManager = new SvnAuthenticationManager(myProject, new File(getConfigurationDirectory()));
|
||||
myAuthManager.setAuthenticationProvider(new SvnAuthenticationProvider(svnVcs));
|
||||
myAuthManager.setAuthenticationProvider(new SvnAuthenticationProvider(svnVcs, myInteractiveManager));
|
||||
myAuthManager.setRuntimeStorage(RUNTIME_AUTH_CACHE);
|
||||
}
|
||||
return myAuthManager;
|
||||
@@ -234,11 +234,11 @@ public class SvnConfiguration implements ProjectComponent, JDOMExternalizable {
|
||||
return myPassiveAuthManager;
|
||||
}
|
||||
|
||||
public ISVNAuthenticationManager getInteractiveManager(final SvnVcs svnVcs) {
|
||||
public SvnAuthenticationManager getInteractiveManager(final SvnVcs svnVcs) {
|
||||
if (myInteractiveManager == null) {
|
||||
myInteractiveManager = new SvnAuthenticationManager(myProject, new File(getConfigurationDirectory()));
|
||||
myInteractiveManager.setRuntimeStorage(RUNTIME_AUTH_CACHE);
|
||||
myInteractiveManager.setAuthenticationProvider(new SvnInteractiveAuthenticationProvider(svnVcs));
|
||||
myInteractiveManager.setAuthenticationProvider(new SvnInteractiveAuthenticationProvider(svnVcs, myInteractiveManager));
|
||||
}
|
||||
return myInteractiveManager;
|
||||
}
|
||||
|
||||
@@ -20,14 +20,16 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.GuiUtils;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationManager;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationNotifier;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.*;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
|
||||
import org.tmatesoft.svn.core.auth.SVNAuthentication;
|
||||
import org.tmatesoft.svn.core.auth.SVNUserNameAuthentication;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
@@ -40,10 +42,10 @@ public class SvnAuthenticationProvider implements ISVNAuthenticationProvider {
|
||||
private final SvnAuthenticationNotifier myAuthenticationNotifier;
|
||||
private final SvnInteractiveAuthenticationProvider mySvnInteractiveAuthenticationProvider;
|
||||
|
||||
public SvnAuthenticationProvider(final SvnVcs svnVcs) {
|
||||
public SvnAuthenticationProvider(final SvnVcs svnVcs, final SvnAuthenticationManager manager) {
|
||||
myProject = svnVcs.getProject();
|
||||
myAuthenticationNotifier = svnVcs.getAuthNotifier();
|
||||
mySvnInteractiveAuthenticationProvider = new SvnInteractiveAuthenticationProvider(svnVcs);
|
||||
mySvnInteractiveAuthenticationProvider = new SvnInteractiveAuthenticationProvider(svnVcs, manager);
|
||||
}
|
||||
|
||||
private void log(final String s) {
|
||||
|
||||
+15
-7
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.GuiUtils;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationManager;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnConfiguration;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
@@ -35,9 +36,11 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
private final Project myProject;
|
||||
private static final ThreadLocal<MyCallState> myCallState = new ThreadLocal<MyCallState>();
|
||||
private final SvnVcs myVcs;
|
||||
private final SvnAuthenticationManager myManager;
|
||||
|
||||
public SvnInteractiveAuthenticationProvider(final SvnVcs vcs) {
|
||||
public SvnInteractiveAuthenticationProvider(final SvnVcs vcs, SvnAuthenticationManager manager) {
|
||||
myVcs = vcs;
|
||||
myManager = manager;
|
||||
myProject = vcs.getProject();
|
||||
}
|
||||
|
||||
@@ -83,7 +86,7 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
}
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
result[0] = new SVNPasswordAuthentication(dialog.getUserName(), dialog.getPassword(), dialog.isSaveAllowed());
|
||||
result[0] = new SVNPasswordAuthentication(dialog.getUserName(), dialog.getPassword(), dialog.isSaveAllowed(), url, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -104,7 +107,7 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
}
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
result[0] = new SVNUserNameAuthentication(dialog.getUserName(), dialog.isSaveAllowed());
|
||||
result[0] = new SVNUserNameAuthentication(dialog.getUserName(), dialog.isSaveAllowed(), url, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -129,10 +132,11 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
passphrase = null;
|
||||
}
|
||||
result[0] =
|
||||
new SVNSSHAuthentication(dialog.getUserName(), new File(dialog.getKeyFile()), passphrase, port, dialog.isSaveAllowed());
|
||||
new SVNSSHAuthentication(dialog.getUserName(), new File(dialog.getKeyFile()), passphrase, port, dialog.isSaveAllowed(),
|
||||
url, false);
|
||||
}
|
||||
else {
|
||||
result[0] = new SVNSSHAuthentication(dialog.getUserName(), dialog.getPassword(), port, dialog.isSaveAllowed());
|
||||
result[0] = new SVNSSHAuthentication(dialog.getUserName(), dialog.getPassword(), port, dialog.isSaveAllowed(), url, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +154,7 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
result[0] = new SVNSSLAuthentication(new File(dialog.getCertificatePath()), String.valueOf(dialog.getCertificatePassword()),
|
||||
dialog.getSaveAuth());
|
||||
dialog.getSaveAuth(), url, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -168,7 +172,11 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
|
||||
}
|
||||
log("3 authentication result: " + result[0]);
|
||||
}
|
||||
callState.setWasCancelled(result[0] == null);
|
||||
final boolean wasCanceled = result[0] == null;
|
||||
callState.setWasCancelled(wasCanceled);
|
||||
if ((! wasCanceled) && (ISVNAuthenticationManager.USERNAME != kind) && (result[0].isStorageAllowed())) {
|
||||
myManager.checkContinueSaveCredentials(result[0], kind, realm);
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user