SVN auth
[fedora-idea.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / SvnAuthenticationNotifier.java
blob537249cef4722a0da367ebc4128477c5f5aaf791
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.jetbrains.idea.svn;
18 import com.intellij.notification.NotificationType;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.application.ModalityState;
21 import com.intellij.openapi.diagnostic.Logger;
22 import com.intellij.openapi.progress.ProgressManager;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.ui.MessageType;
25 import com.intellij.openapi.util.Ref;
26 import com.intellij.openapi.util.text.StringUtil;
27 import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
28 import com.intellij.openapi.vcs.impl.GenericNotifierImpl;
29 import org.jetbrains.annotations.NotNull;
30 import org.jetbrains.annotations.Nullable;
31 import org.jetbrains.idea.svn.dialogs.SvnInteractiveAuthenticationProvider;
32 import org.tmatesoft.svn.core.SVNAuthenticationException;
33 import org.tmatesoft.svn.core.SVNCancelException;
34 import org.tmatesoft.svn.core.SVNException;
35 import org.tmatesoft.svn.core.SVNURL;
36 import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
37 import org.tmatesoft.svn.core.auth.SVNAuthentication;
38 import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
39 import org.tmatesoft.svn.core.wc.SVNRevision;
40 import org.tmatesoft.svn.core.wc.SVNWCClient;
42 import java.util.Collection;
43 import java.util.LinkedList;
44 import java.util.List;
46 public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthenticationNotifier.AuthenticationRequest, SVNURL> {
47 private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnAuthenticationNotifier");
49 private static final String ourGroupId = "Subversion";
50 private final SvnVcs myVcs;
51 private final RootsToWorkingCopies myRootsToWorkingCopies;
53 public SvnAuthenticationNotifier(final SvnVcs svnVcs) {
54 super(svnVcs.getProject(), ourGroupId, "Not Logged To Subversion", NotificationType.ERROR);
55 myVcs = svnVcs;
56 myRootsToWorkingCopies = myVcs.getRootsToWorkingCopies();
59 @Override
60 protected boolean ask(final AuthenticationRequest obj) {
61 final Ref<Boolean> resultRef = new Ref<Boolean>();
62 final boolean done = ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
63 public void run() {
64 final boolean result = interactiveValidation(obj.myProject, obj.getUrl(), obj.getRealm(), obj.getKind());
65 log("ask result for: " + obj.getUrl() + " is: " + result);
66 resultRef.set(result);
67 if (result) {
68 onStateChangedToSuccess(obj);
71 }, "Checking authorization state", true, myVcs.getProject());
72 return done && Boolean.TRUE.equals(resultRef.get());
75 private void onStateChangedToSuccess(final AuthenticationRequest obj) {
76 /*final List<SVNURL> outdatedRequests = new LinkedList<SVNURL>();
77 final Collection<SVNURL> keys = getAllCurrentKeys();
78 for (SVNURL key : keys) {
79 final SVNURL commonURLAncestor = SVNURLUtil.getCommonURLAncestor(key, obj.getUrl());
80 if ((! StringUtil.isEmptyOrSpaces(commonURLAncestor.getHost())) && (! StringUtil.isEmptyOrSpaces(commonURLAncestor.getPath()))) {
81 final AuthenticationRequest currObj = getObj(key);
82 if ((currObj != null) && passiveValidation(myVcs.getProject(), key, true, currObj.getRealm(), currObj.getKind())) {
83 outdatedRequests.add(key);
87 log("on state changed ");
88 ApplicationManager.getApplication().invokeLater(new Runnable() {
89 public void run() {
90 for (SVNURL key : outdatedRequests) {
91 removeLazyNotificationByKey(key);
94 }, ModalityState.NON_MODAL); */
97 @Override
98 public void ensureNotify(AuthenticationRequest obj) {
99 ChangesViewBalloonProblemNotifier.showMe(myVcs.getProject(), "You are not authenticated to '" + obj.getRealm() + "'." +
100 "To login, see pending notifications.", MessageType.ERROR);
101 super.ensureNotify(obj);
104 @NotNull
105 @Override
106 public SVNURL getKey(final AuthenticationRequest obj) {
107 // !!! wc's URL
108 return obj.getWcUrl();
111 @Nullable
112 public SVNURL getWcUrl(final AuthenticationRequest obj) {
113 if (obj.isOutsideCopies()) return null;
114 if (obj.getWcUrl() != null) return obj.getWcUrl();
116 final WorkingCopy copy = myRootsToWorkingCopies.getMatchingCopy(obj.getUrl());
117 if (copy != null) {
118 obj.setOutsideCopies(false);
119 obj.setWcUrl(copy.getUrl());
120 } else {
121 obj.setOutsideCopies(true);
123 return copy == null ? null : copy.getUrl();
126 @NotNull
127 @Override
128 protected String getNotificationContent(AuthenticationRequest obj) {
129 return "<a href=\"\">Click to fix.</a> Not logged to Subversion '" + obj.getRealm() + "' (" + obj.getUrl().toDecodedString() + ")";
132 public static class AuthenticationRequest {
133 private final Project myProject;
134 private final String myKind;
135 private final SVNURL myUrl;
136 private final String myRealm;
138 private SVNURL myWcUrl;
139 private boolean myOutsideCopies;
141 public AuthenticationRequest(Project project, String kind, SVNURL url, String realm) {
142 myProject = project;
143 myKind = kind;
144 myUrl = url;
145 myRealm = realm;
148 public boolean isOutsideCopies() {
149 return myOutsideCopies;
152 public void setOutsideCopies(boolean outsideCopies) {
153 myOutsideCopies = outsideCopies;
156 public SVNURL getWcUrl() {
157 return myWcUrl;
160 public void setWcUrl(SVNURL wcUrl) {
161 myWcUrl = wcUrl;
164 public String getKind() {
165 return myKind;
168 public SVNURL getUrl() {
169 return myUrl;
172 public String getRealm() {
173 return myRealm;
177 static void log(final Throwable t) {
178 LOG.debug(t);
181 static void log(final String s) {
182 LOG.debug(s);
185 public static boolean passiveValidation(final Project project, final SVNURL url, final boolean checkWrite,
186 final String realm, final String kind) {
187 final SvnConfiguration configuration = SvnConfiguration.getInstance(project);
188 final ISVNAuthenticationManager passiveManager = configuration.getPassiveAuthenticationManager();
189 return validationImpl(project, url, configuration, passiveManager, checkWrite, realm, kind);
192 public static boolean interactiveValidation(final Project project, final SVNURL url, final String realm, final String kind) {
193 final SvnConfiguration configuration = SvnConfiguration.getInstance(project);
194 final ISVNAuthenticationManager passiveManager = configuration.getInteractiveManager(SvnVcs.getInstance(project));
195 return validationImpl(project, url, configuration, passiveManager, true, realm, kind);
198 private static boolean validationImpl(final Project project, final SVNURL url,
199 final SvnConfiguration configuration, final ISVNAuthenticationManager manager,
200 final boolean checkWrite, final String realm, final String kind/*, final boolean passive*/) {
201 SvnInteractiveAuthenticationProvider.clearCallState();
202 try {
203 new SVNWCClient(manager, configuration.getOptions(project)).doInfo(url, SVNRevision.UNDEFINED, SVNRevision.HEAD);
204 } catch (SVNAuthenticationException e) {
205 log(e);
206 return false;
207 } catch (SVNCancelException e) {
208 log(e); // auth canceled
209 return false;
210 } catch (SVNException e) {
211 if (e.getErrorMessage().getErrorCode().isAuthentication()) {
212 log(e);
213 return false;
215 LOG.info("some other exc", e);
217 if (! checkWrite) {
218 return true;
220 /*if (passive) {
221 return SvnInteractiveAuthenticationProvider.wasCalled();
224 if (SvnInteractiveAuthenticationProvider.wasCalled() && SvnInteractiveAuthenticationProvider.wasCancelled()) return false;
225 if (SvnInteractiveAuthenticationProvider.wasCalled()) return true;
227 final SvnVcs svnVcs = SvnVcs.getInstance(project);
229 final SvnInteractiveAuthenticationProvider provider = new SvnInteractiveAuthenticationProvider(svnVcs);
230 final SVNAuthentication svnAuthentication = provider.requestClientAuthentication(kind, url, realm, null, null, true);
231 if (svnAuthentication != null) {
232 configuration.acknowledge(kind, realm, svnAuthentication);
233 /*try {
234 configuration.getAuthenticationManager(svnVcs).acknowledgeAuthentication(true, kind, realm, null, svnAuthentication);
236 catch (SVNException e) {
237 LOG.info(e);
238 // acknowledge at least in runtime
239 configuration.acknowledge(kind, realm, svnAuthentication);
241 return true;
243 return false;