diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java index c9a9cde06a42..1bf837fd04c5 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java @@ -29,7 +29,6 @@ import git4idea.checkin.GitPushUtils; import git4idea.commands.*; import git4idea.i18n.GitBundle; import git4idea.ui.GitUIUtil; -import org.jetbrains.plugins.github.ui.GithubLoginDialog; import org.jetbrains.plugins.github.ui.GithubShareDialog; import javax.swing.*; @@ -83,21 +82,29 @@ public class GithubShareAction extends DumbAwareAction { } BasicAction.saveAll(); - final GithubSettings settings = GithubSettings.getInstance(); - if (!GithubUtil.testConnection(settings.getLogin(), settings.getPassword())){ - final GithubLoginDialog dialog = new GithubLoginDialog(project); - dialog.show(); - if (!dialog.isOK()) { - return; - } + final List availableRepos = GithubUtil.getAvailableRepos(project, true); + if (availableRepos == null){ + return; } - final HashSet names = new HashSet(); - for (RepositoryInfo info : GithubUtil.getAvailableRepos(settings.getLogin(), settings.getPassword())) { + for (RepositoryInfo info : availableRepos) { names.add(info.getName()); } - final boolean privateRepoAllowed = GithubUtil.isPrivateRepoAllowed(settings.getLogin(), settings.getPassword()); + final GithubSettings settings = GithubSettings.getInstance(); + final boolean privateRepoAllowed; + try { + privateRepoAllowed = GithubUtil.accessToGithubWithModalProgress(project, new Computable() { + @Override + public Boolean compute() { + ProgressManager.getInstance().getProgressIndicator().setText("Trying to login to GitHub"); + return GithubUtil.isPrivateRepoAllowed(settings.getLogin(), settings.getPassword()); + } + }); + } + catch (GithubUtil.CancelledException ex) { + return; + } final GithubShareDialog shareDialog = new GithubShareDialog(project, names, privateRepoAllowed); shareDialog.show(); if (!shareDialog.isOK()) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 7aff71f0ee95..f2399d1ca986 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -1,5 +1,6 @@ package org.jetbrains.plugins.github; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; @@ -16,6 +17,8 @@ import org.apache.commons.httpclient.methods.PostMethod; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.github.ui.GithubLoginDialog; import java.io.InputStream; import java.util.ArrayList; @@ -28,6 +31,7 @@ import java.util.List; public class GithubUtil { public static final String GITHUB_HOST = "https://github.com"; private static final String API_URL = "/api/v2/xml"; + private static final Logger LOG = Logger.getInstance(GithubUtil.class.getName()); public static T accessToGithubWithModalProgress(final Project project, final Computable computable) throws CancelledException { final Ref result = new Ref(); @@ -81,11 +85,16 @@ public class GithubUtil { return GITHUB_HOST + API_URL; } - public static List getAvailableRepos(final String login, final String password) { + public static List getAvailableRepos(final String login, final String password, final boolean ownOnly) { try { - final HttpMethod method = doREST(login, password, "/repos/watched/" + login, false); + final String request = (ownOnly ? "/repos/show/" : "/repos/watched/") + login; + final HttpMethod method = doREST(login, password, request, false); final InputStream stream = method.getResponseBodyAsStream(); final Element element = new SAXBuilder(false).build(stream).getRootElement(); + if ("error".equals(element.getName())){ + LOG.warn("Got error element by request: " + request); + return Collections.emptyList(); + } final List repositories = element.getChildren(); final List result = new ArrayList(); for (int i = 0; i < repositories.size(); i++) { @@ -102,9 +111,14 @@ public class GithubUtil { public static boolean isPrivateRepoAllowed(final String login, final String password) { try { - final HttpMethod method = doREST(login, password, "/user/show/" + login, false); + final String request = "/user/show/" + login; + final HttpMethod method = doREST(login, password, request, false); final InputStream stream = method.getResponseBodyAsStream(); final Element element = new SAXBuilder(false).build(stream).getRootElement(); + if ("error".equals(element.getName())){ + LOG.warn("Got error element by request: " + request); + return false; + } final Element plan = element.getChild("plan"); assert plan != null : "Authentification failed"; final String privateRepos = plan.getChildText("private_repos"); @@ -117,4 +131,48 @@ public class GithubUtil { } public static class CancelledException extends RuntimeException {} + + /** + * Shows GitHub login settings if credentials are wrong or empty and return the list of all the watched repos by user + * @param project + * @return + */ + @Nullable + public static List getAvailableRepos(final Project project, final boolean ownOnly) { + final GithubSettings settings = GithubSettings.getInstance(); + final boolean validCredentials; + try { + validCredentials = accessToGithubWithModalProgress(project, new Computable() { + @Override + public Boolean compute() { + ProgressManager.getInstance().getProgressIndicator().setText("Trying to login to GitHub"); + return testConnection(settings.getLogin(), settings.getPassword()); + } + }); + } + catch (CancelledException e) { + return null; + } + if (!validCredentials){ + final GithubLoginDialog dialog = new GithubLoginDialog(project); + dialog.show(); + if (!dialog.isOK()) { + return null; + } + } + // Otherwise our credentials are valid and they are successfully stored in settings + try { + return accessToGithubWithModalProgress(project, new Computable>() { + @Override + public List compute() { + ProgressManager.getInstance().getProgressIndicator().setText("Extracting info about available repositories"); + return getAvailableRepos(settings.getLogin(), settings.getPassword(), ownOnly); + } + }); + } + catch (CancelledException e) { + return null; + } + } + }