Import of private organisations, repos and pull requests

Overall refactoring to inject GitHubLogin deep into the repo
and pull request importers and include the GitHub user's credentials
for cloning and fetching GitHub repositories.

Change-Id: I7808b09762f5af51a11d407eb68b2e7c7f5dce1b
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GuiceHttpModule.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GuiceHttpModule.java
index b235809..e608e38 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GuiceHttpModule.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GuiceHttpModule.java
@@ -31,6 +31,7 @@
 import com.googlesource.gerrit.plugins.github.wizard.VelocityControllerServlet;
 import com.googlesrouce.gerrit.plugins.github.git.CreateProjectStep;
 import com.googlesrouce.gerrit.plugins.github.git.GitCloneStep;
+import com.googlesrouce.gerrit.plugins.github.git.GitHubRepository;
 import com.googlesrouce.gerrit.plugins.github.git.GitImporter;
 import com.googlesrouce.gerrit.plugins.github.git.PullRequestImportJob;
 import com.googlesrouce.gerrit.plugins.github.git.ReplicateProjectStep;
@@ -54,6 +55,8 @@
         ReplicateProjectStep.class).build(ReplicateProjectStep.Factory.class));
     install(new FactoryModuleBuilder().implement(PullRequestImportJob.class,
         PullRequestImportJob.class).build(PullRequestImportJob.Factory.class));
+    install(new FactoryModuleBuilder().implement(GitHubRepository.class,
+        GitHubRepository.class).build(GitHubRepository.Factory.class));
 
     bind(RuntimeInstance.class).annotatedWith(
         Names.named("PluginRuntimeInstance")).toProvider(
diff --git a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/CreateProjectStep.java b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/CreateProjectStep.java
index eea6cfa..f68ab55 100644
--- a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/CreateProjectStep.java
+++ b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/CreateProjectStep.java
@@ -13,8 +13,6 @@
 // limitations under the License.
 package com.googlesrouce.gerrit.plugins.github.git;
 
-import java.net.MalformedURLException;
-
 import org.eclipse.jgit.lib.ProgressMonitor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -67,11 +65,12 @@
       MetaDataUpdate.User metaDataUpdateFactory, 
       GroupBackend groupBackend,
       ProjectCache projectCache,
+      GitHubRepository.Factory ghRepoFactory,
       @Assisted("organisation") String organisation,
       @Assisted("name") String repository,
       @Assisted("description") String description,
       @Assisted("username") String username) {
-    super(gitHubUrl, organisation, repository);
+    super(gitHubUrl, organisation, repository, ghRepoFactory);
     LOG.debug("Gerrit CreateProject " + organisation + "/" + repository);
 
     this.organisation = organisation;
diff --git a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitCloneStep.java b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitCloneStep.java
index b02cba5..a7d3b73 100644
--- a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitCloneStep.java
+++ b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitCloneStep.java
@@ -15,7 +15,6 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.net.MalformedURLException;
 
 import org.apache.commons.io.FileUtils;
 import org.eclipse.jgit.api.CloneCommand;
@@ -46,11 +45,12 @@
       MetaDataUpdate.User metaDataUpdateFactory, 
       GroupBackend groupBackend,
       ProjectCache projectCache,
+      GitHubRepository.Factory gitHubRepoFactory,
       @Assisted("organisation") String organisation,
       @Assisted("name") String repository)
       throws GitDestinationAlreadyExistsException,
       GitDestinationNotWritableException {
-    super(gitConfig.gitHubUrl, organisation, repository);
+    super(gitConfig.gitHubUrl, organisation, repository, gitHubRepoFactory);
     LOG.debug("GitHub Clone " + organisation + "/" + repository);
     this.gitDir = gitConfig.gitDir;
     this.destinationDirectory =
diff --git a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitHubRepository.java b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitHubRepository.java
index f2c1b9c..8fcb821 100644
--- a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitHubRepository.java
+++ b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitHubRepository.java
@@ -13,9 +13,13 @@
 // limitations under the License.
 package com.googlesrouce.gerrit.plugins.github.git;
 
+import javax.servlet.http.HttpServletRequest;
+
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import com.googlesource.gerrit.plugins.github.GitHubURL;
+import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
+import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider;
 
 public class GitHubRepository {
   public interface Factory {
@@ -23,16 +27,34 @@
         @Assisted("repository") String repository);
   }
 
-  public final String cloneUrl;
-  public final String organisation;
-  public final String repository;
+
+  private final String organisation;
+  private final String repository;
+  private final GitHubLogin ghLogin;
+  private final String cloneUrl;
+
+  public String getCloneUrl() {
+    return cloneUrl.replace("://", "://" + ghLogin.getMyself().getLogin() + ":"
+        + ghLogin.token.access_token + "@");
+  }
+
+  public String getOrganisation() {
+    return organisation;
+  }
+
+  public String getRepository() {
+    return repository;
+  }
+
 
   @Inject
-  public GitHubRepository(@GitHubURL String gitHubUrl,
+  public GitHubRepository(ScopedProvider<GitHubLogin> ghLoginProvider, HttpServletRequest httpRequest,
+      @GitHubURL String gitHubUrl,
       @Assisted("organisation") String organisation,
       @Assisted("repository") String repository) {
     this.cloneUrl = gitHubUrl + "/" + organisation + "/" + repository + ".git";
     this.organisation = organisation;
     this.repository = repository;
+    this.ghLogin = ghLoginProvider.get(httpRequest);
   }
 }
diff --git a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/ImportStep.java b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/ImportStep.java
index 42b134d..7efe78d 100644
--- a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/ImportStep.java
+++ b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/ImportStep.java
@@ -18,24 +18,24 @@
 import com.googlesource.gerrit.plugins.github.GitHubURL;
 
 public abstract class ImportStep {
-  protected String gitHubUrl;
   private final GitHubRepository gitHubRepository;
 
-  public ImportStep(@GitHubURL String gitHubUrl, String organisation, String repository) {
-    this.gitHubRepository = new GitHubRepository(gitHubUrl, organisation, repository);
-    this.gitHubUrl = gitHubUrl;
+  public ImportStep(@GitHubURL String gitHubUrl, String organisation,
+      String repository, GitHubRepository.Factory ghRepoFactory) {
+    this.gitHubRepository =
+        ghRepoFactory.create(organisation, repository);
   }
 
   protected String getSourceUri() {
-    return gitHubRepository.cloneUrl;
+    return gitHubRepository.getCloneUrl();
   }
-  
+
   public String getOrganisation() {
-    return gitHubRepository.organisation;
+    return gitHubRepository.getOrganisation();
   }
 
   public String getRepository() {
-    return gitHubRepository.repository;
+    return gitHubRepository.getRepository();
   }
 
   public abstract void doImport(ProgressMonitor progress) throws Exception;
diff --git a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/PullRequestImportJob.java b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/PullRequestImportJob.java
index 534379b..494a80b 100644
--- a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/PullRequestImportJob.java
+++ b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/PullRequestImportJob.java
@@ -17,6 +17,8 @@
 import java.net.URL;
 import java.util.List;
 
+import javax.servlet.http.HttpServletRequest;
+
 import org.eclipse.jgit.api.FetchCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.errors.GitAPIException;
@@ -70,6 +72,7 @@
 import com.google.inject.assistedinject.Assisted;
 import com.googlesource.gerrit.plugins.github.GitHubURL;
 import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
+import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider;
 import com.googlesrouce.gerrit.plugins.github.git.GitJobStatus.Code;
 
 public class PullRequestImportJob implements GitJob, ProgressMonitor {
@@ -106,17 +109,19 @@
   private AccountImpoter accountImporter;
 
   @Inject
-  public PullRequestImportJob(@GitHubURL String gitHubUrl, GitHubLogin ghLogin,
+  public PullRequestImportJob(@GitHubURL String gitHubUrl,
       GitRepositoryManager repoMgr, PullRequestCreateChange createChange,
       ProjectCache projectCache, ProjectControl.Factory projectControlFactory,
       Provider<ReviewDb> schema, AccountImpoter accountImporter,
-      @Assisted("index") int jobIndex,
+      GitHubRepository.Factory gitHubRepoFactory,
+      ScopedProvider<GitHubLogin> ghLoginProvider,
+      HttpServletRequest httpRequest, @Assisted("index") int jobIndex,
       @Assisted("organisation") String organisation,
       @Assisted("name") String repoName, @Assisted int pullRequestId,
       @Assisted PullRequestImportType importType) {
     this.jobIndex = jobIndex;
     this.repoMgr = repoMgr;
-    this.ghLogin = ghLogin;
+    this.ghLogin = ghLoginProvider.get(httpRequest);
     this.organisation = organisation;
     this.repoName = repoName;
     this.importType = importType;
@@ -124,7 +129,7 @@
     this.createChange = createChange;
     this.projectControlFactory = projectControlFactory;
     this.project = fetchGerritProject(projectCache, organisation, repoName);
-    this.ghRepository = new GitHubRepository(gitHubUrl, organisation, repoName);
+    this.ghRepository = gitHubRepoFactory.create(organisation, repoName);
     this.status = new GitJobStatus(jobIndex);
     this.schema = schema;
     this.accountImporter = accountImporter;
@@ -276,7 +281,7 @@
 
     Git git = Git.wrap(gitRepo);
     FetchCommand fetch = git.fetch();
-    fetch.setRemote(ghRepository.cloneUrl);
+    fetch.setRemote(ghRepository.getCloneUrl());
     fetch.setRefSpecs(new RefSpec("+refs/pull/" + pr.getNumber()
         + "/head:refs/remotes/origin/pr/" + pr.getNumber()));
     fetch.setProgressMonitor(this);
diff --git a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/ReplicateProjectStep.java b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/ReplicateProjectStep.java
index 9016391..253c0e4 100644
--- a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/ReplicateProjectStep.java
+++ b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/ReplicateProjectStep.java
@@ -13,6 +13,8 @@
 // limitations under the License.
 package com.googlesrouce.gerrit.plugins.github.git;
 
+import javax.servlet.http.HttpServletRequest;
+
 import org.eclipse.jgit.lib.ProgressMonitor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -21,12 +23,14 @@
 import com.google.inject.assistedinject.Assisted;
 import com.googlesource.gerrit.plugins.github.GitHubURL;
 import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
+import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider;
 
 public class ReplicateProjectStep extends ImportStep {
   private static final Logger LOG = LoggerFactory.getLogger(ReplicateProjectStep.class);
   private final ReplicationConfig replicationConfig;
   private final String authUsername;
   private final String authToken;
+  private final String gitHubUrl;
 
   public interface Factory {
     ReplicateProjectStep create(@Assisted("organisation") String organisation,
@@ -36,15 +40,19 @@
 
   @Inject
   public ReplicateProjectStep(final ReplicationConfig replicationConfig,
+      final GitHubRepository.Factory gitHubRepoFactory,
+      final ScopedProvider<GitHubLogin> ghLoginProvider,
+      final HttpServletRequest httpRequest,
       @GitHubURL String gitHubUrl,
       @Assisted("organisation") String organisation,
-      @Assisted("name") String repository,
-      @Assisted GitHubLogin ghLogin) {
-    super(gitHubUrl, organisation, repository);
+      @Assisted("name") String repository) {
+    super(gitHubUrl, organisation, repository, gitHubRepoFactory);
     LOG.debug("Gerrit ReplicateProject " + organisation + "/" + repository);
     this.replicationConfig = replicationConfig;
+    GitHubLogin ghLogin = ghLoginProvider.get(httpRequest);
     this.authUsername = ghLogin.getMyself().getLogin();
     this.authToken = ghLogin.token.access_token;
+    this.gitHubUrl = gitHubUrl;
   }
 
   @Override