Merge branch 'stable-2.14'

* stable-2.14:
  Document how to set default UI
  Note on branch-specific labels with custom rules.pl
  GWT UI: Allow to set blocking label range rules
  Extend LFS plugin servlet so that Git LFS 2.0 Lock API is handled
  PolyGerrit: Fix undefined url in gr-dropdown

Change-Id: I01320e404daf1abd052c39321346e2eacff3dd09
This commit is contained in:
David Pursehouse
2017-06-01 16:54:59 +09:00
8 changed files with 145 additions and 69 deletions

View File

@@ -2102,6 +2102,20 @@ By default false.
+
Path prefix for PolyGerrit's static resources if using a CDN.
[[gerrit.ui]]gerrit.ui::
+
Default UI when the user does not request a different preference via argument
or cookie.
+
* `GWT` for the old-style Google Web Toolkit-based interface.
* `POLYGERRIT` for the new Polymer-based HTML5 Web interface.
+
A sanity check during startup is performed that the value of
gerrit.ui is an enabled UI.
+
Defaults to GWT (if GWT is enabled) or POLYGERRIT (if POLYGERRIT is
enabled and GWT is disabled)
[[gitweb]]
=== Section gitweb

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2017 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.extensions.api.lfs;
import com.google.common.base.Joiner;
public final class LfsDefinitions {
public static final String CONTENTTYPE_VND_GIT_LFS_JSON =
"application/vnd.git-lfs+json; charset=utf-8";
public static final String LFS_OBJECTS_PATH = "objects/batch";
public static final String LFS_LOCKS_PATH_REGEX = "locks(?:/(.*)(?:/unlock))?";
public static final String LFS_VERIFICATION_PATH = "locks/verify";
public static final String LFS_UNIFIED_PATHS_REGEX =
Joiner.on('|').join(LFS_OBJECTS_PATH, LFS_LOCKS_PATH_REGEX, LFS_VERIFICATION_PATH);
public static final String LFS_URL_WO_AUTH_REGEX_TEAMPLATE = "(?:/p/|/)(.+)(?:/info/lfs/)(?:%s)$";
public static final String LFS_URL_WO_AUTH_REGEX =
String.format(LFS_URL_WO_AUTH_REGEX_TEAMPLATE, LFS_UNIFIED_PATHS_REGEX);
public static final String LFS_URL_REGEX_TEMPLATE = "^(?:/a)?" + LFS_URL_WO_AUTH_REGEX_TEAMPLATE;
public static final String LFS_URL_REGEX =
String.format(LFS_URL_REGEX_TEMPLATE, LFS_UNIFIED_PATHS_REGEX);
private LfsDefinitions() {}
}

View File

@@ -0,0 +1,82 @@
// Copyright (C) 2017 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.extensions.api.lfs;
import static com.google.common.truth.Truth.assertThat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
public class LfsDefinitionsTest {
private static final String[] URL_PREFIXES = new String[] {"/", "/a/", "/p/", "/a/p/"};
@Test
public void noLfsEndPoint_noMatch() {
Pattern p = Pattern.compile(LfsDefinitions.LFS_URL_REGEX);
doesNotMatch(p, "/foo");
doesNotMatch(p, "/a/foo");
doesNotMatch(p, "/p/foo");
doesNotMatch(p, "/a/p/foo");
doesNotMatch(p, "/info/lfs/objects/batch");
doesNotMatch(p, "/info/lfs/objects/batch/foo");
doesNotMatch(p, "/info/lfs/locks");
doesNotMatch(p, "/info/lfs/locks/verify");
doesNotMatch(p, "/info/lfs/locks/unlock");
doesNotMatch(p, "/info/lfs/locks/lock_id/unlock");
}
@Test
public void matchingLfsEndpoint_projectNameCaptured() {
Pattern p = Pattern.compile(LfsDefinitions.LFS_URL_REGEX);
testProjectGetsMatched(p, "foo/bar/info/lfs/objects/batch", "foo/bar");
testProjectGetsMatched(p, "foo/bar/info/lfs/locks", "foo/bar");
testProjectGetsMatched(p, "foo/bar/info/lfs/locks/verify", "foo/bar");
testProjectAndLockIdGetMatched(
p, "foo/bar/info/lfs/locks/lock_id/unlock", "foo/bar", "lock_id");
}
private void testProjectAndLockIdGetMatched(
Pattern p, String url, String expectedProject, String expectedLockId) {
for (String prefix : URL_PREFIXES) {
matches(p, prefix + url, expectedProject, expectedLockId);
}
}
private void testProjectGetsMatched(Pattern p, String url, String expected) {
for (String prefix : URL_PREFIXES) {
matches(p, prefix + url, expected);
}
}
private void doesNotMatch(Pattern p, String input) {
Matcher m = p.matcher(input);
assertThat(m.matches()).isFalse();
}
private void matches(Pattern p, String input, String expectedProjectName) {
Matcher m = p.matcher(input);
assertThat(m.matches()).isTrue();
assertThat(m.group(1)).isEqualTo(expectedProjectName);
}
private void matches(Pattern p, String input, String expectedProjectName, String expectedLockId) {
Matcher m = p.matcher(input);
assertThat(m.matches()).isTrue();
assertThat(m.group(1)).isEqualTo(expectedProjectName);
assertThat(m.group(2)).isEqualTo(expectedLockId);
}
}

View File

@@ -111,6 +111,12 @@ public class PermissionRuleEditor extends Composite
min = minList;
max = maxList;
action.setAcceptableValues(
Arrays.asList(
PermissionRule.Action.ALLOW,
PermissionRule.Action.DENY,
PermissionRule.Action.BLOCK));
} else {
min = new RangeBox.Box();
max = new RangeBox.Box();
@@ -144,15 +150,13 @@ public class PermissionRuleEditor extends Composite
}
force.setVisible(canForce);
force.setEnabled(!readOnly);
action.getElement().setPropertyBoolean("disabled", readOnly);
if (validRange != null) {
min.setEnabled(!readOnly);
max.setEnabled(!readOnly);
action.getElement().getStyle().setDisplay(Display.NONE);
} else {
rangeEditor.getStyle().setDisplay(Display.NONE);
action.getElement().setPropertyBoolean("disabled", readOnly);
}
if (readOnly) {

View File

@@ -14,7 +14,7 @@
package com.google.gerrit.httpd;
import static com.google.gerrit.httpd.plugins.LfsPluginServlet.LFS_REST;
import static com.google.gerrit.extensions.api.lfs.LfsDefinitions.LFS_URL_WO_AUTH_REGEX;
import com.google.gerrit.extensions.client.GitBasicAuthPolicy;
import com.google.gerrit.reviewdb.client.CoreDownloadSchemes;
@@ -26,7 +26,7 @@ import javax.servlet.Filter;
/** Configures Git access over HTTP with authentication. */
public class GitOverHttpModule extends ServletModule {
private static final String LFS_URL_REGEX = "^(?:(?!/a/))" + LFS_REST;
private static final String NOT_AUTHORIZED_LFS_URL_REGEX = "^(?:(?!/a/))" + LFS_URL_WO_AUTH_REGEX;
private final AuthConfig authConfig;
private final DownloadConfig downloadConfig;
@@ -55,7 +55,7 @@ public class GitOverHttpModule extends ServletModule {
serveRegex(git).with(GitOverHttpServlet.class);
}
filterRegex(LFS_URL_REGEX).through(authFilter);
filterRegex(NOT_AUTHORIZED_LFS_URL_REGEX).through(authFilter);
filter("/a/*").through(authFilter);
}

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.httpd.plugins;
import com.google.gerrit.extensions.api.lfs.LfsDefinitions;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.httpd.resources.Resource;
import com.google.gerrit.httpd.resources.ResourceKey;
@@ -35,7 +36,7 @@ public class HttpPluginModule extends ServletModule {
serveRegex("^/(?:a/)?plugins/(.*)?$").with(HttpPluginServlet.class);
bind(LfsPluginServlet.class);
serveRegex(LfsPluginServlet.URL_REGEX).with(LfsPluginServlet.class);
serveRegex(LfsDefinitions.LFS_URL_REGEX).with(LfsPluginServlet.class);
bind(StartPluginListener.class)
.annotatedWith(UniqueAnnotations.create())

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.httpd.plugins;
import static com.google.gerrit.extensions.api.lfs.LfsDefinitions.CONTENTTYPE_VND_GIT_LFS_JSON;
import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_NOT_IMPLEMENTED;
@@ -52,12 +53,6 @@ public class LfsPluginServlet extends HttpServlet
implements StartPluginListener, ReloadPluginListener {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(LfsPluginServlet.class);
public static final String LFS_REST = "(?:/p/|/)(.+)(?:/info/lfs/objects/batch)$";
public static final String URL_REGEX = "^(?:/a)?" + LFS_REST;
private static final String CONTENTTYPE_VND_GIT_LFS_JSON =
"application/vnd.git-lfs+json; charset=utf-8";
private static final String MESSAGE_LFS_NOT_CONFIGURED =
"{\"message\":\"No LFS plugin is configured to handle LFS requests.\"}";

View File

@@ -1,56 +0,0 @@
// Copyright (C) 2016 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.httpd.plugins;
import static com.google.common.truth.Truth.assertThat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
public class LfsPluginServletTest {
@Test
public void noLfsEndPoint_noMatch() {
Pattern p = Pattern.compile(LfsPluginServlet.URL_REGEX);
doesNotMatch(p, "/foo");
doesNotMatch(p, "/a/foo");
doesNotMatch(p, "/p/foo");
doesNotMatch(p, "/a/p/foo");
doesNotMatch(p, "/info/lfs/objects/batch");
doesNotMatch(p, "/info/lfs/objects/batch/foo");
}
@Test
public void matchingLfsEndpoint_projectNameCaptured() {
Pattern p = Pattern.compile(LfsPluginServlet.URL_REGEX);
matches(p, "/foo/bar/info/lfs/objects/batch", "foo/bar");
matches(p, "/a/foo/bar/info/lfs/objects/batch", "foo/bar");
matches(p, "/p/foo/bar/info/lfs/objects/batch", "foo/bar");
matches(p, "/a/p/foo/bar/info/lfs/objects/batch", "foo/bar");
}
private void doesNotMatch(Pattern p, String input) {
Matcher m = p.matcher(input);
assertThat(m.matches()).isFalse();
}
private void matches(Pattern p, String input, String expectedProjectName) {
Matcher m = p.matcher(input);
assertThat(m.matches()).isTrue();
assertThat(m.group(1)).isEqualTo(expectedProjectName);
}
}