Merge branch 'stable-2.8'

* stable-2.8:
  "repo download" supports authentication

Change-Id: I068a47d8f9bcc108a374795aff4a6e84179b3d5c
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/Module.java b/src/main/java/com/googlesource/gerrit/plugins/download/Module.java
index 3f6da18..14ff781 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/Module.java
@@ -14,45 +14,15 @@
 
 package com.googlesource.gerrit.plugins.download;
 
-import com.google.gerrit.extensions.annotations.Exports;
-import com.google.gerrit.extensions.config.DownloadCommand;
-import com.google.gerrit.extensions.config.DownloadScheme;
 import com.google.inject.AbstractModule;
 
-import com.googlesource.gerrit.plugins.download.command.CheckoutCommand;
-import com.googlesource.gerrit.plugins.download.command.CherryPickCommand;
-import com.googlesource.gerrit.plugins.download.command.FormatPatchCommand;
-import com.googlesource.gerrit.plugins.download.command.PullCommand;
-import com.googlesource.gerrit.plugins.download.command.RepoCommand;
-import com.googlesource.gerrit.plugins.download.scheme.AnonymousHttpScheme;
-import com.googlesource.gerrit.plugins.download.scheme.GitScheme;
-import com.googlesource.gerrit.plugins.download.scheme.HttpScheme;
-import com.googlesource.gerrit.plugins.download.scheme.RepoScheme;
-import com.googlesource.gerrit.plugins.download.scheme.SshScheme;
+import com.googlesource.gerrit.plugins.download.command.DownloadCommandsModule;
+import com.googlesource.gerrit.plugins.download.scheme.SchemeModule;
 
 class Module extends AbstractModule {
   @Override
   protected void configure() {
-    bind(DownloadScheme.class).annotatedWith(Exports.named("anonymous http"))
-        .to(AnonymousHttpScheme.class);
-    bind(DownloadScheme.class).annotatedWith(Exports.named("git"))
-        .to(GitScheme.class);
-    bind(DownloadScheme.class).annotatedWith(Exports.named("http"))
-        .to(HttpScheme.class);
-    bind(DownloadScheme.class).annotatedWith(Exports.named("repo"))
-        .to(RepoScheme.class);
-    bind(DownloadScheme.class).annotatedWith(Exports.named("ssh"))
-        .to(SshScheme.class);
-
-    bind(DownloadCommand.class).annotatedWith(Exports.named("Checkout"))
-        .to(CheckoutCommand.class);
-    bind(DownloadCommand.class).annotatedWith(Exports.named("Cherry-Pick"))
-        .to(CherryPickCommand.class);
-    bind(DownloadCommand.class).annotatedWith(Exports.named("Format-Patch"))
-        .to(FormatPatchCommand.class);
-    bind(DownloadCommand.class).annotatedWith(Exports.named("Pull"))
-        .to(PullCommand.class);
-    bind(DownloadCommand.class).annotatedWith(Exports.named("Repo-Download"))
-        .to(RepoCommand.class);
+    install(new DownloadCommandsModule());
+    install(new SchemeModule());
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/command/CheckoutCommand.java b/src/main/java/com/googlesource/gerrit/plugins/download/command/CheckoutCommand.java
index 349e56a..b415813 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/command/CheckoutCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/command/CheckoutCommand.java
@@ -16,19 +16,17 @@
 
 import static com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand.CHECKOUT;
 
-import com.google.gerrit.extensions.annotations.Listen;
 import com.google.gerrit.server.config.DownloadConfig;
 import com.google.inject.Inject;
 
-@Listen
-public class CheckoutCommand extends GitDownloadCommand {
+class CheckoutCommand extends GitDownloadCommand {
   @Inject
   CheckoutCommand(DownloadConfig downloadConfig) {
     super(downloadConfig, CHECKOUT);
   }
 
   @Override
-  public String getCommand(String url, String ref) {
+  String getCommand(String url, String ref) {
     return "git fetch " + url + " " + ref + " && git checkout FETCH_HEAD";
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/command/CherryPickCommand.java b/src/main/java/com/googlesource/gerrit/plugins/download/command/CherryPickCommand.java
index a357aa8..5490848 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/command/CherryPickCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/command/CherryPickCommand.java
@@ -16,19 +16,17 @@
 
 import static com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand.CHERRY_PICK;
 
-import com.google.gerrit.extensions.annotations.Listen;
 import com.google.gerrit.server.config.DownloadConfig;
 import com.google.inject.Inject;
 
-@Listen
-public class CherryPickCommand extends GitDownloadCommand {
+class CherryPickCommand extends GitDownloadCommand {
   @Inject
   CherryPickCommand(DownloadConfig downloadConfig) {
     super(downloadConfig, CHERRY_PICK);
   }
 
   @Override
-  public String getCommand(String url, String ref) {
+  String getCommand(String url, String ref) {
     return "git fetch " + url + " " + ref + " && git cherry-pick FETCH_HEAD";
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/command/DownloadCommandsModule.java b/src/main/java/com/googlesource/gerrit/plugins/download/command/DownloadCommandsModule.java
new file mode 100644
index 0000000..22ca5d3
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/command/DownloadCommandsModule.java
@@ -0,0 +1,44 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.download.command;
+
+import com.google.gerrit.extensions.annotations.Exports;
+import com.google.gerrit.extensions.config.DownloadCommand;
+import com.google.inject.AbstractModule;
+
+public class DownloadCommandsModule extends AbstractModule {
+  @Override
+  protected void configure() {
+    bind(DownloadCommand.class)
+      .annotatedWith(Exports.named("Checkout"))
+      .to(CheckoutCommand.class);
+
+    bind(DownloadCommand.class)
+      .annotatedWith(Exports.named("Cherry Pick"))
+      .to(CherryPickCommand.class);
+
+    bind(DownloadCommand.class)
+      .annotatedWith(Exports.named("Format Patch"))
+      .to(FormatPatchCommand.class);
+
+    bind(DownloadCommand.class)
+      .annotatedWith(Exports.named("Pull"))
+      .to(PullCommand.class);
+
+    bind(DownloadCommand.class)
+      .annotatedWith(Exports.named("repo"))
+      .to(RepoCommand.class);
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/command/FormatPatchCommand.java b/src/main/java/com/googlesource/gerrit/plugins/download/command/FormatPatchCommand.java
index aefa23f..67e1d17 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/command/FormatPatchCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/command/FormatPatchCommand.java
@@ -16,19 +16,17 @@
 
 import static com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand.FORMAT_PATCH;
 
-import com.google.gerrit.extensions.annotations.Listen;
 import com.google.gerrit.server.config.DownloadConfig;
 import com.google.inject.Inject;
 
-@Listen
-public class FormatPatchCommand extends GitDownloadCommand {
+class FormatPatchCommand extends GitDownloadCommand {
   @Inject
   FormatPatchCommand(DownloadConfig downloadConfig) {
     super(downloadConfig, FORMAT_PATCH);
   }
 
   @Override
-  public String getCommand(String url, String ref) {
+  String getCommand(String url, String ref) {
     return "git fetch " + url + " " + ref + " && git format-patch -1 --stdout FETCH_HEAD";
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/command/GitDownloadCommand.java b/src/main/java/com/googlesource/gerrit/plugins/download/command/GitDownloadCommand.java
index 61e3fbd..a290856 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/command/GitDownloadCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/command/GitDownloadCommand.java
@@ -21,12 +21,13 @@
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
 import com.google.gerrit.server.config.DownloadConfig;
 
-import com.googlesource.gerrit.plugins.download.scheme.AnonymousHttpScheme;
-import com.googlesource.gerrit.plugins.download.scheme.GitScheme;
-import com.googlesource.gerrit.plugins.download.scheme.HttpScheme;
-import com.googlesource.gerrit.plugins.download.scheme.SshScheme;
+import com.googlesource.gerrit.plugins.download.scheme.RepoScheme;
 
-public abstract class GitDownloadCommand extends DownloadCommand {
+import org.eclipse.jgit.transport.URIish;
+
+import java.net.URISyntaxException;
+
+abstract class GitDownloadCommand extends DownloadCommand {
   private final boolean commandAllowed;
 
   GitDownloadCommand(
@@ -38,23 +39,27 @@
   @Override
   public final String getCommand(DownloadScheme scheme, String project,
       String ref) {
-    if (!commandAllowed) {
-      return null;
-    }
-
-    if (scheme instanceof SshScheme
-        || scheme instanceof HttpScheme
-        || scheme instanceof AnonymousHttpScheme
-        || scheme instanceof GitScheme) {
+    if (commandAllowed && isRecognizedScheme(scheme)) {
       String url = scheme.getUrl(project);
-      if (url != null) {
+      if (url != null && isValidUrl(url)) {
         return getCommand(url, ref);
-      } else
-        return null;
-    } else {
-      return null;
+      }
+    }
+    return null;
+  }
+
+  private static boolean isRecognizedScheme(DownloadScheme scheme) {
+    return !(scheme instanceof RepoScheme);
+  }
+
+  private static boolean isValidUrl(String url) {
+    try {
+      new URIish(url);
+      return true;
+    } catch (URISyntaxException e) {
+      return false;
     }
   }
 
-  public abstract String getCommand(String url, String ref);
+  abstract String getCommand(String url, String ref);
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/command/PullCommand.java b/src/main/java/com/googlesource/gerrit/plugins/download/command/PullCommand.java
index d86a630..b70ff56 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/command/PullCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/command/PullCommand.java
@@ -16,19 +16,17 @@
 
 import static com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand.PULL;
 
-import com.google.gerrit.extensions.annotations.Listen;
 import com.google.gerrit.server.config.DownloadConfig;
 import com.google.inject.Inject;
 
-@Listen
-public class PullCommand extends GitDownloadCommand {
+class PullCommand extends GitDownloadCommand {
   @Inject
   PullCommand(DownloadConfig downloadConfig) {
     super(downloadConfig, PULL);
   }
 
   @Override
-  public String getCommand(String url, String ref) {
+  String getCommand(String url, String ref) {
     return "git pull " + url + " " + ref;
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/command/RepoCommand.java b/src/main/java/com/googlesource/gerrit/plugins/download/command/RepoCommand.java
index 2edfac3..6145d98 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/command/RepoCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/command/RepoCommand.java
@@ -23,7 +23,7 @@
 
 import com.googlesource.gerrit.plugins.download.scheme.RepoScheme;
 
-public class RepoCommand extends DownloadCommand {
+class RepoCommand extends DownloadCommand {
   private final boolean commandAllowed;
 
   @Inject
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/RepoScheme.java b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/RepoScheme.java
index 7397b0a..e5a0110 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/RepoScheme.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/RepoScheme.java
@@ -16,14 +16,11 @@
 
 import static com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme.REPO_DOWNLOAD;
 
-import com.google.gerrit.extensions.annotations.Listen;
 import com.google.gerrit.extensions.config.DownloadScheme;
 import com.google.gerrit.server.config.DownloadConfig;
 import com.google.inject.Inject;
 
-@Listen
 public class RepoScheme extends DownloadScheme {
-
   private final boolean schemeAllowed;
 
   @Inject
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SchemeModule.java b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SchemeModule.java
new file mode 100644
index 0000000..9a42fcc
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SchemeModule.java
@@ -0,0 +1,44 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.download.scheme;
+
+import com.google.gerrit.extensions.annotations.Exports;
+import com.google.gerrit.extensions.config.DownloadScheme;
+import com.google.inject.AbstractModule;
+
+public class SchemeModule extends AbstractModule {
+  @Override
+  protected void configure() {
+    bind(DownloadScheme.class)
+      .annotatedWith(Exports.named("anonymous http"))
+      .to(AnonymousHttpScheme.class);
+
+    bind(DownloadScheme.class)
+      .annotatedWith(Exports.named("git"))
+      .to(GitScheme.class);
+
+    bind(DownloadScheme.class)
+      .annotatedWith(Exports.named("http"))
+      .to(HttpScheme.class);
+
+    bind(DownloadScheme.class)
+      .annotatedWith(Exports.named("repo"))
+      .to(RepoScheme.class);
+
+    bind(DownloadScheme.class)
+      .annotatedWith(Exports.named("ssh"))
+      .to(SshScheme.class);
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SshScheme.java b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SshScheme.java
index 5e3c0da..f662060 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SshScheme.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SshScheme.java
@@ -18,7 +18,6 @@
 import static com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme.SSH;
 
 import com.google.gerrit.common.Nullable;
-import com.google.gerrit.extensions.annotations.Listen;
 import com.google.gerrit.extensions.config.DownloadScheme;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.config.CanonicalWebUrl;
@@ -31,7 +30,6 @@
 import java.net.URL;
 import java.util.List;
 
-@Listen
 public class SshScheme extends DownloadScheme {
   private final String sshdAddress;
   private final Provider<CurrentUser> userProvider;