mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
1) no proxy with current thread (same host can serve Svn and other services)
2) correctly form proxy auth request from Svn when IDEA proxy is used (requestor type = proxy) 3) release no proxy after Svn request 4) correctly check in passive validation (whether remote calls have credentials) - when IDEA proxy & autodetection & no credentials
This commit is contained in:
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.popup.util.PopupUtil;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.net.HTTPProxySettingsPanel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,11 +48,11 @@ public class CommonProxy extends ProxySelector {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.util.proxy.CommonProxy");
|
||||
private final Object myLock;
|
||||
private final Set<HostInfo> myNoProxy;
|
||||
private final Set<Pair<HostInfo, Thread>> myNoProxy;
|
||||
|
||||
private final Map<String, ProxySelector> myCustom;
|
||||
private final Map<String, NonStaticAuthenticator> myCustomAuth;
|
||||
private final Set<HostInfo> myNoAuthentication;
|
||||
private final Set<Pair<HostInfo, Thread>> myNoAuthentication;
|
||||
|
||||
public static CommonProxy getInstance() {
|
||||
return ourInstance;
|
||||
@@ -59,12 +60,12 @@ public class CommonProxy extends ProxySelector {
|
||||
|
||||
public CommonProxy() {
|
||||
myLock = new Object();
|
||||
myNoProxy = new HashSet<HostInfo>();
|
||||
myNoProxy = new HashSet<Pair<HostInfo, Thread>>();
|
||||
myCustom = new HashMap<String, ProxySelector>();
|
||||
myCustomAuth = new HashMap<String, NonStaticAuthenticator>();
|
||||
myAuthenticator = new CommonAuthenticator();
|
||||
ensureAuthenticator();
|
||||
myNoAuthentication = new HashSet<HostInfo>();
|
||||
myNoAuthentication = new HashSet<Pair<HostInfo, Thread>>();
|
||||
}
|
||||
|
||||
public static void isInstalledAssertion() {
|
||||
@@ -110,28 +111,28 @@ public class CommonProxy extends ProxySelector {
|
||||
public void noProxy(@NotNull final String protocol, @NotNull final String host, final int port) {
|
||||
synchronized (myLock) {
|
||||
LOG.debug("no proxy added: " + protocol + "://" + host + ":" + port);
|
||||
myNoProxy.add(new HostInfo(protocol, host, port));
|
||||
myNoProxy.add(Pair.create(new HostInfo(protocol, host, port), Thread.currentThread()));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeNoProxy(@NotNull final String protocol, @NotNull final String host, final int port) {
|
||||
synchronized (myLock) {
|
||||
LOG.debug("no proxy removed: " + protocol + "://" + host + ":" + port);
|
||||
myNoProxy.remove(new HostInfo(protocol, host, port));
|
||||
myNoProxy.remove(Pair.create(new HostInfo(protocol, host, port), Thread.currentThread()));
|
||||
}
|
||||
}
|
||||
|
||||
public void noAuthentication(@NotNull final String protocol, @NotNull final String host, final int port) {
|
||||
synchronized (myLock) {
|
||||
LOG.debug("no proxy added: " + protocol + "://" + host + ":" + port);
|
||||
myNoProxy.add(new HostInfo(protocol, host, port));
|
||||
myNoProxy.add(Pair.create(new HostInfo(protocol, host, port), Thread.currentThread()));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeNoAuthentication(@NotNull final String protocol, @NotNull final String host, final int port) {
|
||||
synchronized (myLock) {
|
||||
LOG.debug("no proxy removed: " + protocol + "://" + host + ":" + port);
|
||||
myNoProxy.remove(new HostInfo(protocol, host, port));
|
||||
myNoProxy.remove(Pair.create(new HostInfo(protocol, host, port), Thread.currentThread()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +180,7 @@ public class CommonProxy extends ProxySelector {
|
||||
final HostInfo info = new HostInfo(protocol, host, port);
|
||||
final Map<String, ProxySelector> copy;
|
||||
synchronized (myLock) {
|
||||
if (myNoProxy.contains(info)) {
|
||||
if (myNoProxy.contains(Pair.create(info, Thread.currentThread()))) {
|
||||
LOG.debug("CommonProxy.select returns no proxy (in no proxy list) for " + uri.toString());
|
||||
return NO_PROXY_LIST;
|
||||
}
|
||||
@@ -220,11 +221,12 @@ public class CommonProxy extends ProxySelector {
|
||||
synchronized (myLock) {
|
||||
// for hosts defined as no proxy we will NOT pass authentication to not provoke credentials
|
||||
final HostInfo hostInfo = new HostInfo(getRequestingProtocol(), host, port);
|
||||
if (myNoProxy.contains(hostInfo)) {
|
||||
final Pair<HostInfo, Thread> pair = Pair.create(hostInfo, Thread.currentThread());
|
||||
if (myNoProxy.contains(pair)) {
|
||||
LOG.debug("CommonAuthenticator.getPasswordAuthentication found host in no proxies set (" + siteStr + ")");
|
||||
return null;
|
||||
}
|
||||
if (myNoAuthentication.contains(hostInfo)) {
|
||||
if (myNoAuthentication.contains(pair)) {
|
||||
LOG.debug("CommonAuthenticator.getPasswordAuthentication found host in no authentication set (" + siteStr + ")");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -389,7 +389,8 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
String realm,
|
||||
SVNErrorMessage errorMessage,
|
||||
SVNAuthentication authentication,
|
||||
SVNURL accessedLocation) throws SVNException {
|
||||
SVNURL url) throws SVNException {
|
||||
CommonProxy.getInstance().removeNoProxy(url.getProtocol(), url.getHost(), url.getPort());
|
||||
}
|
||||
|
||||
public ISVNProxyManager getProxyManager(SVNURL url) throws SVNException {
|
||||
@@ -465,7 +466,8 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
try {
|
||||
final InetAddress ia = InetAddress.getByName(getProxyHost());
|
||||
final PasswordAuthentication authentication =
|
||||
Authenticator.requestPasswordAuthentication(ia, getProxyPort(), myProtocol, getProxyHost(), myProtocol);
|
||||
Authenticator.requestPasswordAuthentication(getProxyHost(), ia, getProxyPort(), myProtocol, getProxyHost(), myProtocol,
|
||||
null, Authenticator.RequestorType.PROXY);
|
||||
if (authentication != null) {
|
||||
myProxyUser = authentication.getUserName();
|
||||
myProxyPassword = String.valueOf(authentication.getPassword());
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.util.net.HttpConfigurable;
|
||||
import com.intellij.util.proxy.CommonProxy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.dialogs.SvnInteractiveAuthenticationProvider;
|
||||
@@ -51,6 +52,7 @@ import org.tmatesoft.svn.core.wc.SVNWCClient;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
@@ -316,12 +318,36 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
|
||||
final String realm,
|
||||
final String kind, boolean interactive) {
|
||||
// we should also NOT show proxy credentials dialog if at least fixed proxy was used, so
|
||||
if (configuration.isIsUseDefaultProxy()) {
|
||||
Proxy proxyToRelease = null;
|
||||
if (! interactive && configuration.isIsUseDefaultProxy()) {
|
||||
final HttpConfigurable instance = HttpConfigurable.getInstance();
|
||||
if (instance.USE_HTTP_PROXY && instance.PROXY_AUTHENTICATION && (StringUtil.isEmptyOrSpaces(instance.PROXY_LOGIN) ||
|
||||
StringUtil.isEmptyOrSpaces(instance.getPlainProxyPassword()))) {
|
||||
return false;
|
||||
}
|
||||
if (instance.USE_PROXY_PAC) {
|
||||
final List<Proxy> select;
|
||||
try {
|
||||
select = CommonProxy.getInstance().select(new URI(url.toString()));
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
LOG.info("wrong URL: " + url.toString());
|
||||
return false;
|
||||
}
|
||||
if (select != null && ! select.isEmpty()) {
|
||||
for (Proxy proxy : select) {
|
||||
if (HttpConfigurable.isRealProxy(proxy) && Proxy.Type.HTTP.equals(proxy.type())) {
|
||||
final InetSocketAddress address = (InetSocketAddress)proxy.address();
|
||||
final PasswordAuthentication password =
|
||||
HttpConfigurable.getInstance().getGenericPassword(address.getHostName(), address.getPort());
|
||||
if (password == null) {
|
||||
CommonProxy.getInstance().noAuthentication("http", address.getHostName(), address.getPort());
|
||||
proxyToRelease = proxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SvnInteractiveAuthenticationProvider.clearCallState();
|
||||
try {
|
||||
@@ -339,32 +365,14 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
|
||||
}
|
||||
LOG.info("some other exc", e);
|
||||
if (interactive) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
VcsBalloonProblemNotifier.showOverChangesView(project, "Authentication failed: " + e.getMessage(), MessageType.ERROR,
|
||||
new NamedRunnable(SvnBundle.message("confirmation.title.clear.authentication.cache")) {
|
||||
@Override
|
||||
public void run() {
|
||||
SvnConfigurable.clearAuthenticationCache(project, null, configuration.getConfigurationDirectory());
|
||||
}
|
||||
},
|
||||
new NamedRunnable(SvnBundle.message("action.title.select.configuration.directory")) {
|
||||
@Override
|
||||
public void run() {
|
||||
SvnConfigurable.selectConfigirationDirectory(configuration.getConfigurationDirectory(),
|
||||
new Consumer<String>() {
|
||||
@Override
|
||||
public void consume(String s) {
|
||||
configuration.setConfigurationDirParameters(false, s);
|
||||
}
|
||||
}, project, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, ModalityState.NON_MODAL, project.getDisposed());
|
||||
showAuthenticationFailedWithHotFixes(project, configuration, e);
|
||||
}
|
||||
return false; /// !!!! any exception means user should be notified that authorization failed
|
||||
} finally {
|
||||
if (! interactive && configuration.isIsUseDefaultProxy() && proxyToRelease != null) {
|
||||
final InetSocketAddress address = (InetSocketAddress)proxyToRelease.address();
|
||||
CommonProxy.getInstance().noAuthentication("http", address.getHostName(), address.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
if (! checkWrite) {
|
||||
@@ -393,4 +401,38 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void showAuthenticationFailedWithHotFixes(final Project project,
|
||||
final SvnConfiguration configuration,
|
||||
final SVNException e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
VcsBalloonProblemNotifier.showOverChangesView(project, "Authentication failed: " + e.getMessage(), MessageType.ERROR,
|
||||
new NamedRunnable(
|
||||
SvnBundle.message("confirmation.title.clear.authentication.cache")) {
|
||||
@Override
|
||||
public void run() {
|
||||
SvnConfigurable.clearAuthenticationCache(project, null, configuration
|
||||
.getConfigurationDirectory());
|
||||
}
|
||||
},
|
||||
new NamedRunnable(SvnBundle.message("action.title.select.configuration.directory")) {
|
||||
@Override
|
||||
public void run() {
|
||||
SvnConfigurable
|
||||
.selectConfigirationDirectory(configuration.getConfigurationDirectory(),
|
||||
new Consumer<String>() {
|
||||
@Override
|
||||
public void consume(String s) {
|
||||
configuration
|
||||
.setConfigurationDirParameters(false, s);
|
||||
}
|
||||
}, project, null);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}, ModalityState.NON_MODAL, project.getDisposed());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user