mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[Mercurial] IDEA-56180: remembering visited URLs, logins and passwords. Also fixed a bug which was preventing cloning (related to IDEA-55930).
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
<orderEntry type="module" module-name="testFramework" scope="TEST" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
<orderEntry type="module" module-name="vcs-impl" />
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -15,6 +15,12 @@ package org.zmlx.hg4idea;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@State(
|
||||
name = "hg4idea.settings",
|
||||
@@ -27,6 +33,32 @@ public class HgGlobalSettings implements PersistentStateComponent<HgGlobalSettin
|
||||
|
||||
private String hgExecutable = HG;
|
||||
|
||||
// visited URL -> list of logins for this URL. Passwords are remembered in the PasswordSafe.
|
||||
private Map<String, List<String>> myRememberedUrls = new HashMap<String, List<String>>();
|
||||
|
||||
/**
|
||||
* Returns the rememebered urls which were accessed while working in the plugin.
|
||||
* @return key is a String representation of a URL, value is the list (probably empty) of logins remembered for this URL.
|
||||
*/
|
||||
@NotNull
|
||||
public Map<String, List<String>> getRememberedUrls() {
|
||||
return myRememberedUrls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the information about visited URL.
|
||||
* @param stringUrl String representation of the URL.
|
||||
* @param username Login used to access the URL.
|
||||
*/
|
||||
public void addRememberedUrl(@NotNull String stringUrl, @NotNull String username) {
|
||||
List<String> list = myRememberedUrls.get(stringUrl);
|
||||
if (list == null) {
|
||||
list = new LinkedList<String>();
|
||||
myRememberedUrls.put(stringUrl, list);
|
||||
}
|
||||
list.add(username);
|
||||
}
|
||||
|
||||
public static String getDefaultExecutable() {
|
||||
return HG;
|
||||
}
|
||||
|
||||
@@ -341,4 +341,7 @@ public class HgVcs extends AbstractVcs {
|
||||
return globalSettings.getHgExecutable();
|
||||
}
|
||||
|
||||
public HgGlobalSettings getGlobalSettings() {
|
||||
return globalSettings;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,22 +12,32 @@
|
||||
// limitations under the License.
|
||||
package org.zmlx.hg4idea.command;
|
||||
|
||||
import com.intellij.ide.passwordSafe.PasswordSafe;
|
||||
import com.intellij.ide.passwordSafe.PasswordSafeException;
|
||||
import com.intellij.idea.LoggerFactory;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.zmlx.hg4idea.HgGlobalSettings;
|
||||
import org.zmlx.hg4idea.HgVcs;
|
||||
import org.zmlx.hg4idea.ui.HgUsernamePasswordDialog;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Base class for any command interacting with a remote repository and which needs authentication.
|
||||
*/
|
||||
class HgCommandAuthenticator {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(HgCommandAuthenticator.class.getName());
|
||||
|
||||
@Nullable
|
||||
protected HgCommandResult executeCommandAndAuthenticateIfNecessary(Project project, VirtualFile localRepository, String remoteRepository, String command, List<String> arguments) {
|
||||
HgCommandService service = HgCommandService.getInstance(project);
|
||||
@@ -47,8 +57,20 @@ class HgCommandAuthenticator {
|
||||
hgUrl.setUsername( runnable.getUserName() );
|
||||
hgUrl.setPassword(String.valueOf( runnable.getPassword() ));
|
||||
|
||||
arguments.set(arguments.size() - 1, hgUrl.asString());
|
||||
arguments.set(0, hgUrl.asString());
|
||||
result = service.execute(localRepository, command, arguments);
|
||||
|
||||
if (result != null && result.getExitValue() == 0) {
|
||||
final String key = keyForUrlAndLogin(runnable.getURL(), runnable.getUserName());
|
||||
try {
|
||||
PasswordSafe.getInstance().storePassword(project, HgCommandAuthenticator.class, key, runnable.getPassword());
|
||||
HgVcs.getInstance(project).getGlobalSettings().addRememberedUrl(runnable.getURL(), runnable.getUserName());
|
||||
}
|
||||
catch (PasswordSafeException e) {
|
||||
LOG.error("Couldn't store the password for key [" + key + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
@@ -62,9 +84,11 @@ class HgCommandAuthenticator {
|
||||
|
||||
private final HgUrl hgUrl;
|
||||
private String userName;
|
||||
private char[] password;
|
||||
private String myPassword;
|
||||
private Project project;
|
||||
private boolean ok = false;
|
||||
private static final Logger LOG = Logger.getInstance(GetPasswordRunnable.class.getName());
|
||||
private String myURL;
|
||||
|
||||
public GetPasswordRunnable(Project project, HgUrl hgUrl) {
|
||||
this.hgUrl = hgUrl;
|
||||
@@ -72,13 +96,50 @@ class HgCommandAuthenticator {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
final HgUsernamePasswordDialog dialog = new HgUsernamePasswordDialog(project, hgUrl.getUsername());
|
||||
dialog.show();
|
||||
|
||||
// get the string representation of the url
|
||||
@Nullable String stringUrl = null;
|
||||
try {
|
||||
stringUrl = hgUrl.asString();
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
LOG.warn("Couldn't parse hgUrl: [" + hgUrl + "]", e);
|
||||
}
|
||||
|
||||
// find if we've already been here
|
||||
final HgGlobalSettings hgGlobalSettings = HgVcs.getInstance(project).getGlobalSettings();
|
||||
final Map<String, List<String>> urls = hgGlobalSettings.getRememberedUrls();
|
||||
@Nullable List<String> rememberedLoginsForUrl = urls.get(stringUrl);
|
||||
|
||||
String login = hgUrl.getUsername();
|
||||
if (StringUtils.isBlank(login)) {
|
||||
// find the last used login
|
||||
if (rememberedLoginsForUrl != null && !rememberedLoginsForUrl.isEmpty()) {
|
||||
login = rememberedLoginsForUrl.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
String password = hgUrl.getPassword();
|
||||
if (StringUtils.isBlank(password) && stringUrl != null) {
|
||||
// if we've logged in with this login, search for password
|
||||
final String key = keyForUrlAndLogin(stringUrl, login);
|
||||
try {
|
||||
password = PasswordSafe.getInstance().getPassword(project, HgCommandAuthenticator.class, key);
|
||||
} catch (PasswordSafeException e) {
|
||||
LOG.error("Couldn't get password for key [" + key + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
final HgUsernamePasswordDialog dialog = new HgUsernamePasswordDialog(project, login, password);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
userName = dialog.getUsername();
|
||||
password = dialog.getPassword();
|
||||
myPassword = dialog.getPassword();
|
||||
ok = true;
|
||||
|
||||
if (dialog.isRememberPassword() && stringUrl != null) {
|
||||
myURL = stringUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,13 +147,21 @@ class HgCommandAuthenticator {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public char[] getPassword() {
|
||||
return password.clone();
|
||||
public String getPassword() {
|
||||
return myPassword;
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return ok;
|
||||
}
|
||||
|
||||
public String getURL() {
|
||||
return myURL;
|
||||
}
|
||||
}
|
||||
|
||||
private static String keyForUrlAndLogin(String stringUrl, String login) {
|
||||
return stringUrl + login;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ package org.zmlx.hg4idea.ui;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.util.net.AuthenticationPanel;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.zmlx.hg4idea.HgVcsMessages;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -22,10 +23,10 @@ import javax.swing.*;
|
||||
public class HgUsernamePasswordDialog extends DialogWrapper {
|
||||
private AuthenticationPanel authPanel;
|
||||
|
||||
public HgUsernamePasswordDialog(Project project, String login) {
|
||||
public HgUsernamePasswordDialog(Project project, String login, String password) {
|
||||
super(project, false);
|
||||
setTitle(HgVcsMessages.message("hgidea.dialog.login.password.required"));
|
||||
authPanel = new AuthenticationPanel(null, login, "", false);
|
||||
authPanel = new AuthenticationPanel(null, login, password, !StringUtils.isBlank(password));
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -42,8 +43,12 @@ public class HgUsernamePasswordDialog extends DialogWrapper {
|
||||
return authPanel.getLogin();
|
||||
}
|
||||
|
||||
public char[] getPassword() {
|
||||
return authPanel.getPassword().toCharArray();
|
||||
public String getPassword() {
|
||||
return authPanel.getPassword();
|
||||
}
|
||||
|
||||
public boolean isRememberPassword() {
|
||||
return authPanel.isRememberPassword();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user