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
This commit is contained in:
monica.dionisio 2010-06-29 15:42:57 -03:00 committed by Shawn O. Pearce
parent f76fb4f82c
commit 3f63044c4e
11 changed files with 226 additions and 46 deletions

View File

@ -713,6 +713,52 @@ If a unit suffix is not specified, `milliseconds` is assumed.
+
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 @@ Common examples:
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.

View File

@ -18,6 +18,7 @@ import com.google.gerrit.common.auth.openid.OpenIdProviderPattern;
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 @@ public class GerritConfig implements Cloneable {
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 @@ public class GerritConfig implements Cloneable {
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 @@ public class GerritConfig implements Cloneable {
useContactInfo = r;
}
public boolean isUseRepoDownload() {
return useRepoDownload;
}
public void setUseRepoDownload(final boolean r) {
useRepoDownload = r;
}
public String getGitDaemonUrl() {
return gitDaemonUrl;
}

View File

@ -62,6 +62,10 @@ abstract class DownloadCommandLink extends Anchor implements ClickHandler {
}
}
public AccountGeneralPreferences.DownloadCommand getCmdType() {
return cmdType;
}
void select() {
DownloadCommandPanel parent = (DownloadCommandPanel) getParent();
for (Widget w : parent) {

View File

@ -16,6 +16,7 @@ package com.google.gerrit.client.changes;
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 @@ class DownloadCommandPanel extends FlowPanel {
private void update() {
if (currentCommand != null && currentUrl != null) {
currentCommand.setCurrentUrl(currentUrl);
} else if (currentCommand != null &&
currentCommand.getCmdType().equals(DownloadCommand.REPO_DOWNLOAD)) {
currentCommand.setCurrentUrl(null);
}
}
}

View File

@ -25,10 +25,10 @@ import com.google.gwt.user.client.ui.Widget;
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;

View File

@ -33,7 +33,7 @@ class DownloadUrlPanel extends FlowPanel {
return getWidgetCount() == 0;
}
void select(AccountGeneralPreferences.DownloadUrl urlType) {
void select(AccountGeneralPreferences.DownloadScheme urlType) {
DownloadUrlLink first = null;
for (Widget w : this) {

View File

@ -37,7 +37,7 @@ import com.google.gerrit.reviewdb.PatchSetInfo;
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 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel implements O
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 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel implements O
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 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel implements O
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.
//

View File

@ -21,6 +21,7 @@ import com.google.gerrit.reviewdb.Account;
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 @@ class GerritConfigProvider implements Provider<GerritConfig> {
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 @@ class GerritConfigProvider implements Provider<GerritConfig> {
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 @@ class GerritConfigProvider implements Provider<GerritConfig> {
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);

View File

@ -25,9 +25,9 @@ public final class AccountGeneralPreferences {
/** 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 @@ public final class AccountGeneralPreferences {
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 {

View File

@ -26,7 +26,9 @@ import org.slf4j.Logger;
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 @@ public class ConfigUtil {
* 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 @@ public class ConfigUtil {
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Cannot obtain enumeration values", e);
}
return getEnum(config, section, subsection, setting, all, defaultValue);
}
/**
@ -86,6 +91,25 @@ public class ConfigUtil {
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,9 +133,61 @@ public class ConfigUtil {
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.
*

View File

@ -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;
}
}