Config download methods
Allow download methods configuration in gerrit.config. It was
included a section [download] in gerrit.config file to set the
scheme to be used in downloads.
This configuration hide or show ssh/http/anonymous git/anonymous
http and repo download tabs in change screen.
Bug: issue 583
Change-Id: I157135c6793771fc7b9e22bef5bae1a7d3b1da35
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 7384a87..4b7aead 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -713,6 +713,52 @@
+
Default is `30 seconds`.
+[[download]]Section download
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+----
+[download]
+ scheme = ssh
+ scheme = http
+ scheme = anon_http
+ scheme = anon_git
+ scheme = repo_download
+----
+
+The download section configures the allowed download methods.
+
+[[download.scheme]]download.scheme::
++
+Schemes that should be used to download changes.
++
+Multiple schemes are supported:
++
+* `http`
++
+HTTP download is allowed.
++
+* `ssh`
++
+SSH download is allowed.
++
+* `anon_http`
++
+Anonymous HTTP download is allowed.
++
+* `anon_git`
++
+Anonymous Git download is allowed.
+This is not default, it is also necessary to fill gerrit.canonicalGitUrl variable.
++
+* `repo_download`
++
+Gerrit advertises patch set downloads with the `repo download` command,
+assuming that all projects managed by this instance are generally worked
+on with the repo multi-repository tool.
+This is not default, as not all instances will deploy repo.
+
++
+If download.scheme is not specified, SSH, HTTP and Anonymous HTTP downloads are allowed.
[[gerrit]]Section gerrit
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1267,17 +1313,6 @@
safe = true
----
-[[repo]]Section repo
-~~~~~~~~~~~~~~~~~~~~
-
-[[repo.showDownloadCommand]]repo.showDownloadCommand::
-+
-If set to true, Gerrit advertises patch set downloads with the
-`repo download` command, assuming that all projects managed by this
-instance are generally worked on with the repo multi-repository tool.
-+
-By default, false, as not all instances will deploy repo.
-
[[repository]]Section repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Repositories in this sense are the same as projects.
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
index c954a6e..2e6be7e 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
@@ -18,6 +18,7 @@
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AuthType;
import com.google.gerrit.reviewdb.Project;
+import com.google.gerrit.reviewdb.AccountGeneralPreferences.DownloadScheme;
import com.google.gwtexpui.safehtml.client.RegexFindReplace;
import java.util.List;
@@ -32,7 +33,7 @@
protected boolean useContactInfo;
protected boolean allowRegisterNewEmail;
protected AuthType authType;
- protected boolean useRepoDownload;
+ protected Set<DownloadScheme> downloadSchemes;
protected String gitDaemonUrl;
protected String sshdAddress;
protected Project.NameKey wildProject;
@@ -71,6 +72,14 @@
authType = t;
}
+ public Set<DownloadScheme> getDownloadSchemes() {
+ return downloadSchemes;
+ }
+
+ public void setDownloadSchemes(final Set<DownloadScheme> s) {
+ downloadSchemes = s;
+ }
+
public GitwebLink getGitwebLink() {
return gitweb;
}
@@ -95,14 +104,6 @@
useContactInfo = r;
}
- public boolean isUseRepoDownload() {
- return useRepoDownload;
- }
-
- public void setUseRepoDownload(final boolean r) {
- useRepoDownload = r;
- }
-
public String getGitDaemonUrl() {
return gitDaemonUrl;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadCommandLink.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadCommandLink.java
index 1260819..53771a97 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadCommandLink.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadCommandLink.java
@@ -62,6 +62,10 @@
}
}
+ public AccountGeneralPreferences.DownloadCommand getCmdType() {
+ return cmdType;
+ }
+
void select() {
DownloadCommandPanel parent = (DownloadCommandPanel) getParent();
for (Widget w : parent) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadCommandPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadCommandPanel.java
index 3ecf527..0affcfb 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadCommandPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadCommandPanel.java
@@ -16,6 +16,7 @@
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
+import com.google.gerrit.reviewdb.AccountGeneralPreferences.DownloadCommand;
import com.google.gwt.user.client.ui.Accessibility;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
@@ -69,6 +70,9 @@
private void update() {
if (currentCommand != null && currentUrl != null) {
currentCommand.setCurrentUrl(currentUrl);
+ } else if (currentCommand != null &&
+ currentCommand.getCmdType().equals(DownloadCommand.REPO_DOWNLOAD)) {
+ currentCommand.setCurrentUrl(null);
}
}
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadUrlLink.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadUrlLink.java
index 6f52ef9..6e72e20 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadUrlLink.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadUrlLink.java
@@ -25,10 +25,10 @@
import com.google.gwtjsonrpc.client.VoidResult;
class DownloadUrlLink extends Anchor implements ClickHandler {
- final AccountGeneralPreferences.DownloadUrl urlType;
+ final AccountGeneralPreferences.DownloadScheme urlType;
final String urlData;
- DownloadUrlLink(AccountGeneralPreferences.DownloadUrl urlType, String text,
+ DownloadUrlLink(AccountGeneralPreferences.DownloadScheme urlType, String text,
String urlData) {
super(text);
this.urlType = urlType;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadUrlPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadUrlPanel.java
index 783963b..f4260e2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadUrlPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DownloadUrlPanel.java
@@ -33,7 +33,7 @@
return getWidgetCount() == 0;
}
- void select(AccountGeneralPreferences.DownloadUrl urlType) {
+ void select(AccountGeneralPreferences.DownloadScheme urlType) {
DownloadUrlLink first = null;
for (Widget w : this) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
index da4b78b..ce0cb6d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
@@ -37,7 +37,7 @@
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.UserIdentity;
import com.google.gerrit.reviewdb.AccountGeneralPreferences.DownloadCommand;
-import com.google.gerrit.reviewdb.AccountGeneralPreferences.DownloadUrl;
+import com.google.gerrit.reviewdb.AccountGeneralPreferences.DownloadScheme;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -175,34 +175,40 @@
final CopyableLabel copyLabel = new CopyableLabel("");
final DownloadCommandPanel commands = new DownloadCommandPanel();
final DownloadUrlPanel urls = new DownloadUrlPanel(commands);
+ final Set<DownloadScheme> allowedSchemes = Gerrit.getConfig().getDownloadSchemes();
copyLabel.setStyleName(Gerrit.RESOURCES.css().downloadLinkCopyLabel());
if (changeDetail.isAllowsAnonymous()
- && Gerrit.getConfig().getGitDaemonUrl() != null) {
+ && Gerrit.getConfig().getGitDaemonUrl() != null
+ && allowedSchemes.contains(DownloadScheme.ANON_GIT)) {
StringBuilder r = new StringBuilder();
r.append(Gerrit.getConfig().getGitDaemonUrl());
r.append(projectName);
r.append(" ");
r.append(patchSet.getRefName());
- urls.add(new DownloadUrlLink(DownloadUrl.ANON_GIT, Util.M
+ urls.add(new DownloadUrlLink(DownloadScheme.ANON_GIT, Util.M
.anonymousDownload("Git"), r.toString()));
}
- if (changeDetail.isAllowsAnonymous()) {
+ if (changeDetail.isAllowsAnonymous()
+ && (allowedSchemes.contains(DownloadScheme.ANON_HTTP) ||
+ allowedSchemes.contains(DownloadScheme.DEFAULT_DOWNLOADS))) {
StringBuilder r = new StringBuilder();
r.append(GWT.getHostPageBaseURL());
r.append("p/");
r.append(projectName);
r.append(" ");
r.append(patchSet.getRefName());
- urls.add(new DownloadUrlLink(DownloadUrl.ANON_HTTP, Util.M
+ urls.add(new DownloadUrlLink(DownloadScheme.ANON_HTTP, Util.M
.anonymousDownload("HTTP"), r.toString()));
}
if (Gerrit.getConfig().getSshdAddress() != null && Gerrit.isSignedIn()
&& Gerrit.getUserAccount().getUserName() != null
- && Gerrit.getUserAccount().getUserName().length() > 0) {
+ && Gerrit.getUserAccount().getUserName().length() > 0
+ && (allowedSchemes.contains(DownloadScheme.SSH) ||
+ allowedSchemes.contains(DownloadScheme.DEFAULT_DOWNLOADS))) {
String sshAddr = Gerrit.getConfig().getSshdAddress();
final StringBuilder r = new StringBuilder();
r.append("ssh://");
@@ -219,11 +225,13 @@
r.append(projectName);
r.append(" ");
r.append(patchSet.getRefName());
- urls.add(new DownloadUrlLink(DownloadUrl.SSH, "SSH", r.toString()));
+ urls.add(new DownloadUrlLink(DownloadScheme.SSH, "SSH", r.toString()));
}
if (Gerrit.isSignedIn() && Gerrit.getUserAccount().getUserName() != null
- && Gerrit.getUserAccount().getUserName().length() > 0) {
+ && Gerrit.getUserAccount().getUserName().length() > 0
+ && (allowedSchemes.contains(DownloadScheme.HTTP) ||
+ allowedSchemes.contains(DownloadScheme.DEFAULT_DOWNLOADS))) {
String base = GWT.getHostPageBaseURL();
int p = base.indexOf("://");
int s = base.indexOf('/', p + 3);
@@ -245,10 +253,10 @@
r.append(projectName);
r.append(" ");
r.append(patchSet.getRefName());
- urls.add(new DownloadUrlLink(DownloadUrl.HTTP, "HTTP", r.toString()));
+ urls.add(new DownloadUrlLink(DownloadScheme.HTTP, "HTTP", r.toString()));
}
- if (Gerrit.getConfig().isUseRepoDownload()) {
+ if (allowedSchemes.contains(DownloadScheme.REPO_DOWNLOAD)) {
// This site prefers usage of the 'repo' tool, so suggest
// that for easy fetch.
//
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
index e075ed8..e51731d 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
@@ -21,6 +21,7 @@
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.server.account.Realm;
import com.google.gerrit.server.config.AuthConfig;
+import com.google.gerrit.server.config.DownloadSchemeConfig;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.WildProjectName;
import com.google.gerrit.server.contact.ContactStore;
@@ -47,6 +48,7 @@
private final Realm realm;
private final Config cfg;
private final AuthConfig authConfig;
+ private final DownloadSchemeConfig schemeConfig;
private final GitWebConfig gitWebConfig;
private final Project.NameKey wildProject;
private final SshInfo sshInfo;
@@ -60,10 +62,12 @@
GerritConfigProvider(final Realm r, @GerritServerConfig final Config gsc,
final AuthConfig ac, final GitWebConfig gwc,
@WildProjectName final Project.NameKey wp, final SshInfo si,
- final ApprovalTypes at, final ContactStore cs, final ServletContext sc) {
+ final ApprovalTypes at, final ContactStore cs, final ServletContext sc,
+ final DownloadSchemeConfig dc) {
realm = r;
cfg = gsc;
authConfig = ac;
+ schemeConfig = dc;
gitWebConfig = gwc;
sshInfo = si;
wildProject = wp;
@@ -92,9 +96,8 @@
config.setUseContributorAgreements(cfg.getBoolean("auth",
"contributoragreements", false));
config.setGitDaemonUrl(cfg.getString("gerrit", null, "canonicalgiturl"));
- config.setUseRepoDownload(cfg.getBoolean("repo", null,
- "showdownloadcommand", false));
config.setUseContactInfo(contactStore != null && contactStore.isEnabled());
+ config.setDownloadSchemes(schemeConfig.getDownloadScheme());
config.setAuthType(authConfig.getAuthType());
config.setWildProject(wildProject);
config.setApprovalTypes(approvalTypes);
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/AccountGeneralPreferences.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/AccountGeneralPreferences.java
index 9b607b0..c69e785 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/AccountGeneralPreferences.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/AccountGeneralPreferences.java
@@ -25,9 +25,9 @@
/** Valid choices for the page size. */
public static final short[] PAGESIZE_CHOICES = {10, 25, 50, 100};
- /** Preferred URL type to download a change. */
- public static enum DownloadUrl {
- ANON_GIT, ANON_HTTP, ANON_SSH, HTTP, SSH;
+ /** Preferred scheme type to download a change. */
+ public static enum DownloadScheme {
+ ANON_GIT, ANON_HTTP, ANON_SSH, HTTP, SSH, REPO_DOWNLOAD, DEFAULT_DOWNLOADS;
}
/** Preferred method to download a change. */
@@ -86,14 +86,14 @@
useFlashClipboard = b;
}
- public DownloadUrl getDownloadUrl() {
+ public DownloadScheme getDownloadUrl() {
if (downloadUrl == null) {
return null;
}
- return DownloadUrl.valueOf(downloadUrl);
+ return DownloadScheme.valueOf(downloadUrl);
}
- public void setDownloadUrl(DownloadUrl url) {
+ public void setDownloadUrl(DownloadScheme url) {
if (url != null) {
downloadUrl = url.name();
} else {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/ConfigUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/ConfigUtil.java
index f889a2b..73320ad 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/ConfigUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/ConfigUtil.java
@@ -26,7 +26,9 @@
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -43,13 +45,17 @@
* Must not be null as the enumeration values are derived from this.
* @return the selected enumeration value, or {@code defaultValue}.
*/
- @SuppressWarnings("unchecked")
public static <T extends Enum<?>> T getEnum(final Config config,
final String section, final String subsection, final String setting,
final T defaultValue) {
- final T[] all;
+ final T[] all = allValuesOf(defaultValue);
+ return getEnum(config, section, subsection, setting, all, defaultValue);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> T[] allValuesOf(final T defaultValue) {
try {
- all = (T[]) defaultValue.getClass().getMethod("values").invoke(null);
+ return (T[]) defaultValue.getClass().getMethod("values").invoke(null);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Cannot obtain enumeration values", e);
} catch (SecurityException e) {
@@ -61,7 +67,6 @@
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Cannot obtain enumeration values", e);
}
- return getEnum(config, section, subsection, setting, all, defaultValue);
}
/**
@@ -86,6 +91,25 @@
return defaultValue;
}
+ return getEnum(section, subsection, setting, valueString, all);
+ }
+
+ /**
+ * Parse a Java enumeration from the configuration.
+ *
+ * @param <T> type of the enumeration object.
+ * @param section section the key is in.
+ * @param subsection subsection the key is in, or null if not in a subsection.
+ * @param setting name of the setting to read.
+ * @param valueString string value from git Config
+ * @param all all possible values in the enumeration which should be
+ * recognized. This should be {@code EnumType.values()}.
+ * @return the selected enumeration value, or {@code defaultValue}.
+ */
+ private static <T extends Enum<?>> T getEnum(final String section,
+ final String subsection, final String setting, String valueString,
+ final T[] all) {
+
String n = valueString.replace(' ', '_');
for (final T e : all) {
if (equalsIgnoreCase(e.name(), n)) {
@@ -109,10 +133,62 @@
r.append(e.name());
r.append(" ");
}
+
throw new IllegalArgumentException(r.toString().trim());
}
/**
+ * Parse a Java enumeration list from the configuration.
+ *
+ * @param <T> type of the enumeration object.
+ * @param config the configuration file to read.
+ * @param section section the key is in.
+ * @param subsection subsection the key is in, or null if not in a subsection.
+ * @param setting name of the setting to read.
+ * @param defaultValue default value to return if the setting was not set.
+ * Must not be null as the enumeration values are derived from this.
+ * @return the selected enumeration values list, or {@code defaultValue}.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T extends Enum<?>> List<T> getEnumList(final Config config,
+ final String section, final String subsection, final String setting,
+ final T defaultValue) {
+ final T[] all = allValuesOf(defaultValue);
+ return getEnumList(config, section, subsection, setting, all, defaultValue);
+ }
+
+ /**
+ * Parse a Java enumeration list from the configuration.
+ *
+ * @param <T> type of the enumeration object.
+ * @param config the configuration file to read.
+ * @param section section the key is in.
+ * @param subsection subsection the key is in, or null if not in a subsection.
+ * @param setting name of the setting to read.
+ * @param all all possible values in the enumeration which should be
+ * recognized. This should be {@code EnumType.values()}.
+ * @param defaultValue default value to return if the setting was not set.
+ * This value may be null.
+ * @return the selected enumeration values list, or {@code defaultValue}.
+ */
+ public static <T extends Enum<?>> List<T> getEnumList(final Config config,
+ final String section, final String subsection, final String setting,
+ final T[] all, final T defaultValue) {
+ final List<T> list = new ArrayList<T>();
+ final String[] values = config.getStringList(section, subsection, setting);
+ if (values.length == 0) {
+ list.add(defaultValue);
+ } else {
+ for (String string : values) {
+ if (string != null) {
+ list.add(getEnum(section, subsection, setting, string, all));
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
* Parse a numerical time unit, such as "1 minute", from the configuration.
*
* @param config the configuration file to read.
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/DownloadSchemeConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/DownloadSchemeConfig.java
new file mode 100644
index 0000000..6f67032
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/DownloadSchemeConfig.java
@@ -0,0 +1,49 @@
+// Copyright (C) 2010 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.google.gerrit.server.config;
+
+import com.google.gerrit.reviewdb.SystemConfig;
+import com.google.gerrit.reviewdb.AccountGeneralPreferences.DownloadScheme;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import org.eclipse.jgit.lib.Config;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/** Download protocol from {@code gerrit.config}. */
+@Singleton
+public class DownloadSchemeConfig {
+ private final Set<DownloadScheme> downloadSchemes;
+
+ @Inject
+ DownloadSchemeConfig(@GerritServerConfig final Config cfg,
+ final SystemConfig s) {
+ List<DownloadScheme> all =
+ ConfigUtil.getEnumList(cfg, "download", null, "scheme",
+ DownloadScheme.DEFAULT_DOWNLOADS);
+
+ downloadSchemes =
+ Collections.unmodifiableSet(new HashSet<DownloadScheme>(all));
+ }
+
+ /** Scheme used to download. */
+ public Set<DownloadScheme> getDownloadScheme() {
+ return downloadSchemes;
+ }
+}