Merge changes I76de47b0,I4fa85dd1

* changes:
  ListAccess: Fail for non-visible projects
  ListAccess: Filter out empty project names
diff --git a/java/com/google/gerrit/server/restapi/access/ListAccess.java b/java/com/google/gerrit/server/restapi/access/ListAccess.java
index 1e1bade..dca969d 100644
--- a/java/com/google/gerrit/server/restapi/access/ListAccess.java
+++ b/java/com/google/gerrit/server/restapi/access/ListAccess.java
@@ -14,11 +14,17 @@
 
 package com.google.gerrit.server.restapi.access;
 
+import com.google.common.base.Strings;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.access.ProjectAccessInfo;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.ProjectPermission;
+import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.restapi.project.GetAccess;
 import com.google.inject.Inject;
 import java.util.ArrayList;
@@ -41,10 +47,15 @@
       usage = "projects for which the access rights should be returned")
   private List<String> projects = new ArrayList<>();
 
+  private final PermissionBackend permissionBackend;
+  private final ProjectCache projectCache;
   private final GetAccess getAccess;
 
   @Inject
-  public ListAccess(GetAccess getAccess) {
+  public ListAccess(
+      PermissionBackend permissionBackend, ProjectCache projectCache, GetAccess getAccess) {
+    this.permissionBackend = permissionBackend;
+    this.projectCache = projectCache;
     this.getAccess = getAccess;
   }
 
@@ -53,7 +64,23 @@
       throws Exception {
     Map<String, ProjectAccessInfo> access = new TreeMap<>();
     for (String p : projects) {
-      access.put(p, getAccess.apply(Project.nameKey(p)));
+      if (Strings.nullToEmpty(p).isEmpty()) {
+        continue;
+      }
+
+      Project.NameKey projectName = Project.nameKey(p);
+
+      if (!projectCache.get(projectName).isPresent()) {
+        throw new ResourceNotFoundException(projectName.get());
+      }
+
+      try {
+        permissionBackend.currentUser().project(projectName).check(ProjectPermission.ACCESS);
+      } catch (AuthException e) {
+        throw new ResourceNotFoundException(projectName.get(), e);
+      }
+
+      access.put(p, getAccess.apply(projectName));
     }
     return Response.ok(access);
   }
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/AccessIT.java b/javatests/com/google/gerrit/acceptance/rest/project/AccessIT.java
index a67a3e3..b99c624 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/AccessIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/AccessIT.java
@@ -15,15 +15,21 @@
 package com.google.gerrit.acceptance.rest.project;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
 
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.entities.Permission;
 import com.google.gerrit.extensions.api.access.ProjectAccessInfo;
 import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
 import java.util.Map;
 import org.junit.Test;
 
 public class AccessIT extends AbstractDaemonTest {
+  @Inject private ProjectOperations projectOperations;
 
   @Test
   public void listAccessWithoutSpecifyingProject() throws Exception {
@@ -38,8 +44,11 @@
   @Test
   public void listAccessWithoutSpecifyingAnEmptyProjectName() throws Exception {
     RestResponse r = adminRestSession.get("/access/?p=");
-    r.assertNotFound();
-    assertThat(r.getEntityContent()).isEqualTo("Not Found");
+    r.assertOK();
+    Map<String, ProjectAccessInfo> infoByProject =
+        newGson()
+            .fromJson(r.getReader(), new TypeToken<Map<String, ProjectAccessInfo>>() {}.getType());
+    assertThat(infoByProject).isEmpty();
   }
 
   @Test
@@ -50,6 +59,19 @@
   }
 
   @Test
+  public void listAccessForNonVisibleProject() throws Exception {
+    projectOperations
+        .project(project)
+        .forUpdate()
+        .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+        .update();
+
+    RestResponse r = userRestSession.get("/access/?project=" + project.get());
+    r.assertNotFound();
+    assertThat(r.getEntityContent()).isEqualTo(project.get());
+  }
+
+  @Test
   public void listAccess() throws Exception {
     RestResponse r = adminRestSession.get("/access/?project=" + project.get());
     r.assertOK();