From dce16175ac6830e0ad4f4f09442a4638aec2490d Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Fri, 25 Mar 2011 13:54:18 +0300 Subject: [PATCH] IDEA-66991 Allow cloning from github using ssh protocol in case if user has write access to the repo IDEA-66869 Cannot clone watched PRIVATE repository from Github --- .../github/GithubCheckoutProvider.java | 12 +++++-- .../jetbrains/plugins/github/GithubUtil.java | 34 +++++++++++++++++++ .../plugins/github/RepositoryInfo.java | 11 ++++++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java index db926545b20b..d1d7e4a877fc 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java @@ -68,14 +68,20 @@ public class GithubCheckoutProvider implements CheckoutProvider { // All the preliminary work is already done, go and clone the selected repository! final RepositoryInfo selectedRepository = checkoutDialog.getSelectedRepository(); + final boolean writeAccessAllowed = GithubUtil.isWriteAccessAllowed(project, selectedRepository); + if (!writeAccessAllowed){ + Messages.showErrorDialog(project, "It seems that you have only read access to the selected repository.\n" + + "GitHub supports only https protocol for readonly access, which is not supported yet.\n" + + "More details are available here: http://youtrack.jetbrains.net/issue/IDEA-55298", "Cannot clone this repository"); + return; + } + final String host = writeAccessAllowed ? "git@" + settings.getHost() + ":" : "https://github.com" + settings.getHost() + "/"; final String selectedPath = checkoutDialog.getSelectedPath(); final VirtualFile selectedPathFile = LocalFileSystem.getInstance().findFileByPath(selectedPath); final String projectName = checkoutDialog.getProjectName(); final String repositoryName = selectedRepository.getName(); final String repositoryOwner = selectedRepository.getOwner(); - final String checkoutUrl = settings.getLogin().equals(repositoryOwner) - ? "git@github.com:" + repositoryOwner + "/" + repositoryName + ".git" - : "https://github.com/" + repositoryOwner + "/" + repositoryName + ".git"; + final String checkoutUrl = host + repositoryOwner + "/" + repositoryName + ".git"; GitCheckoutProvider.checkout(project, listener, selectedPathFile, checkoutUrl, projectName, "origin", selectedPath); } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 9cac56ee2348..ce4b8a94e456 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -139,6 +139,29 @@ public class GithubUtil { return Collections.emptyList(); } + public static boolean isPushableRepo(final String url, final String login, final String password, final RepositoryInfo repositoryInfo) { + try { + final HttpMethod method = doREST(url, login, password, "/repos/pushable", 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: " + "/repos/pushable"); + return false; + } + final List repositories = element.getChildren(); + for (int i = 0; i < repositories.size(); i++) { + final Element repo = (Element)repositories.get(i); + if (repositoryInfo.equals(new RepositoryInfo(repo))){ + return true; + } + } + } + catch (Exception e) { + // ignore + } + return false; + } + @Nullable public static RepositoryInfo getDetailedRepoInfo(final String url, final String login, final String password, final String name) { try { @@ -325,4 +348,15 @@ public class GithubUtil { } return null; } + + public static boolean isWriteAccessAllowed(final Project project, final RepositoryInfo repo) { + final GithubSettings settings = GithubSettings.getInstance(); + return accessToGithubWithModalProgress(project, new Computable() { + @Override + public Boolean compute() { + ProgressManager.getInstance().getProgressIndicator().setText("Extracting info about pushable repositories"); + return isPushableRepo(settings.getHost(), settings.getLogin(), settings.getPassword(), repo); + } + }); + } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java b/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java index 592b452b37e1..7d33bf5975e0 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java +++ b/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java @@ -1,5 +1,6 @@ package org.jetbrains.plugins.github; +import com.intellij.openapi.util.Comparing; import org.jdom.Element; /** @@ -28,4 +29,14 @@ public class RepositoryInfo { public String getParent() { return myRepository.getChildText("parent"); } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof RepositoryInfo)){ + return false; + } + final RepositoryInfo repositoryInfo = (RepositoryInfo)obj; + return Comparing.equal(getName(), repositoryInfo.getName()) && + Comparing.equal(getOwner(), repositoryInfo.getOwner()); + } }