Merge changes from topic "remove-project-ctl-isHidden"
* changes: ProjectControl: remove "isHidden" when checking "READ" permission UploadArchive: check ProjectState readable before checking "READ" permission ListProjects: check ProjectState readable before checking "READ" permission ProjectIsVisibleToPredicate: check ProjectState readable before checking "READ" permission DefaultRefFilter: check ProjectState readable before checking "READ" permission AsyncReceiveCommits: check ProjectState readable before checking "READ" permission GitWebServlet: check ProjectState readable before checking "READ" permission
This commit is contained in:
		@@ -36,6 +36,7 @@ import com.google.common.base.CharMatcher;
 | 
			
		||||
import com.google.common.base.Splitter;
 | 
			
		||||
import com.google.gerrit.common.PageLinks;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.AuthException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.Url;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Project;
 | 
			
		||||
import com.google.gerrit.server.AnonymousUser;
 | 
			
		||||
@@ -51,6 +52,7 @@ import com.google.gerrit.server.permissions.PermissionBackend;
 | 
			
		||||
import com.google.gerrit.server.permissions.PermissionBackendException;
 | 
			
		||||
import com.google.gerrit.server.permissions.ProjectPermission;
 | 
			
		||||
import com.google.gerrit.server.project.ProjectCache;
 | 
			
		||||
import com.google.gerrit.server.project.ProjectState;
 | 
			
		||||
import com.google.gerrit.server.ssh.SshInfo;
 | 
			
		||||
import com.google.gwtexpui.server.CacheHeaders;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
@@ -412,33 +414,45 @@ class GitwebServlet extends HttpServlet {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Project.NameKey nameKey = new Project.NameKey(name);
 | 
			
		||||
    ProjectState projectState;
 | 
			
		||||
    try {
 | 
			
		||||
      if (projectCache.checkedGet(nameKey) == null) {
 | 
			
		||||
        notFound(req, rsp);
 | 
			
		||||
      projectState = projectCache.checkedGet(nameKey);
 | 
			
		||||
      if (projectState == null) {
 | 
			
		||||
        sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_NOT_FOUND);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      projectState.checkStatePermitsRead();
 | 
			
		||||
      permissionBackend.user(userProvider).project(nameKey).check(ProjectPermission.READ);
 | 
			
		||||
    } catch (AuthException e) {
 | 
			
		||||
      notFound(req, rsp);
 | 
			
		||||
      sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_NOT_FOUND);
 | 
			
		||||
      return;
 | 
			
		||||
    } catch (IOException | PermissionBackendException err) {
 | 
			
		||||
      log.error("cannot load " + name, err);
 | 
			
		||||
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
 | 
			
		||||
      return;
 | 
			
		||||
    } catch (ResourceConflictException e) {
 | 
			
		||||
      sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_CONFLICT);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try (Repository repo = repoManager.openRepository(nameKey)) {
 | 
			
		||||
      CacheHeaders.setNotCacheable(rsp);
 | 
			
		||||
      exec(req, rsp, nameKey);
 | 
			
		||||
      exec(req, rsp, projectState);
 | 
			
		||||
    } catch (RepositoryNotFoundException e) {
 | 
			
		||||
      getServletContext().log("Cannot open repository", e);
 | 
			
		||||
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void notFound(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
 | 
			
		||||
  /**
 | 
			
		||||
   * Sends error response if the user is authenticated. Or redirect the user to the login page. By
 | 
			
		||||
   * doing this, anonymous users cannot infer the existence of a resource from the status code.
 | 
			
		||||
   */
 | 
			
		||||
  private void sendErrorOrRedirect(HttpServletRequest req, HttpServletResponse rsp, int statusCode)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
    if (userProvider.get().isIdentifiedUser()) {
 | 
			
		||||
      rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
 | 
			
		||||
      rsp.sendError(statusCode);
 | 
			
		||||
    } else {
 | 
			
		||||
      rsp.sendRedirect(getLoginRedirectUrl(req));
 | 
			
		||||
    }
 | 
			
		||||
@@ -475,13 +489,13 @@ class GitwebServlet extends HttpServlet {
 | 
			
		||||
    return params;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void exec(HttpServletRequest req, HttpServletResponse rsp, Project.NameKey project)
 | 
			
		||||
  private void exec(HttpServletRequest req, HttpServletResponse rsp, ProjectState projectState)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
    final Process proc =
 | 
			
		||||
        Runtime.getRuntime()
 | 
			
		||||
            .exec(
 | 
			
		||||
                new String[] {gitwebCgi.toAbsolutePath().toString()},
 | 
			
		||||
                makeEnv(req, project),
 | 
			
		||||
                makeEnv(req, projectState),
 | 
			
		||||
                gitwebCgi.toAbsolutePath().getParent().toFile());
 | 
			
		||||
 | 
			
		||||
    copyStderrToLog(proc.getErrorStream());
 | 
			
		||||
@@ -524,7 +538,7 @@ class GitwebServlet extends HttpServlet {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private String[] makeEnv(HttpServletRequest req, Project.NameKey nameKey) {
 | 
			
		||||
  private String[] makeEnv(HttpServletRequest req, ProjectState projectState) {
 | 
			
		||||
    final EnvList env = new EnvList(_env);
 | 
			
		||||
    final int contentLength = Math.max(0, req.getContentLength());
 | 
			
		||||
 | 
			
		||||
@@ -562,15 +576,17 @@ class GitwebServlet extends HttpServlet {
 | 
			
		||||
      env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Project.NameKey nameKey = projectState.getNameKey();
 | 
			
		||||
    env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/");
 | 
			
		||||
    env.set("GERRIT_PROJECT_NAME", nameKey.get());
 | 
			
		||||
 | 
			
		||||
    env.set("GITWEB_PROJECTROOT", repoManager.getBasePath(nameKey).toAbsolutePath().toString());
 | 
			
		||||
 | 
			
		||||
    if (permissionBackend
 | 
			
		||||
        .user(anonymousUserProvider)
 | 
			
		||||
        .project(nameKey)
 | 
			
		||||
        .testOrFalse(ProjectPermission.READ)) {
 | 
			
		||||
    if (projectState.statePermitsRead()
 | 
			
		||||
        && permissionBackend
 | 
			
		||||
            .user(anonymousUserProvider)
 | 
			
		||||
            .project(nameKey)
 | 
			
		||||
            .testOrFalse(ProjectPermission.READ)) {
 | 
			
		||||
      env.set("GERRIT_ANONYMOUS_READ", "1");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ import com.google.common.collect.SetMultimap;
 | 
			
		||||
import com.google.gerrit.common.Nullable;
 | 
			
		||||
import com.google.gerrit.common.data.Capable;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.AuthException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Account;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Project;
 | 
			
		||||
import com.google.gerrit.server.IdentifiedUser;
 | 
			
		||||
@@ -228,8 +229,9 @@ public class AsyncReceiveCommits implements PreReceiveHook {
 | 
			
		||||
    // Check objects mentioned inside the incoming pack file are reachable from visible refs.
 | 
			
		||||
    this.perm = permissionBackend.user(user).project(projectName);
 | 
			
		||||
    try {
 | 
			
		||||
      projectState.checkStatePermitsRead();
 | 
			
		||||
      this.perm.check(ProjectPermission.READ);
 | 
			
		||||
    } catch (AuthException e) {
 | 
			
		||||
    } catch (AuthException | ResourceConflictException e) {
 | 
			
		||||
      rp.setCheckReferencedObjectsAreReachable(receiveConfig.checkReferencedObjectsAreReachable);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,8 @@ class DefaultRefFilter {
 | 
			
		||||
    PermissionBackend.WithUser withUser = permissionBackend.user(user);
 | 
			
		||||
    PermissionBackend.ForProject forProject = withUser.project(projectState.getNameKey());
 | 
			
		||||
    if (!projectState.isAllUsers()) {
 | 
			
		||||
      if (checkProjectPermission(forProject, ProjectPermission.READ)) {
 | 
			
		||||
      if (projectState.statePermitsRead()
 | 
			
		||||
          && checkProjectPermission(forProject, ProjectPermission.READ)) {
 | 
			
		||||
        return refs;
 | 
			
		||||
      } else if (projectControl.allRefsAreVisible(ImmutableSet.of(RefNames.REFS_CONFIG))) {
 | 
			
		||||
        return fastHideRefsMetaConfig(refs);
 | 
			
		||||
 
 | 
			
		||||
@@ -404,7 +404,7 @@ class ProjectControl {
 | 
			
		||||
              || isOwner();
 | 
			
		||||
 | 
			
		||||
        case READ:
 | 
			
		||||
          return !isHidden() && allRefsAreVisible(Collections.emptySet());
 | 
			
		||||
          return allRefsAreVisible(Collections.emptySet());
 | 
			
		||||
 | 
			
		||||
        case CREATE_REF:
 | 
			
		||||
          return canAddRefs();
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,10 @@ public class ProjectIsVisibleToPredicate extends IsVisibleToPredicate<ProjectDat
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean match(ProjectData pd) throws OrmException {
 | 
			
		||||
    if (!pd.getProject().getState().permitsRead()) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return permissionBackend
 | 
			
		||||
        .user(user)
 | 
			
		||||
        .project(pd.getProject().getNameKey())
 | 
			
		||||
 
 | 
			
		||||
@@ -413,16 +413,19 @@ public class ListProjects implements RestReadView<TopLevelResource> {
 | 
			
		||||
              if (!type.matches(git)) {
 | 
			
		||||
                continue;
 | 
			
		||||
              }
 | 
			
		||||
              boolean canReadAllRefs;
 | 
			
		||||
              try {
 | 
			
		||||
                permissionBackend
 | 
			
		||||
                    .user(currentUser)
 | 
			
		||||
                    .project(e.getNameKey())
 | 
			
		||||
                    .check(ProjectPermission.READ);
 | 
			
		||||
                canReadAllRefs = true;
 | 
			
		||||
              } catch (AuthException ae) {
 | 
			
		||||
                canReadAllRefs = false;
 | 
			
		||||
 | 
			
		||||
              boolean canReadAllRefs = e.statePermitsRead();
 | 
			
		||||
              if (canReadAllRefs) {
 | 
			
		||||
                try {
 | 
			
		||||
                  permissionBackend
 | 
			
		||||
                      .user(currentUser)
 | 
			
		||||
                      .project(e.getNameKey())
 | 
			
		||||
                      .check(ProjectPermission.READ);
 | 
			
		||||
                } catch (AuthException exp) {
 | 
			
		||||
                  canReadAllRefs = false;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              List<Ref> refs = getBranchRefs(projectName, canReadAllRefs);
 | 
			
		||||
              if (!hasValidRef(refs)) {
 | 
			
		||||
                continue;
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@
 | 
			
		||||
 | 
			
		||||
package com.google.gerrit.sshd.commands;
 | 
			
		||||
 | 
			
		||||
import static com.google.common.base.Preconditions.checkNotNull;
 | 
			
		||||
import static java.nio.charset.StandardCharsets.UTF_8;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Splitter;
 | 
			
		||||
@@ -23,6 +24,8 @@ import com.google.gerrit.server.change.ArchiveFormat;
 | 
			
		||||
import com.google.gerrit.server.permissions.PermissionBackend;
 | 
			
		||||
import com.google.gerrit.server.permissions.PermissionBackendException;
 | 
			
		||||
import com.google.gerrit.server.permissions.ProjectPermission;
 | 
			
		||||
import com.google.gerrit.server.project.ProjectCache;
 | 
			
		||||
import com.google.gerrit.server.project.ProjectState;
 | 
			
		||||
import com.google.gerrit.server.restapi.change.AllowedFormats;
 | 
			
		||||
import com.google.gerrit.server.restapi.project.CommitsCollection;
 | 
			
		||||
import com.google.gerrit.sshd.AbstractGitCommand;
 | 
			
		||||
@@ -123,6 +126,7 @@ public class UploadArchive extends AbstractGitCommand {
 | 
			
		||||
  @Inject private PermissionBackend permissionBackend;
 | 
			
		||||
  @Inject private CommitsCollection commits;
 | 
			
		||||
  @Inject private AllowedFormats allowedFormats;
 | 
			
		||||
  @Inject private ProjectCache projectCache;
 | 
			
		||||
  private Options options = new Options();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -242,6 +246,13 @@ public class UploadArchive extends AbstractGitCommand {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean canRead(ObjectId revId) throws IOException, PermissionBackendException {
 | 
			
		||||
    ProjectState projectState = projectCache.get(projectName);
 | 
			
		||||
    checkNotNull(projectState, "Failed to load project %s", projectName);
 | 
			
		||||
 | 
			
		||||
    if (!projectState.statePermitsRead()) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      permissionBackend.user(user).project(projectName).check(ProjectPermission.READ);
 | 
			
		||||
      return true;
 | 
			
		||||
 
 | 
			
		||||
 Submodule plugins/replication updated: f57f0297e3...d8f5bcec21
									
								
							
		Reference in New Issue
	
	Block a user