Merge branch 'stable-3.0' * stable-3.0: Bump Bazel version to 2.2.0 Re-add support for projects with anonymous HTTP access Adapt to project cache returning Optional in latest master. Switch to snapshot API so this builds again. Change-Id: I86e5acd26de085a6e82c59d3560d1ad9cc6793b8
diff --git a/.bazelversion b/.bazelversion index 7ec1d6d..ccbccc3 100644 --- a/.bazelversion +++ b/.bazelversion
@@ -1 +1 @@ -2.1.0 +2.2.0
diff --git a/WORKSPACE b/WORKSPACE index 2257fb2..4faf63f 100644 --- a/WORKSPACE +++ b/WORKSPACE
@@ -8,19 +8,19 @@ ) # Snapshot Plugin API -#load( -# "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl", -# "gerrit_api_maven_local", -#) - -# Load snapshot Plugin API -#gerrit_api_maven_local() - -# Release Plugin API load( - "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl", - "gerrit_api", + "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl", + "gerrit_api_maven_local", ) +# Load snapshot Plugin API +gerrit_api_maven_local() + +# Release Plugin API +#load( +# "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl", +# "gerrit_api", +#) + # Load release Plugin API -gerrit_api() +#gerrit_api()
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 697938f..93e4ba2 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/goimport/GoImportFilter.java +++ b/src/main/java/com/ericsson/gerrit/plugins/goimport/GoImportFilter.java
@@ -16,14 +16,20 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; +import com.google.gerrit.entities.BranchNameKey; import com.google.gerrit.entities.Project; +import com.google.gerrit.entities.RefNames; import com.google.gerrit.httpd.AllRequestFilter; import com.google.gerrit.httpd.HtmlDomUtil; +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; @@ -31,6 +37,7 @@ import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Optional; import java.util.regex.Pattern; import javax.servlet.FilterChain; import javax.servlet.ServletException; @@ -74,13 +81,21 @@ + "</html>"; private static final Pattern AUTHENTICATED_REQ = Pattern.compile("^/a/.*"); + 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(); @@ -160,13 +175,25 @@ + (authenticated ? "a/" : "") + projectName + " git " - + webUrl - + "a/" - + projectName; + + getRepoRoot(projectName, authenticated); + } + + private String getRepoRoot(String projectName, boolean authenticated) { + if (allowsAnonymousAccess(projectName) && !authenticated) { + return webUrl + projectName; + } + return webUrl + "a/" + projectName; + } + + private boolean allowsAnonymousAccess(String projectName) { + AnonymousUser anonymous = anonProvider.get(); + BranchNameKey heads = BranchNameKey.create(Project.nameKey(projectName), RefNames.REFS_HEADS); + + return permissions.user(anonymous).ref(heads).testOrFalse(RefPermission.READ); } private boolean projectExists(String projectName) { - ProjectState p = projectCache.get(Project.nameKey(projectName)); + Optional<ProjectState> p = projectCache.get(Project.nameKey(projectName)); return p != null; } }
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 c65fb5e..39f01df 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/goimport/GoImportFilterTest.java +++ b/src/test/java/com/ericsson/gerrit/plugins/goimport/GoImportFilterTest.java
@@ -27,11 +27,13 @@ import com.google.gerrit.entities.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 java.util.Optional; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; @@ -51,6 +53,8 @@ private static final String CONTENT_FORMAT = "%1$s/%3$s git %2$s/%3$s"; private static final String CONTENT = String.format(CONTENT_FORMAT, PROD_FQDN, auth(PROD_URL), PROJECT_NAME); + private static final String ANON_CONTENT = + String.format(CONTENT_FORMAT, PROD_FQDN, PROD_URL, PROJECT_NAME); private static final String AUTH_CONTENT = String.format(CONTENT_FORMAT, auth(PROD_FQDN), auth(PROD_URL), PROJECT_NAME); @@ -59,10 +63,13 @@ return baseUrl + "/a"; } - private static byte[] response200(boolean authenticated) { - return authenticated - ? PAGE_200.replace(CONTENT_PLH, AUTH_CONTENT).getBytes() - : PAGE_200.replace(CONTENT_PLH, CONTENT).getBytes(); + private static byte[] response200(boolean allowAnon, boolean authenticated) { + if (authenticated) { + return PAGE_200.replace(CONTENT_PLH, AUTH_CONTENT).getBytes(); + } else if (allowAnon) { + return PAGE_200.replace(CONTENT_PLH, ANON_CONTENT).getBytes(); + } + return PAGE_200.replace(CONTENT_PLH, CONTENT).getBytes(); } private GoImportFilter unitUnderTest; @@ -81,23 +88,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 @@ -126,33 +141,39 @@ public void testDoFilterWithExistingProject() throws Exception { when(mockRequest.getServletPath()).thenReturn("/" + PROJECT_NAME); when(mockRequest.getParameter("go-get")).thenReturn("1"); - when(mockProjectCache.get(Project.nameKey(PROJECT_NAME))).thenReturn(mockProjectState); + when(mockProjectCache.get(Project.nameKey(PROJECT_NAME))) + .thenReturn(Optional.of(mockProjectState)); + when(mockPermsForRef.testOrFalse(RefPermission.READ)).thenReturn(false); unitUnderTest.doFilter(mockRequest, mockResponse, mockChain); - verify(mockOutputStream, times(1)).write(response200(false)); + verify(mockOutputStream, times(1)).write(response200(false, false)); 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 public void testDoFilterAuthenticatedWithExistingProject() throws Exception { when(mockRequest.getServletPath()).thenReturn("/a/" + PROJECT_NAME); when(mockRequest.getParameter("go-get")).thenReturn("1"); - when(mockProjectCache.get(Project.nameKey(PROJECT_NAME))).thenReturn(mockProjectState); + when(mockProjectCache.get(Project.nameKey(PROJECT_NAME))) + .thenReturn(Optional.of(mockProjectState)); + when(mockPermsForRef.testOrFalse(RefPermission.READ)).thenReturn(false); unitUnderTest.doFilter(mockRequest, mockResponse, mockChain); - verify(mockOutputStream, times(1)).write(response200(true)); + verify(mockOutputStream, times(1)).write(response200(false, true)); 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 public void testDoFilterWithExistingProjectAndPackage() throws Exception { when(mockRequest.getServletPath()).thenReturn("/" + PROJECT_NAME + "/my/package"); when(mockRequest.getParameter("go-get")).thenReturn("1"); - when(mockProjectCache.get(Project.nameKey(PROJECT_NAME))).thenReturn(mockProjectState); + when(mockPermsForRef.testOrFalse(RefPermission.READ)).thenReturn(false); unitUnderTest.doFilter(mockRequest, mockResponse, mockChain); - verify(mockOutputStream, times(1)).write(response200(false)); + verify(mockOutputStream, times(1)).write(response200(false, false)); verify(mockChain, times(0)).doFilter(mockRequest, mockResponse); verify(mockProjectCache, times(3)).get(any(Project.NameKey.class)); verify(mockResponse, times(1)).setStatus(200); @@ -162,13 +183,15 @@ public void testDoFilterWithAnonymousAccessibleProject() throws Exception { when(mockRequest.getServletPath()).thenReturn("/projectName"); when(mockRequest.getParameter("go-get")).thenReturn("1"); - when(mockProjectCache.get(Project.nameKey("projectName"))).thenReturn(mockProjectState); - when(mockProjectCache.get(Project.nameKey("projectName"))).thenReturn(mockProjectState); + when(mockProjectCache.get(Project.nameKey("projectName"))) + .thenReturn(Optional.of(mockProjectState)); + when(mockPermsForRef.testOrFalse(RefPermission.READ)).thenReturn(true); unitUnderTest.doFilter(mockRequest, mockResponse, mockChain); - verify(mockOutputStream, times(1)).write(response200(false)); + verify(mockOutputStream, times(1)).write(response200(true, false)); 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 @@ -189,7 +212,8 @@ when(mockRequest.getServletPath()).thenReturn("/" + PROJECT_NAME); when(mockRequest.getParameter("go-get")).thenReturn("1"); doThrow(new IOException(msg)).when(mockOutputStream).write(any(byte[].class)); - when(mockProjectCache.get(any(Project.NameKey.class))).thenReturn(mockProjectState); + when(mockProjectCache.get(any(Project.NameKey.class))) + .thenReturn(Optional.of(mockProjectState)); IOException thrown = assertThrows( IOException.class, () -> unitUnderTest.doFilter(mockRequest, mockResponse, mockChain));