Java tutorial
/* * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.idea.svn.dialogs; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.security.cert.X509Certificate; import javax.swing.SwingUtilities; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnAuthenticationManager; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnConfiguration; import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.auth.ProviderType; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNURL; 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.SVNPasswordAuthentication; import org.tmatesoft.svn.core.auth.SVNSSHAuthentication; import org.tmatesoft.svn.core.auth.SVNSSLAuthentication; import org.tmatesoft.svn.core.auth.SVNUserNameAuthentication; import org.tmatesoft.svn.core.internal.wc.ISVNHostOptions; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.util.WaitForProgressToShow; public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationProvider { private static final Logger LOG = Logger .getInstance("#org.jetbrains.idea.svn.dialogs.SvnInteractiveAuthenticationProvider"); private final Project myProject; private static final ThreadLocal<MyCallState> myCallState = new ThreadLocal<MyCallState>(); private final SvnAuthenticationManager myManager; public SvnInteractiveAuthenticationProvider(final SvnVcs vcs, SvnAuthenticationManager manager) { myManager = manager; myProject = vcs.getProject(); } public static void clearCallState() { myCallState.set(null); } public static boolean wasCalled() { return myCallState.get() != null && myCallState.get().isWasCalled(); } public static boolean wasCancelled() { return myCallState.get() != null && myCallState.get().isWasCancelled(); } public SVNAuthentication requestClientAuthentication(final String kind, final SVNURL url, final String realm, final SVNErrorMessage errorMessage, final SVNAuthentication previousAuth, final boolean authMayBeStored) { final MyCallState callState = new MyCallState(true, false); myCallState.set(callState); // once we came here, we don't know _correct_ auth todo +- final SvnConfiguration configuration = SvnConfiguration.getInstance(myProject); configuration.clearCredentials(kind, realm); final SVNAuthentication[] result = new SVNAuthentication[1]; Runnable command = null; final boolean authCredsOn = authMayBeStored && myManager.getHostOptionsProvider().getHostOptions(url).isAuthStorageEnabled(); final String userName = previousAuth != null && previousAuth.getUserName() != null ? previousAuth.getUserName() : myManager.getDefaultUsername(kind, url); if (ISVNAuthenticationManager.PASSWORD.equals(kind)) {// || ISVNAuthenticationManager.USERNAME.equals(kind)) { command = new Runnable() { public void run() { SimpleCredentialsDialog dialog = new SimpleCredentialsDialog(myProject); dialog.setup(realm, userName, authCredsOn); setTitle(dialog, errorMessage); dialog.show(); if (dialog.isOK()) { result[0] = new SVNPasswordAuthentication(dialog.getUserName(), dialog.getPassword(), dialog.isSaveAllowed(), url, false); } } }; } else if (ISVNAuthenticationManager.USERNAME.equals(kind)) { if (ApplicationManager.getApplication().isUnitTestMode()) { return new SVNUserNameAuthentication(userName, false); } command = new Runnable() { public void run() { UserNameCredentialsDialog dialog = new UserNameCredentialsDialog(myProject); dialog.setup(realm, userName, authCredsOn); setTitle(dialog, errorMessage); dialog.show(); if (dialog.isOK()) { result[0] = new SVNUserNameAuthentication(dialog.getUserName(), dialog.isSaveAllowed(), url, false); } } }; } else if (ISVNAuthenticationManager.SSH.equals(kind)) { // In current implementation, pageant connector available = operating system is Windows. // So "ssh agent" option will be always available on Windows, even if pageant is not running. //final Connector agentConnector = createSshAgentConnector(); final boolean isAgentAvailable = false;//agentConnector != null && agentConnector.isAvailable(); command = new Runnable() { public void run() { SSHCredentialsDialog dialog = new SSHCredentialsDialog(myProject, realm, userName, authCredsOn, url.getPort(), isAgentAvailable); setTitle(dialog, errorMessage); dialog.show(); if (dialog.isOK()) { int port = dialog.getPortNumber(); if (dialog.isSshAgentSelected()) { /*if (agentConnector != null) { result[0] = new SVNSSHAuthentication(dialog.getUserName(), new TrileadAgentProxy(agentConnector), port, url, false); }*/ } else if (dialog.getKeyFile() != null && dialog.getKeyFile().trim().length() > 0) { String passphrase = dialog.getPassphrase(); if (passphrase != null && passphrase.length() == 0) { passphrase = null; } result[0] = 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(), url, false); } } } }; } else if (ISVNAuthenticationManager.SSL.equals(kind)) { command = new Runnable() { public void run() { final ISVNHostOptions options = myManager.getHostOptionsProvider().getHostOptions(url); final String file = options.getSSLClientCertFile(); final SSLCredentialsDialog dialog = new SSLCredentialsDialog(myProject, realm, authCredsOn); if (!StringUtil.isEmptyOrSpaces(file)) { dialog.setFile(file); } setTitle(dialog, errorMessage); dialog.show(); if (dialog.isOK()) { result[0] = new SVNSSLAuthentication(new File(dialog.getCertificatePath()), String.valueOf(dialog.getCertificatePassword()), dialog.getSaveAuth(), url, false); } } }; } if (command != null) { WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(command); log("3 authentication result: " + result[0]); } final boolean wasCanceled = result[0] == null; callState.setWasCancelled(wasCanceled); myManager.requested(ProviderType.interactive, url, realm, kind, wasCanceled); return result[0]; } /*@Nullable private static Connector createSshAgentConnector() { Connector result = null; try { result = ConnectorFactory.getDefault().createConnector(); } catch (AgentProxyException e) { LOG.info("Could not create ssh agent connector", e); } return result; } */ private static void setTitle(@NotNull DialogWrapper dialog, @Nullable SVNErrorMessage errorMessage) { dialog.setTitle(errorMessage == null ? SvnBundle.message("dialog.title.authentication.required") : SvnBundle.message("dialog.title.authentication.required.was.failed")); } public int acceptServerAuthentication(final SVNURL url, String realm, final Object certificate, final boolean resultMayBeStored) { final int[] result = new int[1]; Runnable command; if (certificate instanceof X509Certificate) { command = new Runnable() { public void run() { ServerSSLDialog dialog = new ServerSSLDialog(myProject, (X509Certificate) certificate, resultMayBeStored); dialog.show(); result[0] = dialog.getResult(); } }; } else if (certificate instanceof byte[]) { final String sshKeyAlgorithm = myManager.getSSHKeyAlgorithm(); command = new Runnable() { @Override public void run() { final ServerSSHDialog serverSSHDialog = new ServerSSHDialog(myProject, resultMayBeStored, url.toDecodedString(), sshKeyAlgorithm, (byte[]) certificate); serverSSHDialog.show(); result[0] = serverSSHDialog.getResult(); } }; } else { VcsBalloonProblemNotifier.showOverChangesView(myProject, "Subversion: unknown certificate type from " + url.toDecodedString(), MessageType.ERROR); return REJECTED; } final ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator(); if (pi != null) { WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(command, pi.getModalityState()); } else { try { SwingUtilities.invokeAndWait(command); } catch (InterruptedException e) { // } catch (InvocationTargetException e) { // } } return result[0]; } private void log(final String s) { LOG.debug(s); } public static class MyCallState { private final boolean myWasCalled; private boolean myWasCancelled; public MyCallState(boolean wasCalled, boolean wasCancelled) { myWasCalled = wasCalled; myWasCancelled = wasCancelled; } public boolean isWasCalled() { return myWasCalled; } public boolean isWasCancelled() { return myWasCancelled; } public void setWasCancelled(boolean wasCancelled) { myWasCancelled = wasCancelled; } } }