Merge branch 'stable-2.16' into stable-3.0
* stable-2.16:
Replace bazel-genfiles with bazel-bin in documentation
Change-Id: Id95d7189d936d008825fe08be875747e9eeafa8e
diff --git a/BUILD b/BUILD
index a0e371e..afc2580 100644
--- a/BUILD
+++ b/BUILD
@@ -36,6 +36,5 @@
visibility = ["//visibility:public"],
exports = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
":go-import__plugin",
- "@mockito//jar",
],
)
diff --git a/WORKSPACE b/WORKSPACE
index 7f1f8ce..fcce572 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
load("//:bazlets.bzl", "load_bazlets")
load_bazlets(
- commit = "ec989bb514e39447764057c60d3f9959bff8e153",
+ commit = "29ba75f790c68ae2c233a67f7ce1e58e04201ce2",
#local_path = "/home/<user>/projects/bazlets",
)
@@ -24,7 +24,3 @@
# Load release Plugin API
gerrit_api()
-
-load("//:external_plugin_deps.bzl", "external_plugin_deps")
-
-external_plugin_deps()
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
deleted file mode 100644
index c1932a9..0000000
--- a/external_plugin_deps.bzl
+++ /dev/null
@@ -1,33 +0,0 @@
-load("//tools/bzl:maven_jar.bzl", "maven_jar")
-
-def external_plugin_deps():
- maven_jar(
- name = "mockito",
- artifact = "org.mockito:mockito-core:2.28.2",
- sha1 = "91110215a8cb9b77a46e045ee758f77d79167cc0",
- deps = [
- "@byte-buddy//jar",
- "@byte-buddy-agent//jar",
- "@objenesis//jar",
- ],
- )
-
- BYTE_BUDDY_VERSION = "1.9.10"
-
- maven_jar(
- name = "byte-buddy",
- artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION,
- sha1 = "211a2b4d3df1eeef2a6cacf78d74a1f725e7a840",
- )
-
- maven_jar(
- name = "byte-buddy-agent",
- artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION,
- sha1 = "9674aba5ee793e54b864952b001166848da0f26b",
- )
-
- maven_jar(
- name = "objenesis",
- artifact = "org.objenesis:objenesis:2.6",
- sha1 = "639033469776fd37c08358c6b92a4761feb2af4b",
- )
diff --git a/src/main/java/com/ericsson/gerrit/plugins/goimport/GoImportFilter.java b/src/main/java/com/ericsson/gerrit/plugins/goimport/GoImportFilter.java
index d297b26..3675d92 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/goimport/GoImportFilter.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/goimport/GoImportFilter.java
@@ -17,12 +17,18 @@
import com.google.common.base.Strings;
import com.google.gerrit.httpd.AllRequestFilter;
import com.google.gerrit.httpd.HtmlDomUtil;
+import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.util.http.CacheHeaders;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.io.OutputStream;
@@ -67,13 +73,21 @@
+ "</body>\n"
+ "</html>";
+ private final Provider<AnonymousUser> anonProvider;
+ private final PermissionBackend permissions;
private final ProjectCache projectCache;
final String webUrl;
final String projectPrefix;
@Inject
- GoImportFilter(ProjectCache projectCache, @CanonicalWebUrl String webUrl)
+ GoImportFilter(
+ Provider<AnonymousUser> anonProvider,
+ PermissionBackend permissions,
+ ProjectCache projectCache,
+ @CanonicalWebUrl String webUrl)
throws URISyntaxException {
+ this.anonProvider = anonProvider;
+ this.permissions = permissions;
this.projectCache = projectCache;
this.webUrl = webUrl.replaceFirst("/?$", "/");
this.projectPrefix = generateProjectPrefix();
@@ -146,7 +160,23 @@
}
private CharSequence getContent(String projectName) {
- return projectPrefix + projectName + " git " + webUrl + "a/" + projectName;
+ return projectPrefix + projectName + " git " + getRepoRoot(projectName);
+ }
+
+ private String getRepoRoot(String projectName) {
+ if (allowsAnonymousAccess(projectName)) {
+ return webUrl + projectName;
+ }
+
+ return webUrl + "a/" + projectName;
+ }
+
+ private boolean allowsAnonymousAccess(String projectName) {
+ AnonymousUser anonymous = anonProvider.get();
+ Branch.NameKey heads =
+ new Branch.NameKey(new Project.NameKey(projectName), RefNames.REFS_HEADS);
+
+ return permissions.user(anonymous).ref(heads).testOrFalse(RefPermission.READ);
}
private boolean projectExists(String projectName) {
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index d2b86eb..35cfe61 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -47,3 +47,9 @@
| `/bob/my-project/package1` | `bob/my-project` |
| `/bob/my-project/package1/folder2` | `bob/my-project` |
+### Access (Anonymous vs. Authenticated URLs)
+The exact git clone URL served to the client go command will depend on the
+project's configured ACLs. If the project is configured to allow anonymous
+read access to `refs/heads/*`, an anonymous URL will be served (e.g.
+`https://gerrit.example/bob/my-project`). Otherwise, a URL that requires
+authentication will be used (e.g. `https://gerrit.example/a/bob/my-project`).
diff --git a/src/test/java/com/ericsson/gerrit/plugins/goimport/GoImportFilterTest.java b/src/test/java/com/ericsson/gerrit/plugins/goimport/GoImportFilterTest.java
index d00e03e..3b24f18 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/goimport/GoImportFilterTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/goimport/GoImportFilterTest.java
@@ -23,8 +23,12 @@
import static org.mockito.Mockito.when;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.AnonymousUser;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
+import com.google.inject.Provider;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.servlet.FilterChain;
@@ -42,13 +46,17 @@
public class GoImportFilterTest {
private static final String PROD_URL = "https://gerrit-review.googlesource.com";
+ private static final String PROJECT_URL_AUTH =
+ "https://gerrit-review.googlesource.com/a/projectName";
+ private static final String PROJECT_URL_ANON =
+ "https://gerrit-review.googlesource.com/projectName";
private static final String PAGE_200 =
"<!DOCTYPE html>\n"
+ "<html>\n"
+ "<head>\n"
+ " <title>Gerrit-Go-Import</title>\n"
+ " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n"
- + " <meta name=\"go-import\" content=\"gerrit-review.googlesource.com/projectName git https://gerrit-review.googlesource.com/a/projectName\"/>\n"
+ + " <meta name=\"go-import\" content=\"gerrit-review.googlesource.com/projectName git ${content}\"/>\n"
+ "</head>\n"
+ "<body>\n"
+ "<div>\n"
@@ -56,9 +64,16 @@
+ "</div>\n"
+ "</body>\n"
+ "</html>";
+ private static final String PAGE_200_AUTH = PAGE_200.replace("${content}", PROJECT_URL_AUTH);
+ private static final String PAGE_200_ANON = PAGE_200.replace("${content}", PROJECT_URL_ANON);
private GoImportFilter unitUnderTest;
+ @Mock private Provider<AnonymousUser> mockAnonProvider;
+ @Mock private AnonymousUser mockAnon;
+ @Mock private PermissionBackend mockPerms;
+ @Mock private PermissionBackend.WithUser mockPermsWithUser;
+ @Mock private PermissionBackend.ForRef mockPermsForRef;
@Mock private ProjectCache mockProjectCache;
@Mock private HttpServletRequest mockRequest;
@Mock private HttpServletResponse mockResponse;
@@ -68,23 +83,31 @@
@Before
public void setUp() throws Exception {
- unitUnderTest = new GoImportFilter(mockProjectCache, PROD_URL);
+ unitUnderTest = new GoImportFilter(mockAnonProvider, mockPerms, mockProjectCache, PROD_URL);
assertThat(unitUnderTest).isNotNull();
when(mockResponse.getOutputStream()).thenReturn(mockOutputStream);
+
+ when(mockAnonProvider.get()).thenReturn(mockAnon);
+ when(mockPerms.user(mockAnon)).thenReturn(mockPermsWithUser);
+ when(mockPermsWithUser.ref(any())).thenReturn(mockPermsForRef);
}
@Test
public void testConstructor() throws Exception {
assertThat(unitUnderTest.webUrl.endsWith("/")).isTrue();
unitUnderTest =
- new GoImportFilter(mockProjectCache, "http://gerrit-review.googlesource.com:8080/");
+ new GoImportFilter(
+ mockAnonProvider,
+ mockPerms,
+ mockProjectCache,
+ "http://gerrit-review.googlesource.com:8080/");
assertThat(unitUnderTest.webUrl.endsWith("/")).isTrue();
assertThat(unitUnderTest.projectPrefix).isNotNull();
}
@Test(expected = URISyntaxException.class)
public void testConstructorWithURISyntaxException() throws Exception {
- unitUnderTest = new GoImportFilter(mockProjectCache, "\\\\");
+ unitUnderTest = new GoImportFilter(mockAnonProvider, mockPerms, mockProjectCache, "\\\\");
}
@Test
@@ -116,11 +139,13 @@
when(mockRequest.getServletPath()).thenReturn("/projectName");
when(mockRequest.getParameter("go-get")).thenReturn("1");
when(mockProjectCache.get(new Project.NameKey("projectName"))).thenReturn(mockProjectState);
+ when(mockPermsForRef.testOrFalse(RefPermission.READ)).thenReturn(false);
unitUnderTest.doFilter(mockRequest, mockResponse, mockChain);
- verify(mockOutputStream, times(1)).write(PAGE_200.getBytes());
+ verify(mockOutputStream, times(1)).write(PAGE_200_AUTH.getBytes());
verify(mockChain, times(0)).doFilter(mockRequest, mockResponse);
verify(mockProjectCache, times(1)).get(any(Project.NameKey.class));
verify(mockResponse, times(1)).setStatus(200);
+ verify(mockPermsForRef, times(1)).testOrFalse(RefPermission.READ);
}
@Test
@@ -128,11 +153,27 @@
when(mockRequest.getServletPath()).thenReturn("/projectName/my/package");
when(mockRequest.getParameter("go-get")).thenReturn("1");
when(mockProjectCache.get(new Project.NameKey("projectName"))).thenReturn(mockProjectState);
+ when(mockPermsForRef.testOrFalse(RefPermission.READ)).thenReturn(false);
unitUnderTest.doFilter(mockRequest, mockResponse, mockChain);
- verify(mockOutputStream, times(1)).write(PAGE_200.getBytes());
+ verify(mockOutputStream, times(1)).write(PAGE_200_AUTH.getBytes());
verify(mockChain, times(0)).doFilter(mockRequest, mockResponse);
verify(mockProjectCache, times(3)).get(any(Project.NameKey.class));
verify(mockResponse, times(1)).setStatus(200);
+ verify(mockPermsForRef, times(1)).testOrFalse(RefPermission.READ);
+ }
+
+ @Test
+ public void testDoFilterWithAnonymousAccessibleProject() throws Exception {
+ when(mockRequest.getServletPath()).thenReturn("/projectName");
+ when(mockRequest.getParameter("go-get")).thenReturn("1");
+ when(mockProjectCache.get(new Project.NameKey("projectName"))).thenReturn(mockProjectState);
+ when(mockPermsForRef.testOrFalse(RefPermission.READ)).thenReturn(true);
+ unitUnderTest.doFilter(mockRequest, mockResponse, mockChain);
+ verify(mockOutputStream, times(1)).write(PAGE_200_ANON.getBytes());
+ verify(mockChain, times(0)).doFilter(mockRequest, mockResponse);
+ verify(mockProjectCache, times(1)).get(any(Project.NameKey.class));
+ verify(mockResponse, times(1)).setStatus(200);
+ verify(mockPermsForRef, times(1)).testOrFalse(RefPermission.READ);
}
@Test
diff --git a/src/test/java/com/ericsson/gerrit/plugins/goimport/HttpModuleTest.java b/src/test/java/com/ericsson/gerrit/plugins/goimport/HttpModuleTest.java
index 547c159..a0a107d 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/goimport/HttpModuleTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/goimport/HttpModuleTest.java
@@ -16,7 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
+import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
+import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
@@ -32,6 +34,8 @@
public class HttpModuleTest {
private HttpModule unitUnderTest;
+ @Mock private AnonymousUser mockAnon;
+ @Mock private PermissionBackend mockPerms;
@Mock private ProjectCache mockProjectCache;
@Before
@@ -53,6 +57,8 @@
public class TestModule extends AbstractModule {
@Override
protected void configure() {
+ bind(AnonymousUser.class).toInstance(mockAnon);
+ bind(PermissionBackend.class).toInstance(mockPerms);
bind(ProjectCache.class).toInstance(mockProjectCache);
}