Remove ReviewDb from PermissionBackend hierarchy
Change-Id: I5a1a2f59573f3f3f3ea67137ea203e32e2f07e79
This commit is contained in:
		@@ -20,7 +20,6 @@ import com.google.gerrit.extensions.restapi.Url;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Patch;
 | 
					import com.google.gerrit.reviewdb.client.Patch;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.PatchSetUtil;
 | 
					import com.google.gerrit.server.PatchSetUtil;
 | 
				
			||||||
import com.google.gerrit.server.edit.ChangeEdit;
 | 
					import com.google.gerrit.server.edit.ChangeEdit;
 | 
				
			||||||
import com.google.gerrit.server.edit.ChangeEditUtil;
 | 
					import com.google.gerrit.server.edit.ChangeEditUtil;
 | 
				
			||||||
@@ -32,7 +31,6 @@ import com.google.gerrit.server.project.NoSuchChangeException;
 | 
				
			|||||||
import com.google.gerrit.server.project.ProjectCache;
 | 
					import com.google.gerrit.server.project.ProjectCache;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.Singleton;
 | 
					import com.google.inject.Singleton;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.Optional;
 | 
					import java.util.Optional;
 | 
				
			||||||
@@ -52,7 +50,6 @@ import org.eclipse.jgit.lib.ObjectId;
 | 
				
			|||||||
@SuppressWarnings("serial")
 | 
					@SuppressWarnings("serial")
 | 
				
			||||||
@Singleton
 | 
					@Singleton
 | 
				
			||||||
public class CatServlet extends HttpServlet {
 | 
					public class CatServlet extends HttpServlet {
 | 
				
			||||||
  private final Provider<ReviewDb> requestDb;
 | 
					 | 
				
			||||||
  private final ChangeEditUtil changeEditUtil;
 | 
					  private final ChangeEditUtil changeEditUtil;
 | 
				
			||||||
  private final PatchSetUtil psUtil;
 | 
					  private final PatchSetUtil psUtil;
 | 
				
			||||||
  private final ChangeNotes.Factory changeNotesFactory;
 | 
					  private final ChangeNotes.Factory changeNotesFactory;
 | 
				
			||||||
@@ -61,13 +58,11 @@ public class CatServlet extends HttpServlet {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  CatServlet(
 | 
					  CatServlet(
 | 
				
			||||||
      Provider<ReviewDb> sf,
 | 
					 | 
				
			||||||
      ChangeEditUtil ceu,
 | 
					      ChangeEditUtil ceu,
 | 
				
			||||||
      PatchSetUtil psu,
 | 
					      PatchSetUtil psu,
 | 
				
			||||||
      ChangeNotes.Factory cnf,
 | 
					      ChangeNotes.Factory cnf,
 | 
				
			||||||
      PermissionBackend pb,
 | 
					      PermissionBackend pb,
 | 
				
			||||||
      ProjectCache pc) {
 | 
					      ProjectCache pc) {
 | 
				
			||||||
    requestDb = sf;
 | 
					 | 
				
			||||||
    changeEditUtil = ceu;
 | 
					    changeEditUtil = ceu;
 | 
				
			||||||
    psUtil = psu;
 | 
					    psUtil = psu;
 | 
				
			||||||
    changeNotesFactory = cnf;
 | 
					    changeNotesFactory = cnf;
 | 
				
			||||||
@@ -127,11 +122,7 @@ public class CatServlet extends HttpServlet {
 | 
				
			|||||||
    String revision;
 | 
					    String revision;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      ChangeNotes notes = changeNotesFactory.createChecked(changeId);
 | 
					      ChangeNotes notes = changeNotesFactory.createChecked(changeId);
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend.currentUser().change(notes).check(ChangePermission.READ);
 | 
				
			||||||
          .currentUser()
 | 
					 | 
				
			||||||
          .change(notes)
 | 
					 | 
				
			||||||
          .database(requestDb)
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					 | 
				
			||||||
      projectCache.checkedGet(notes.getProjectName()).checkStatePermitsRead();
 | 
					      projectCache.checkedGet(notes.getProjectName()).checkStatePermitsRead();
 | 
				
			||||||
      if (patchKey.getParentKey().get() == 0) {
 | 
					      if (patchKey.getParentKey().get() == 0) {
 | 
				
			||||||
        // change edit
 | 
					        // change edit
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -204,11 +204,11 @@ public class ApprovalsUtil {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Set<Account.Id> need = Sets.newLinkedHashSet(wantReviewers);
 | 
					    Set<Account.Id> need = Sets.newLinkedHashSet(wantReviewers);
 | 
				
			||||||
    if (authorId != null && canSee(db, update.getNotes(), authorId)) {
 | 
					    if (authorId != null && canSee(update.getNotes(), authorId)) {
 | 
				
			||||||
      need.add(authorId);
 | 
					      need.add(authorId);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (committerId != null && canSee(db, update.getNotes(), committerId)) {
 | 
					    if (committerId != null && canSee(update.getNotes(), committerId)) {
 | 
				
			||||||
      need.add(committerId);
 | 
					      need.add(committerId);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    need.remove(change.getOwner());
 | 
					    need.remove(change.getOwner());
 | 
				
			||||||
@@ -229,16 +229,12 @@ public class ApprovalsUtil {
 | 
				
			|||||||
    return Collections.unmodifiableList(cells);
 | 
					    return Collections.unmodifiableList(cells);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private boolean canSee(ReviewDb db, ChangeNotes notes, Account.Id accountId) {
 | 
					  private boolean canSee(ChangeNotes notes, Account.Id accountId) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      if (!projectCache.checkedGet(notes.getProjectName()).statePermitsRead()) {
 | 
					      if (!projectCache.checkedGet(notes.getProjectName()).statePermitsRead()) {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend.absentUser(accountId).change(notes).check(ChangePermission.READ);
 | 
				
			||||||
          .absentUser(accountId)
 | 
					 | 
				
			||||||
          .change(notes)
 | 
					 | 
				
			||||||
          .database(db)
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
@@ -304,7 +300,7 @@ public class ApprovalsUtil {
 | 
				
			|||||||
    if (approvals.isEmpty()) {
 | 
					    if (approvals.isEmpty()) {
 | 
				
			||||||
      return ImmutableList.of();
 | 
					      return ImmutableList.of();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    checkApprovals(approvals, permissionBackend.user(user).database(db).change(update.getNotes()));
 | 
					    checkApprovals(approvals, permissionBackend.user(user).change(update.getNotes()));
 | 
				
			||||||
    List<PatchSetApproval> cells = new ArrayList<>(approvals.size());
 | 
					    List<PatchSetApproval> cells = new ArrayList<>(approvals.size());
 | 
				
			||||||
    Date ts = update.getWhen();
 | 
					    Date ts = update.getWhen();
 | 
				
			||||||
    for (Map.Entry<String, Short> vote : approvals.entrySet()) {
 | 
					    for (Map.Entry<String, Short> vote : approvals.entrySet()) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -425,8 +425,7 @@ public class ChangeInserter implements InsertChangeOp {
 | 
				
			|||||||
    update.fixStatus(change.getStatus());
 | 
					    update.fixStatus(change.getStatus());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reviewerAdditions =
 | 
					    reviewerAdditions =
 | 
				
			||||||
        reviewerAdder.prepare(
 | 
					        reviewerAdder.prepare(ctx.getNotes(), ctx.getUser(), getReviewerInputs(), true);
 | 
				
			||||||
            ctx.getDb(), ctx.getNotes(), ctx.getUser(), getReviewerInputs(), true);
 | 
					 | 
				
			||||||
    Optional<ReviewerAddition> reviewerError = reviewerAdditions.getFailures().stream().findFirst();
 | 
					    Optional<ReviewerAddition> reviewerError = reviewerAdditions.getFailures().stream().findFirst();
 | 
				
			||||||
    if (reviewerError.isPresent()) {
 | 
					    if (reviewerError.isPresent()) {
 | 
				
			||||||
      throw new UnprocessableEntityException(reviewerError.get().result.error);
 | 
					      throw new UnprocessableEntityException(reviewerError.get().result.error);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,7 +74,6 @@ import com.google.gerrit.reviewdb.client.ChangeMessage;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
					import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.ChangeMessagesUtil;
 | 
					import com.google.gerrit.server.ChangeMessagesUtil;
 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.GpgException;
 | 
					import com.google.gerrit.server.GpgException;
 | 
				
			||||||
@@ -202,7 +201,6 @@ public class ChangeJson {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private final Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
  private final Provider<CurrentUser> userProvider;
 | 
					  private final Provider<CurrentUser> userProvider;
 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
  private final ChangeData.Factory changeDataFactory;
 | 
					  private final ChangeData.Factory changeDataFactory;
 | 
				
			||||||
@@ -225,7 +223,6 @@ public class ChangeJson {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  ChangeJson(
 | 
					  ChangeJson(
 | 
				
			||||||
      Provider<ReviewDb> db,
 | 
					 | 
				
			||||||
      Provider<CurrentUser> user,
 | 
					      Provider<CurrentUser> user,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      ChangeData.Factory cdf,
 | 
					      ChangeData.Factory cdf,
 | 
				
			||||||
@@ -241,7 +238,6 @@ public class ChangeJson {
 | 
				
			|||||||
      RevisionJson.Factory revisionJsonFactory,
 | 
					      RevisionJson.Factory revisionJsonFactory,
 | 
				
			||||||
      @Assisted Iterable<ListChangesOption> options,
 | 
					      @Assisted Iterable<ListChangesOption> options,
 | 
				
			||||||
      @Assisted Optional<PluginDefinedAttributesFactory> pluginDefinedAttributesFactory) {
 | 
					      @Assisted Optional<PluginDefinedAttributesFactory> pluginDefinedAttributesFactory) {
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.userProvider = user;
 | 
					    this.userProvider = user;
 | 
				
			||||||
    this.changeDataFactory = cdf;
 | 
					    this.changeDataFactory = cdf;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
@@ -803,7 +799,7 @@ public class ChangeJson {
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
  private PermissionBackend.ForChange permissionBackendForChange(CurrentUser user, ChangeData cd)
 | 
					  private PermissionBackend.ForChange permissionBackendForChange(CurrentUser user, ChangeData cd)
 | 
				
			||||||
      throws OrmException {
 | 
					      throws OrmException {
 | 
				
			||||||
    PermissionBackend.WithUser withUser = permissionBackend.user(user).database(db);
 | 
					    PermissionBackend.WithUser withUser = permissionBackend.user(user);
 | 
				
			||||||
    return lazyLoad
 | 
					    return lazyLoad
 | 
				
			||||||
        ? withUser.change(cd)
 | 
					        ? withUser.change(cd)
 | 
				
			||||||
        : withUser.indexedChange(cd, notesFactory.createFromIndexedChange(cd.change()));
 | 
					        : withUser.indexedChange(cd, notesFactory.createFromIndexedChange(cd.change()));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,6 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.ApprovalsUtil;
 | 
					import com.google.gerrit.server.ApprovalsUtil;
 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.PatchSetUtil;
 | 
					import com.google.gerrit.server.PatchSetUtil;
 | 
				
			||||||
@@ -42,7 +41,6 @@ import com.google.gerrit.server.project.ProjectCache;
 | 
				
			|||||||
import com.google.gerrit.server.project.ProjectState;
 | 
					import com.google.gerrit.server.project.ProjectState;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.TypeLiteral;
 | 
					import com.google.inject.TypeLiteral;
 | 
				
			||||||
import com.google.inject.assistedinject.Assisted;
 | 
					import com.google.inject.assistedinject.Assisted;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
@@ -71,7 +69,6 @@ public class ChangeResource implements RestResource, HasETag {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  private static final String ZERO_ID_STRING = ObjectId.zeroId().name();
 | 
					  private static final String ZERO_ID_STRING = ObjectId.zeroId().name();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private final Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
  private final AccountCache accountCache;
 | 
					  private final AccountCache accountCache;
 | 
				
			||||||
  private final ApprovalsUtil approvalUtil;
 | 
					  private final ApprovalsUtil approvalUtil;
 | 
				
			||||||
  private final PatchSetUtil patchSetUtil;
 | 
					  private final PatchSetUtil patchSetUtil;
 | 
				
			||||||
@@ -83,7 +80,6 @@ public class ChangeResource implements RestResource, HasETag {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  ChangeResource(
 | 
					  ChangeResource(
 | 
				
			||||||
      Provider<ReviewDb> db,
 | 
					 | 
				
			||||||
      AccountCache accountCache,
 | 
					      AccountCache accountCache,
 | 
				
			||||||
      ApprovalsUtil approvalUtil,
 | 
					      ApprovalsUtil approvalUtil,
 | 
				
			||||||
      PatchSetUtil patchSetUtil,
 | 
					      PatchSetUtil patchSetUtil,
 | 
				
			||||||
@@ -92,7 +88,6 @@ public class ChangeResource implements RestResource, HasETag {
 | 
				
			|||||||
      ProjectCache projectCache,
 | 
					      ProjectCache projectCache,
 | 
				
			||||||
      @Assisted ChangeNotes notes,
 | 
					      @Assisted ChangeNotes notes,
 | 
				
			||||||
      @Assisted CurrentUser user) {
 | 
					      @Assisted CurrentUser user) {
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.accountCache = accountCache;
 | 
					    this.accountCache = accountCache;
 | 
				
			||||||
    this.approvalUtil = approvalUtil;
 | 
					    this.approvalUtil = approvalUtil;
 | 
				
			||||||
    this.patchSetUtil = patchSetUtil;
 | 
					    this.patchSetUtil = patchSetUtil;
 | 
				
			||||||
@@ -104,7 +99,7 @@ public class ChangeResource implements RestResource, HasETag {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public PermissionBackend.ForChange permissions() {
 | 
					  public PermissionBackend.ForChange permissions() {
 | 
				
			||||||
    return permissionBackend.user(user).database(db).change(notes);
 | 
					    return permissionBackend.user(user).change(notes);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public CurrentUser getUser() {
 | 
					  public CurrentUser getUser() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,6 @@ import com.google.gerrit.reviewdb.client.Account;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Account.Id;
 | 
					import com.google.gerrit.reviewdb.client.Account.Id;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
					import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.ApprovalsUtil;
 | 
					import com.google.gerrit.server.ApprovalsUtil;
 | 
				
			||||||
import com.google.gerrit.server.account.AccountLoader;
 | 
					import com.google.gerrit.server.account.AccountLoader;
 | 
				
			||||||
import com.google.gerrit.server.notedb.ChangeNotes;
 | 
					import com.google.gerrit.server.notedb.ChangeNotes;
 | 
				
			||||||
@@ -55,7 +54,6 @@ import com.google.gerrit.server.permissions.PermissionBackendException;
 | 
				
			|||||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
					import com.google.gerrit.server.query.change.ChangeData;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.assistedinject.Assisted;
 | 
					import com.google.inject.assistedinject.Assisted;
 | 
				
			||||||
import java.sql.Timestamp;
 | 
					import java.sql.Timestamp;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
@@ -79,7 +77,6 @@ public class LabelsJson {
 | 
				
			|||||||
    LabelsJson create(Iterable<ListChangesOption> options);
 | 
					    LabelsJson create(Iterable<ListChangesOption> options);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private final Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
  private final ApprovalsUtil approvalsUtil;
 | 
					  private final ApprovalsUtil approvalsUtil;
 | 
				
			||||||
  private final ChangeNotes.Factory notesFactory;
 | 
					  private final ChangeNotes.Factory notesFactory;
 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
@@ -87,12 +84,10 @@ public class LabelsJson {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  LabelsJson(
 | 
					  LabelsJson(
 | 
				
			||||||
      Provider<ReviewDb> db,
 | 
					 | 
				
			||||||
      ApprovalsUtil approvalsUtil,
 | 
					      ApprovalsUtil approvalsUtil,
 | 
				
			||||||
      ChangeNotes.Factory notesFactory,
 | 
					      ChangeNotes.Factory notesFactory,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      @Assisted Iterable<ListChangesOption> options) {
 | 
					      @Assisted Iterable<ListChangesOption> options) {
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.approvalsUtil = approvalsUtil;
 | 
					    this.approvalsUtil = approvalsUtil;
 | 
				
			||||||
    this.notesFactory = notesFactory;
 | 
					    this.notesFactory = notesFactory;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
@@ -507,7 +502,7 @@ public class LabelsJson {
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
  private PermissionBackend.ForChange permissionBackendForChange(Account.Id user, ChangeData cd)
 | 
					  private PermissionBackend.ForChange permissionBackendForChange(Account.Id user, ChangeData cd)
 | 
				
			||||||
      throws OrmException {
 | 
					      throws OrmException {
 | 
				
			||||||
    PermissionBackend.WithUser withUser = permissionBackend.absentUser(user).database(db);
 | 
					    PermissionBackend.WithUser withUser = permissionBackend.absentUser(user);
 | 
				
			||||||
    return lazyLoad
 | 
					    return lazyLoad
 | 
				
			||||||
        ? withUser.change(cd)
 | 
					        ? withUser.change(cd)
 | 
				
			||||||
        : withUser.indexedChange(cd, notesFactory.createFromIndexedChange(cd.change()));
 | 
					        : withUser.indexedChange(cd, notesFactory.createFromIndexedChange(cd.change()));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -287,11 +287,7 @@ public class PatchSetInserter implements BatchUpdateOp {
 | 
				
			|||||||
    psUtil.checkPatchSetNotLocked(origNotes);
 | 
					    psUtil.checkPatchSetNotLocked(origNotes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (checkAddPatchSetPermission) {
 | 
					    if (checkAddPatchSetPermission) {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend.user(ctx.getUser()).change(origNotes).check(ChangePermission.ADD_PATCH_SET);
 | 
				
			||||||
          .user(ctx.getUser())
 | 
					 | 
				
			||||||
          .database(ctx.getDb())
 | 
					 | 
				
			||||||
          .change(origNotes)
 | 
					 | 
				
			||||||
          .check(ChangePermission.ADD_PATCH_SET);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    projectCache.checkedGet(ctx.getProject()).checkStatePermitsWrite();
 | 
					    projectCache.checkedGet(ctx.getProject()).checkStatePermitsWrite();
 | 
				
			||||||
    if (!validate) {
 | 
					    if (!validate) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,6 @@ import com.google.gerrit.reviewdb.client.Branch;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
					import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.AnonymousUser;
 | 
					import com.google.gerrit.server.AnonymousUser;
 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.IdentifiedUser;
 | 
					import com.google.gerrit.server.IdentifiedUser;
 | 
				
			||||||
@@ -189,7 +188,6 @@ public class ReviewerAdder {
 | 
				
			|||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Prepare application of a single {@link AddReviewerInput}.
 | 
					   * Prepare application of a single {@link AddReviewerInput}.
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * @param db database.
 | 
					 | 
				
			||||||
   * @param notes change notes.
 | 
					   * @param notes change notes.
 | 
				
			||||||
   * @param user user performing the reviewer addition.
 | 
					   * @param user user performing the reviewer addition.
 | 
				
			||||||
   * @param input input describing user or group to add as a reviewer.
 | 
					   * @param input input describing user or group to add as a reviewer.
 | 
				
			||||||
@@ -203,7 +201,7 @@ public class ReviewerAdder {
 | 
				
			|||||||
   * @throws ConfigInvalidException
 | 
					   * @throws ConfigInvalidException
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public ReviewerAddition prepare(
 | 
					  public ReviewerAddition prepare(
 | 
				
			||||||
      ReviewDb db, ChangeNotes notes, CurrentUser user, AddReviewerInput input, boolean allowGroup)
 | 
					      ChangeNotes notes, CurrentUser user, AddReviewerInput input, boolean allowGroup)
 | 
				
			||||||
      throws OrmException, IOException, PermissionBackendException, ConfigInvalidException {
 | 
					      throws OrmException, IOException, PermissionBackendException, ConfigInvalidException {
 | 
				
			||||||
    requireNonNull(input.reviewer);
 | 
					    requireNonNull(input.reviewer);
 | 
				
			||||||
    ListMultimap<RecipientType, Account.Id> accountsToNotify;
 | 
					    ListMultimap<RecipientType, Account.Id> accountsToNotify;
 | 
				
			||||||
@@ -219,13 +217,12 @@ public class ReviewerAdder {
 | 
				
			|||||||
            .is(BooleanProjectConfig.ENABLE_REVIEWER_BY_EMAIL);
 | 
					            .is(BooleanProjectConfig.ENABLE_REVIEWER_BY_EMAIL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ReviewerAddition byAccountId =
 | 
					    ReviewerAddition byAccountId =
 | 
				
			||||||
        addByAccountId(db, input, notes, user, accountsToNotify, allowGroup, allowByEmail);
 | 
					        addByAccountId(input, notes, user, accountsToNotify, allowGroup, allowByEmail);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ReviewerAddition wholeGroup = null;
 | 
					    ReviewerAddition wholeGroup = null;
 | 
				
			||||||
    if (byAccountId == null || !byAccountId.exactMatchFound) {
 | 
					    if (byAccountId == null || !byAccountId.exactMatchFound) {
 | 
				
			||||||
      wholeGroup =
 | 
					      wholeGroup =
 | 
				
			||||||
          addWholeGroup(
 | 
					          addWholeGroup(input, notes, user, accountsToNotify, confirmed, allowGroup, allowByEmail);
 | 
				
			||||||
              db, input, notes, user, accountsToNotify, confirmed, allowGroup, allowByEmail);
 | 
					 | 
				
			||||||
      if (wholeGroup != null && wholeGroup.exactMatchFound) {
 | 
					      if (wholeGroup != null && wholeGroup.exactMatchFound) {
 | 
				
			||||||
        return wholeGroup;
 | 
					        return wholeGroup;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -238,7 +235,7 @@ public class ReviewerAdder {
 | 
				
			|||||||
      return wholeGroup;
 | 
					      return wholeGroup;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return addByEmail(db, input, notes, user, accountsToNotify);
 | 
					    return addByEmail(input, notes, user, accountsToNotify);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public ReviewerAddition ccCurrentUser(CurrentUser user, RevisionResource revision) {
 | 
					  public ReviewerAddition ccCurrentUser(CurrentUser user, RevisionResource revision) {
 | 
				
			||||||
@@ -254,7 +251,6 @@ public class ReviewerAdder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Nullable
 | 
					  @Nullable
 | 
				
			||||||
  private ReviewerAddition addByAccountId(
 | 
					  private ReviewerAddition addByAccountId(
 | 
				
			||||||
      ReviewDb db,
 | 
					 | 
				
			||||||
      AddReviewerInput input,
 | 
					      AddReviewerInput input,
 | 
				
			||||||
      ChangeNotes notes,
 | 
					      ChangeNotes notes,
 | 
				
			||||||
      CurrentUser user,
 | 
					      CurrentUser user,
 | 
				
			||||||
@@ -282,7 +278,7 @@ public class ReviewerAdder {
 | 
				
			|||||||
      return null;
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (isValidReviewer(db, notes.getChange().getDest(), reviewerUser.getAccount())) {
 | 
					    if (isValidReviewer(notes.getChange().getDest(), reviewerUser.getAccount())) {
 | 
				
			||||||
      return new ReviewerAddition(
 | 
					      return new ReviewerAddition(
 | 
				
			||||||
          input,
 | 
					          input,
 | 
				
			||||||
          notes,
 | 
					          notes,
 | 
				
			||||||
@@ -309,7 +305,6 @@ public class ReviewerAdder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Nullable
 | 
					  @Nullable
 | 
				
			||||||
  private ReviewerAddition addWholeGroup(
 | 
					  private ReviewerAddition addWholeGroup(
 | 
				
			||||||
      ReviewDb db,
 | 
					 | 
				
			||||||
      AddReviewerInput input,
 | 
					      AddReviewerInput input,
 | 
				
			||||||
      ChangeNotes notes,
 | 
					      ChangeNotes notes,
 | 
				
			||||||
      CurrentUser user,
 | 
					      CurrentUser user,
 | 
				
			||||||
@@ -380,7 +375,7 @@ public class ReviewerAdder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (Account member : members) {
 | 
					    for (Account member : members) {
 | 
				
			||||||
      if (isValidReviewer(db, notes.getChange().getDest(), member)) {
 | 
					      if (isValidReviewer(notes.getChange().getDest(), member)) {
 | 
				
			||||||
        reviewers.add(member.getId());
 | 
					        reviewers.add(member.getId());
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -390,18 +385,13 @@ public class ReviewerAdder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Nullable
 | 
					  @Nullable
 | 
				
			||||||
  private ReviewerAddition addByEmail(
 | 
					  private ReviewerAddition addByEmail(
 | 
				
			||||||
      ReviewDb db,
 | 
					 | 
				
			||||||
      AddReviewerInput input,
 | 
					      AddReviewerInput input,
 | 
				
			||||||
      ChangeNotes notes,
 | 
					      ChangeNotes notes,
 | 
				
			||||||
      CurrentUser user,
 | 
					      CurrentUser user,
 | 
				
			||||||
      ListMultimap<RecipientType, Account.Id> accountsToNotify)
 | 
					      ListMultimap<RecipientType, Account.Id> accountsToNotify)
 | 
				
			||||||
      throws PermissionBackendException {
 | 
					      throws PermissionBackendException {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend.user(anonymousProvider.get()).change(notes).check(ChangePermission.READ);
 | 
				
			||||||
          .user(anonymousProvider.get())
 | 
					 | 
				
			||||||
          .database(db)
 | 
					 | 
				
			||||||
          .change(notes)
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      return fail(
 | 
					      return fail(
 | 
				
			||||||
          input,
 | 
					          input,
 | 
				
			||||||
@@ -420,7 +410,7 @@ public class ReviewerAdder {
 | 
				
			|||||||
        input, notes, user, null, ImmutableList.of(adr), accountsToNotify, true);
 | 
					        input, notes, user, null, ImmutableList.of(adr), accountsToNotify, true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private boolean isValidReviewer(ReviewDb db, Branch.NameKey branch, Account member)
 | 
					  private boolean isValidReviewer(Branch.NameKey branch, Account member)
 | 
				
			||||||
      throws PermissionBackendException {
 | 
					      throws PermissionBackendException {
 | 
				
			||||||
    if (!member.isActive()) {
 | 
					    if (!member.isActive()) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
@@ -430,11 +420,7 @@ public class ReviewerAdder {
 | 
				
			|||||||
      // Check ref permission instead of change permission, since change permissions take into
 | 
					      // Check ref permission instead of change permission, since change permissions take into
 | 
				
			||||||
      // account the private bit, whereas adding a user as a reviewer is explicitly allowing them to
 | 
					      // account the private bit, whereas adding a user as a reviewer is explicitly allowing them to
 | 
				
			||||||
      // see private changes.
 | 
					      // see private changes.
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend.absentUser(member.getId()).ref(branch).check(RefPermission.READ);
 | 
				
			||||||
          .absentUser(member.getId())
 | 
					 | 
				
			||||||
          .database(db)
 | 
					 | 
				
			||||||
          .ref(branch)
 | 
					 | 
				
			||||||
          .check(RefPermission.READ);
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
@@ -566,7 +552,6 @@ public class ReviewerAdder {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public ReviewerAdditionList prepare(
 | 
					  public ReviewerAdditionList prepare(
 | 
				
			||||||
      ReviewDb db,
 | 
					 | 
				
			||||||
      ChangeNotes notes,
 | 
					      ChangeNotes notes,
 | 
				
			||||||
      CurrentUser user,
 | 
					      CurrentUser user,
 | 
				
			||||||
      Iterable<? extends AddReviewerInput> inputs,
 | 
					      Iterable<? extends AddReviewerInput> inputs,
 | 
				
			||||||
@@ -587,7 +572,7 @@ public class ReviewerAdder {
 | 
				
			|||||||
            .collect(toImmutableList());
 | 
					            .collect(toImmutableList());
 | 
				
			||||||
    List<ReviewerAddition> additions = new ArrayList<>();
 | 
					    List<ReviewerAddition> additions = new ArrayList<>();
 | 
				
			||||||
    for (AddReviewerInput input : sorted) {
 | 
					    for (AddReviewerInput input : sorted) {
 | 
				
			||||||
      additions.add(prepare(db, notes, user, input, allowGroup));
 | 
					      additions.add(prepare(notes, user, input, allowGroup));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return new ReviewerAdditionList(additions);
 | 
					    return new ReviewerAdditionList(additions);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,6 @@ import com.google.gerrit.mail.Address;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Account;
 | 
					import com.google.gerrit.reviewdb.client.Account;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
					import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.ApprovalsUtil;
 | 
					import com.google.gerrit.server.ApprovalsUtil;
 | 
				
			||||||
import com.google.gerrit.server.account.AccountLoader;
 | 
					import com.google.gerrit.server.account.AccountLoader;
 | 
				
			||||||
import com.google.gerrit.server.permissions.LabelPermission;
 | 
					import com.google.gerrit.server.permissions.LabelPermission;
 | 
				
			||||||
@@ -38,7 +37,6 @@ import com.google.gerrit.server.project.SubmitRuleOptions;
 | 
				
			|||||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
					import com.google.gerrit.server.query.change.ChangeData;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.Singleton;
 | 
					import com.google.inject.Singleton;
 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
@@ -46,7 +44,6 @@ import java.util.TreeMap;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Singleton
 | 
					@Singleton
 | 
				
			||||||
public class ReviewerJson {
 | 
					public class ReviewerJson {
 | 
				
			||||||
  private final Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
  private final ChangeData.Factory changeDataFactory;
 | 
					  private final ChangeData.Factory changeDataFactory;
 | 
				
			||||||
  private final ApprovalsUtil approvalsUtil;
 | 
					  private final ApprovalsUtil approvalsUtil;
 | 
				
			||||||
@@ -55,13 +52,11 @@ public class ReviewerJson {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  ReviewerJson(
 | 
					  ReviewerJson(
 | 
				
			||||||
      Provider<ReviewDb> db,
 | 
					 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      ChangeData.Factory changeDataFactory,
 | 
					      ChangeData.Factory changeDataFactory,
 | 
				
			||||||
      ApprovalsUtil approvalsUtil,
 | 
					      ApprovalsUtil approvalsUtil,
 | 
				
			||||||
      AccountLoader.Factory accountLoaderFactory,
 | 
					      AccountLoader.Factory accountLoaderFactory,
 | 
				
			||||||
      SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory) {
 | 
					      SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory) {
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
    this.changeDataFactory = changeDataFactory;
 | 
					    this.changeDataFactory = changeDataFactory;
 | 
				
			||||||
    this.approvalsUtil = approvalsUtil;
 | 
					    this.approvalsUtil = approvalsUtil;
 | 
				
			||||||
@@ -128,8 +123,7 @@ public class ReviewerJson {
 | 
				
			|||||||
    // do not exist in the DB.
 | 
					    // do not exist in the DB.
 | 
				
			||||||
    PatchSet ps = cd.currentPatchSet();
 | 
					    PatchSet ps = cd.currentPatchSet();
 | 
				
			||||||
    if (ps != null) {
 | 
					    if (ps != null) {
 | 
				
			||||||
      PermissionBackend.ForChange perm =
 | 
					      PermissionBackend.ForChange perm = permissionBackend.absentUser(reviewerAccountId).change(cd);
 | 
				
			||||||
          permissionBackend.absentUser(reviewerAccountId).database(db).change(cd);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for (SubmitRecord rec : submitRuleEvaluator.evaluate(cd)) {
 | 
					      for (SubmitRecord rec : submitRuleEvaluator.evaluate(cd)) {
 | 
				
			||||||
        if (rec.labels == null) {
 | 
					        if (rec.labels == null) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@ import com.google.gerrit.extensions.restapi.ResourceConflictException;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.RefNames;
 | 
					import com.google.gerrit.reviewdb.client.RefNames;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.GerritPersonIdent;
 | 
					import com.google.gerrit.server.GerritPersonIdent;
 | 
				
			||||||
import com.google.gerrit.server.IdentifiedUser;
 | 
					import com.google.gerrit.server.IdentifiedUser;
 | 
				
			||||||
@@ -80,7 +79,6 @@ public class ChangeEditModifier {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  private final TimeZone tz;
 | 
					  private final TimeZone tz;
 | 
				
			||||||
  private final ChangeIndexer indexer;
 | 
					  private final ChangeIndexer indexer;
 | 
				
			||||||
  private final Provider<ReviewDb> reviewDb;
 | 
					 | 
				
			||||||
  private final Provider<CurrentUser> currentUser;
 | 
					  private final Provider<CurrentUser> currentUser;
 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
  private final ChangeEditUtil changeEditUtil;
 | 
					  private final ChangeEditUtil changeEditUtil;
 | 
				
			||||||
@@ -91,14 +89,12 @@ public class ChangeEditModifier {
 | 
				
			|||||||
  ChangeEditModifier(
 | 
					  ChangeEditModifier(
 | 
				
			||||||
      @GerritPersonIdent PersonIdent gerritIdent,
 | 
					      @GerritPersonIdent PersonIdent gerritIdent,
 | 
				
			||||||
      ChangeIndexer indexer,
 | 
					      ChangeIndexer indexer,
 | 
				
			||||||
      Provider<ReviewDb> reviewDb,
 | 
					 | 
				
			||||||
      Provider<CurrentUser> currentUser,
 | 
					      Provider<CurrentUser> currentUser,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      ChangeEditUtil changeEditUtil,
 | 
					      ChangeEditUtil changeEditUtil,
 | 
				
			||||||
      PatchSetUtil patchSetUtil,
 | 
					      PatchSetUtil patchSetUtil,
 | 
				
			||||||
      ProjectCache projectCache) {
 | 
					      ProjectCache projectCache) {
 | 
				
			||||||
    this.indexer = indexer;
 | 
					    this.indexer = indexer;
 | 
				
			||||||
    this.reviewDb = reviewDb;
 | 
					 | 
				
			||||||
    this.currentUser = currentUser;
 | 
					    this.currentUser = currentUser;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
    this.tz = gerritIdent.getTimeZone();
 | 
					    this.tz = gerritIdent.getTimeZone();
 | 
				
			||||||
@@ -410,11 +406,7 @@ public class ChangeEditModifier {
 | 
				
			|||||||
    // Not allowed to edit if the current patch set is locked.
 | 
					    // Not allowed to edit if the current patch set is locked.
 | 
				
			||||||
    patchSetUtil.checkPatchSetNotLocked(notes);
 | 
					    patchSetUtil.checkPatchSetNotLocked(notes);
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend.currentUser().change(notes).check(ChangePermission.ADD_PATCH_SET);
 | 
				
			||||||
          .currentUser()
 | 
					 | 
				
			||||||
          .database(reviewDb)
 | 
					 | 
				
			||||||
          .change(notes)
 | 
					 | 
				
			||||||
          .check(ChangePermission.ADD_PATCH_SET);
 | 
					 | 
				
			||||||
      projectCache.checkedGet(notes.getProjectName()).checkStatePermitsWrite();
 | 
					      projectCache.checkedGet(notes.getProjectName()).checkStatePermitsWrite();
 | 
				
			||||||
    } catch (AuthException denied) {
 | 
					    } catch (AuthException denied) {
 | 
				
			||||||
      throw new AuthException("edit not permitted", denied);
 | 
					      throw new AuthException("edit not permitted", denied);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,6 @@ import com.google.gerrit.reviewdb.client.Branch;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.notedb.ChangeNotes;
 | 
					import com.google.gerrit.server.notedb.ChangeNotes;
 | 
				
			||||||
import com.google.gerrit.server.permissions.ChangePermission;
 | 
					import com.google.gerrit.server.permissions.ChangePermission;
 | 
				
			||||||
@@ -37,7 +36,6 @@ import com.google.gerrit.server.project.ProjectCache;
 | 
				
			|||||||
import com.google.gerrit.server.project.ProjectState;
 | 
					import com.google.gerrit.server.project.ProjectState;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.Singleton;
 | 
					import com.google.inject.Singleton;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Distributes Events to listeners if they are allowed to see them */
 | 
					/** Distributes Events to listeners if they are allowed to see them */
 | 
				
			||||||
@@ -64,22 +62,18 @@ public class EventBroker implements EventDispatcher {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  protected final ChangeNotes.Factory notesFactory;
 | 
					  protected final ChangeNotes.Factory notesFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected final Provider<ReviewDb> dbProvider;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  public EventBroker(
 | 
					  public EventBroker(
 | 
				
			||||||
      PluginSetContext<UserScopedEventListener> listeners,
 | 
					      PluginSetContext<UserScopedEventListener> listeners,
 | 
				
			||||||
      PluginSetContext<EventListener> unrestrictedListeners,
 | 
					      PluginSetContext<EventListener> unrestrictedListeners,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      ProjectCache projectCache,
 | 
					      ProjectCache projectCache,
 | 
				
			||||||
      ChangeNotes.Factory notesFactory,
 | 
					      ChangeNotes.Factory notesFactory) {
 | 
				
			||||||
      Provider<ReviewDb> dbProvider) {
 | 
					 | 
				
			||||||
    this.listeners = listeners;
 | 
					    this.listeners = listeners;
 | 
				
			||||||
    this.unrestrictedListeners = unrestrictedListeners;
 | 
					    this.unrestrictedListeners = unrestrictedListeners;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
    this.projectCache = projectCache;
 | 
					    this.projectCache = projectCache;
 | 
				
			||||||
    this.notesFactory = notesFactory;
 | 
					    this.notesFactory = notesFactory;
 | 
				
			||||||
    this.dbProvider = dbProvider;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Override
 | 
					  @Override
 | 
				
			||||||
@@ -173,12 +167,10 @@ public class EventBroker implements EventDispatcher {
 | 
				
			|||||||
    if (pe == null || !pe.statePermitsRead()) {
 | 
					    if (pe == null || !pe.statePermitsRead()) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    ReviewDb db = dbProvider.get();
 | 
					 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend
 | 
				
			||||||
          .user(user)
 | 
					          .user(user)
 | 
				
			||||||
          .change(notesFactory.createChecked(change))
 | 
					          .change(notesFactory.createChecked(change))
 | 
				
			||||||
          .database(db)
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					          .check(ChangePermission.READ);
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2659,7 +2659,7 @@ class ReceiveCommits {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        permissions.change(notes).database(db).check(ChangePermission.ADD_PATCH_SET);
 | 
					        permissions.change(notes).check(ChangePermission.ADD_PATCH_SET);
 | 
				
			||||||
      } catch (AuthException no) {
 | 
					      } catch (AuthException no) {
 | 
				
			||||||
        reject(inputCommand, "cannot add patch set to " + ontoChange + ".");
 | 
					        reject(inputCommand, "cannot add patch set to " + ontoChange + ".");
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -316,7 +316,6 @@ public class ReplaceOp implements BatchUpdateOp {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    reviewerAdditions =
 | 
					    reviewerAdditions =
 | 
				
			||||||
        reviewerAdder.prepare(
 | 
					        reviewerAdder.prepare(
 | 
				
			||||||
            ctx.getDb(),
 | 
					 | 
				
			||||||
            ctx.getNotes(),
 | 
					            ctx.getNotes(),
 | 
				
			||||||
            ctx.getUser(),
 | 
					            ctx.getUser(),
 | 
				
			||||||
            getReviewerInputs(magicBranch, fromFooters, ctx.getChange(), info),
 | 
					            getReviewerInputs(magicBranch, fromFooters, ctx.getChange(), info),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -378,11 +378,7 @@ public abstract class ChangeEmail extends NotificationEmail {
 | 
				
			|||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      args.permissionBackend
 | 
					      args.permissionBackend.absentUser(to).change(changeData).check(ChangePermission.READ);
 | 
				
			||||||
          .absentUser(to)
 | 
					 | 
				
			||||||
          .change(changeData)
 | 
					 | 
				
			||||||
          .database(args.db)
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,6 @@ import com.google.gerrit.reviewdb.client.Comment;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Patch;
 | 
					import com.google.gerrit.reviewdb.client.Patch;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
 | 
					import com.google.gerrit.reviewdb.client.Patch.ChangeType;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.CommentsUtil;
 | 
					import com.google.gerrit.server.CommentsUtil;
 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.PatchSetUtil;
 | 
					import com.google.gerrit.server.PatchSetUtil;
 | 
				
			||||||
@@ -82,7 +81,6 @@ public class PatchScriptFactory implements Callable<PatchScript> {
 | 
				
			|||||||
  private final PatchSetUtil psUtil;
 | 
					  private final PatchSetUtil psUtil;
 | 
				
			||||||
  private final Provider<PatchScriptBuilder> builderFactory;
 | 
					  private final Provider<PatchScriptBuilder> builderFactory;
 | 
				
			||||||
  private final PatchListCache patchListCache;
 | 
					  private final PatchListCache patchListCache;
 | 
				
			||||||
  private final ReviewDb db;
 | 
					 | 
				
			||||||
  private final CommentsUtil commentsUtil;
 | 
					  private final CommentsUtil commentsUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private final String fileName;
 | 
					  private final String fileName;
 | 
				
			||||||
@@ -112,7 +110,6 @@ public class PatchScriptFactory implements Callable<PatchScript> {
 | 
				
			|||||||
      PatchSetUtil psUtil,
 | 
					      PatchSetUtil psUtil,
 | 
				
			||||||
      Provider<PatchScriptBuilder> builderFactory,
 | 
					      Provider<PatchScriptBuilder> builderFactory,
 | 
				
			||||||
      PatchListCache patchListCache,
 | 
					      PatchListCache patchListCache,
 | 
				
			||||||
      ReviewDb db,
 | 
					 | 
				
			||||||
      CommentsUtil commentsUtil,
 | 
					      CommentsUtil commentsUtil,
 | 
				
			||||||
      ChangeEditUtil editReader,
 | 
					      ChangeEditUtil editReader,
 | 
				
			||||||
      Provider<CurrentUser> userProvider,
 | 
					      Provider<CurrentUser> userProvider,
 | 
				
			||||||
@@ -127,7 +124,6 @@ public class PatchScriptFactory implements Callable<PatchScript> {
 | 
				
			|||||||
    this.psUtil = psUtil;
 | 
					    this.psUtil = psUtil;
 | 
				
			||||||
    this.builderFactory = builderFactory;
 | 
					    this.builderFactory = builderFactory;
 | 
				
			||||||
    this.patchListCache = patchListCache;
 | 
					    this.patchListCache = patchListCache;
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.notes = notes;
 | 
					    this.notes = notes;
 | 
				
			||||||
    this.commentsUtil = commentsUtil;
 | 
					    this.commentsUtil = commentsUtil;
 | 
				
			||||||
    this.editReader = editReader;
 | 
					    this.editReader = editReader;
 | 
				
			||||||
@@ -150,7 +146,6 @@ public class PatchScriptFactory implements Callable<PatchScript> {
 | 
				
			|||||||
      PatchSetUtil psUtil,
 | 
					      PatchSetUtil psUtil,
 | 
				
			||||||
      Provider<PatchScriptBuilder> builderFactory,
 | 
					      Provider<PatchScriptBuilder> builderFactory,
 | 
				
			||||||
      PatchListCache patchListCache,
 | 
					      PatchListCache patchListCache,
 | 
				
			||||||
      ReviewDb db,
 | 
					 | 
				
			||||||
      CommentsUtil commentsUtil,
 | 
					      CommentsUtil commentsUtil,
 | 
				
			||||||
      ChangeEditUtil editReader,
 | 
					      ChangeEditUtil editReader,
 | 
				
			||||||
      Provider<CurrentUser> userProvider,
 | 
					      Provider<CurrentUser> userProvider,
 | 
				
			||||||
@@ -165,7 +160,6 @@ public class PatchScriptFactory implements Callable<PatchScript> {
 | 
				
			|||||||
    this.psUtil = psUtil;
 | 
					    this.psUtil = psUtil;
 | 
				
			||||||
    this.builderFactory = builderFactory;
 | 
					    this.builderFactory = builderFactory;
 | 
				
			||||||
    this.patchListCache = patchListCache;
 | 
					    this.patchListCache = patchListCache;
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.notes = notes;
 | 
					    this.notes = notes;
 | 
				
			||||||
    this.commentsUtil = commentsUtil;
 | 
					    this.commentsUtil = commentsUtil;
 | 
				
			||||||
    this.editReader = editReader;
 | 
					    this.editReader = editReader;
 | 
				
			||||||
@@ -204,7 +198,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
 | 
				
			|||||||
    PatchSet psEntityB = psb.get() == 0 ? new PatchSet(psb) : psUtil.get(notes, psb);
 | 
					    PatchSet psEntityB = psb.get() == 0 ? new PatchSet(psb) : psUtil.get(notes, psb);
 | 
				
			||||||
    if (psEntityA != null || psEntityB != null) {
 | 
					    if (psEntityA != null || psEntityB != null) {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        permissionBackend.currentUser().change(notes).database(db).check(ChangePermission.READ);
 | 
					        permissionBackend.currentUser().change(notes).check(ChangePermission.READ);
 | 
				
			||||||
      } catch (AuthException e) {
 | 
					      } catch (AuthException e) {
 | 
				
			||||||
        throw new NoSuchChangeException(changeId);
 | 
					        throw new NoSuchChangeException(changeId);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,6 @@ import com.google.gerrit.extensions.restapi.AuthException;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Account;
 | 
					import com.google.gerrit.reviewdb.client.Account;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.notedb.ChangeNotes;
 | 
					import com.google.gerrit.server.notedb.ChangeNotes;
 | 
				
			||||||
import com.google.gerrit.server.permissions.PermissionBackend.ForChange;
 | 
					import com.google.gerrit.server.permissions.PermissionBackend.ForChange;
 | 
				
			||||||
@@ -221,13 +220,6 @@ class ChangeControl {
 | 
				
			|||||||
      this.cd = cd;
 | 
					      this.cd = cd;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private ReviewDb db() {
 | 
					 | 
				
			||||||
      if (db != null) {
 | 
					 | 
				
			||||||
        return db.get();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private ChangeData changeData() {
 | 
					    private ChangeData changeData() {
 | 
				
			||||||
      if (cd == null) {
 | 
					      if (cd == null) {
 | 
				
			||||||
        cd = changeDataFactory.create(notes);
 | 
					        cd = changeDataFactory.create(notes);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,7 +109,7 @@ public class DefaultPermissionBackend extends PermissionBackend {
 | 
				
			|||||||
            PerThreadCache.getOrCompute(
 | 
					            PerThreadCache.getOrCompute(
 | 
				
			||||||
                PerThreadCache.Key.create(ProjectControl.class, project, user.getCacheKey()),
 | 
					                PerThreadCache.Key.create(ProjectControl.class, project, user.getCacheKey()),
 | 
				
			||||||
                () -> projectControlFactory.create(user, state));
 | 
					                () -> projectControlFactory.create(user, state));
 | 
				
			||||||
        return control.asForProject().database(db);
 | 
					        return control.asForProject();
 | 
				
			||||||
      } catch (Exception e) {
 | 
					      } catch (Exception e) {
 | 
				
			||||||
        Throwable cause = e.getCause() != null ? e.getCause() : e;
 | 
					        Throwable cause = e.getCause() != null ? e.getCause() : e;
 | 
				
			||||||
        return FailedPermissionBackend.project(
 | 
					        return FailedPermissionBackend.project(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,6 @@ import com.google.gerrit.reviewdb.client.Branch;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.RefNames;
 | 
					import com.google.gerrit.reviewdb.client.RefNames;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.IdentifiedUser;
 | 
					import com.google.gerrit.server.IdentifiedUser;
 | 
				
			||||||
import com.google.gerrit.server.account.GroupCache;
 | 
					import com.google.gerrit.server.account.GroupCache;
 | 
				
			||||||
@@ -51,7 +50,6 @@ import com.google.gerrit.server.project.ProjectState;
 | 
				
			|||||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
					import com.google.gerrit.server.query.change.ChangeData;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.assistedinject.Assisted;
 | 
					import com.google.inject.assistedinject.Assisted;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
@@ -93,7 +91,6 @@ class DefaultRefFilter {
 | 
				
			|||||||
      TagCache tagCache,
 | 
					      TagCache tagCache,
 | 
				
			||||||
      ChangeNotes.Factory changeNotesFactory,
 | 
					      ChangeNotes.Factory changeNotesFactory,
 | 
				
			||||||
      @Nullable SearchingChangeCacheImpl changeCache,
 | 
					      @Nullable SearchingChangeCacheImpl changeCache,
 | 
				
			||||||
      Provider<ReviewDb> db,
 | 
					 | 
				
			||||||
      GroupCache groupCache,
 | 
					      GroupCache groupCache,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      @GerritServerConfig Config config,
 | 
					      @GerritServerConfig Config config,
 | 
				
			||||||
@@ -111,7 +108,7 @@ class DefaultRefFilter {
 | 
				
			|||||||
    this.user = projectControl.getUser();
 | 
					    this.user = projectControl.getUser();
 | 
				
			||||||
    this.projectState = projectControl.getProjectState();
 | 
					    this.projectState = projectControl.getProjectState();
 | 
				
			||||||
    this.permissionBackendForProject =
 | 
					    this.permissionBackendForProject =
 | 
				
			||||||
        permissionBackend.user(user).database(db).project(projectState.getNameKey());
 | 
					        permissionBackend.user(user).project(projectState.getNameKey());
 | 
				
			||||||
    this.fullFilterCount =
 | 
					    this.fullFilterCount =
 | 
				
			||||||
        metricMaker.newCounter(
 | 
					        metricMaker.newCounter(
 | 
				
			||||||
            "permissions/ref_filter/full_filter_count",
 | 
					            "permissions/ref_filter/full_filter_count",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@ package com.google.gerrit.server.permissions;
 | 
				
			|||||||
import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
 | 
					import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
 | 
				
			||||||
import com.google.gerrit.extensions.conditions.BooleanCondition;
 | 
					import com.google.gerrit.extensions.conditions.BooleanCondition;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.notedb.ChangeNotes;
 | 
					import com.google.gerrit.server.notedb.ChangeNotes;
 | 
				
			||||||
import com.google.gerrit.server.permissions.PermissionBackend.ForChange;
 | 
					import com.google.gerrit.server.permissions.PermissionBackend.ForChange;
 | 
				
			||||||
import com.google.gerrit.server.permissions.PermissionBackend.ForProject;
 | 
					import com.google.gerrit.server.permissions.PermissionBackend.ForProject;
 | 
				
			||||||
@@ -25,7 +24,6 @@ import com.google.gerrit.server.permissions.PermissionBackend.ForRef;
 | 
				
			|||||||
import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
 | 
					import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
 | 
				
			||||||
import com.google.gerrit.server.permissions.PermissionBackend.WithUser;
 | 
					import com.google.gerrit.server.permissions.PermissionBackend.WithUser;
 | 
				
			||||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
					import com.google.gerrit.server.query.change.ChangeData;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
@@ -114,11 +112,6 @@ public class FailedPermissionBackend {
 | 
				
			|||||||
      this.cause = cause;
 | 
					      this.cause = cause;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public ForProject database(Provider<ReviewDb> db) {
 | 
					 | 
				
			||||||
      return this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public String resourcePath() {
 | 
					    public String resourcePath() {
 | 
				
			||||||
      throw new UnsupportedOperationException(
 | 
					      throw new UnsupportedOperationException(
 | 
				
			||||||
@@ -163,11 +156,6 @@ public class FailedPermissionBackend {
 | 
				
			|||||||
      this.cause = cause;
 | 
					      this.cause = cause;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public ForRef database(Provider<ReviewDb> db) {
 | 
					 | 
				
			||||||
      return this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public String resourcePath() {
 | 
					    public String resourcePath() {
 | 
				
			||||||
      throw new UnsupportedOperationException(
 | 
					      throw new UnsupportedOperationException(
 | 
				
			||||||
@@ -216,11 +204,6 @@ public class FailedPermissionBackend {
 | 
				
			|||||||
      this.cause = cause;
 | 
					      this.cause = cause;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public ForChange database(Provider<ReviewDb> db) {
 | 
					 | 
				
			||||||
      return this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public String resourcePath() {
 | 
					    public String resourcePath() {
 | 
				
			||||||
      throw new UnsupportedOperationException(
 | 
					      throw new UnsupportedOperationException(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,14 +29,11 @@ import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Account;
 | 
					import com.google.gerrit.reviewdb.client.Account;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Branch;
 | 
					import com.google.gerrit.reviewdb.client.Branch;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.notedb.ChangeNotes;
 | 
					import com.google.gerrit.server.notedb.ChangeNotes;
 | 
				
			||||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
					import com.google.gerrit.server.query.change.ChangeData;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.ImplementedBy;
 | 
					import com.google.inject.ImplementedBy;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.util.Providers;
 | 
					 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.EnumSet;
 | 
					import java.util.EnumSet;
 | 
				
			||||||
@@ -152,35 +149,14 @@ public abstract class PermissionBackend {
 | 
				
			|||||||
    // delegates to the appropriate testOrFalse method in PermissionBackend.
 | 
					    // delegates to the appropriate testOrFalse method in PermissionBackend.
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** PermissionBackend with an optional per-request ReviewDb handle. */
 | 
					 | 
				
			||||||
  public abstract static class AcceptsReviewDb<T> {
 | 
					 | 
				
			||||||
    protected Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public T database(Provider<ReviewDb> db) {
 | 
					 | 
				
			||||||
      if (db != null) {
 | 
					 | 
				
			||||||
        this.db = db;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return self();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public T database(ReviewDb db) {
 | 
					 | 
				
			||||||
      return database(Providers.of(requireNonNull(db, "ReviewDb")));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @SuppressWarnings("unchecked")
 | 
					 | 
				
			||||||
    private T self() {
 | 
					 | 
				
			||||||
      return (T) this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** PermissionBackend scoped to a specific user. */
 | 
					  /** PermissionBackend scoped to a specific user. */
 | 
				
			||||||
  public abstract static class WithUser extends AcceptsReviewDb<WithUser> {
 | 
					  public abstract static class WithUser {
 | 
				
			||||||
    /** Returns an instance scoped for the specified project. */
 | 
					    /** Returns an instance scoped for the specified project. */
 | 
				
			||||||
    public abstract ForProject project(Project.NameKey project);
 | 
					    public abstract ForProject project(Project.NameKey project);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Returns an instance scoped for the {@code ref}, and its parent project. */
 | 
					    /** Returns an instance scoped for the {@code ref}, and its parent project. */
 | 
				
			||||||
    public ForRef ref(Branch.NameKey ref) {
 | 
					    public ForRef ref(Branch.NameKey ref) {
 | 
				
			||||||
      return project(ref.getParentKey()).ref(ref.get()).database(db);
 | 
					      return project(ref.getParentKey()).ref(ref.get());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Returns an instance scoped for the change, and its destination ref and project. */
 | 
					    /** Returns an instance scoped for the change, and its destination ref and project. */
 | 
				
			||||||
@@ -292,7 +268,7 @@ public abstract class PermissionBackend {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** PermissionBackend scoped to a user and project. */
 | 
					  /** PermissionBackend scoped to a user and project. */
 | 
				
			||||||
  public abstract static class ForProject extends AcceptsReviewDb<ForProject> {
 | 
					  public abstract static class ForProject {
 | 
				
			||||||
    /** Returns the fully qualified resource path that this instance is scoped to. */
 | 
					    /** Returns the fully qualified resource path that this instance is scoped to. */
 | 
				
			||||||
    public abstract String resourcePath();
 | 
					    public abstract String resourcePath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -401,7 +377,7 @@ public abstract class PermissionBackend {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** PermissionBackend scoped to a user, project and reference. */
 | 
					  /** PermissionBackend scoped to a user, project and reference. */
 | 
				
			||||||
  public abstract static class ForRef extends AcceptsReviewDb<ForRef> {
 | 
					  public abstract static class ForRef {
 | 
				
			||||||
    /** Returns a fully qualified resource path that this instance is scoped to. */
 | 
					    /** Returns a fully qualified resource path that this instance is scoped to. */
 | 
				
			||||||
    public abstract String resourcePath();
 | 
					    public abstract String resourcePath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -451,7 +427,7 @@ public abstract class PermissionBackend {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** PermissionBackend scoped to a user, project, reference and change. */
 | 
					  /** PermissionBackend scoped to a user, project, reference and change. */
 | 
				
			||||||
  public abstract static class ForChange extends AcceptsReviewDb<ForChange> {
 | 
					  public abstract static class ForChange {
 | 
				
			||||||
    /** Returns the fully qualified resource path that this instance is scoped to. */
 | 
					    /** Returns the fully qualified resource path that this instance is scoped to. */
 | 
				
			||||||
    public abstract String resourcePath();
 | 
					    public abstract String resourcePath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -343,7 +343,7 @@ class ProjectControl {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public ForRef ref(String ref) {
 | 
					    public ForRef ref(String ref) {
 | 
				
			||||||
      return controlForRef(ref).asForRef().database(db);
 | 
					      return controlForRef(ref).asForRef();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,6 @@ import com.google.gerrit.extensions.restapi.AuthException;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Account;
 | 
					import com.google.gerrit.reviewdb.client.Account;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
					import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.notedb.ChangeNotes;
 | 
					import com.google.gerrit.server.notedb.ChangeNotes;
 | 
				
			||||||
import com.google.gerrit.server.permissions.ChangePermission;
 | 
					import com.google.gerrit.server.permissions.ChangePermission;
 | 
				
			||||||
@@ -29,18 +28,15 @@ import com.google.gerrit.server.permissions.RefPermission;
 | 
				
			|||||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
					import com.google.gerrit.server.query.change.ChangeData;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.Singleton;
 | 
					import com.google.inject.Singleton;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Singleton
 | 
					@Singleton
 | 
				
			||||||
public class RemoveReviewerControl {
 | 
					public class RemoveReviewerControl {
 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
  private final Provider<ReviewDb> dbProvider;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  RemoveReviewerControl(PermissionBackend permissionBackend, Provider<ReviewDb> dbProvider) {
 | 
					  RemoveReviewerControl(PermissionBackend permissionBackend) {
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
    this.dbProvider = dbProvider;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@@ -75,11 +71,7 @@ public class RemoveReviewerControl {
 | 
				
			|||||||
        permissionBackend, cd.change(), currentUser, reviewer, value)) {
 | 
					        permissionBackend, cd.change(), currentUser, reviewer, value)) {
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return permissionBackend
 | 
					    return permissionBackend.user(currentUser).change(cd).test(ChangePermission.REMOVE_REVIEWER);
 | 
				
			||||||
        .user(currentUser)
 | 
					 | 
				
			||||||
        .change(cd)
 | 
					 | 
				
			||||||
        .database(dbProvider)
 | 
					 | 
				
			||||||
        .test(ChangePermission.REMOVE_REVIEWER);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private void checkRemoveReviewer(
 | 
					  private void checkRemoveReviewer(
 | 
				
			||||||
@@ -90,11 +82,7 @@ public class RemoveReviewerControl {
 | 
				
			|||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    permissionBackend
 | 
					    permissionBackend.user(currentUser).change(notes).check(ChangePermission.REMOVE_REVIEWER);
 | 
				
			||||||
        .user(currentUser)
 | 
					 | 
				
			||||||
        .change(notes)
 | 
					 | 
				
			||||||
        .database(dbProvider)
 | 
					 | 
				
			||||||
        .check(ChangePermission.REMOVE_REVIEWER);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private static boolean canRemoveReviewerWithoutPermissionCheck(
 | 
					  private static boolean canRemoveReviewerWithoutPermissionCheck(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -126,7 +126,7 @@ public class AccountPredicates {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  public static Predicate<AccountState> cansee(
 | 
					  public static Predicate<AccountState> cansee(
 | 
				
			||||||
      AccountQueryBuilder.Arguments args, ChangeNotes changeNotes) {
 | 
					      AccountQueryBuilder.Arguments args, ChangeNotes changeNotes) {
 | 
				
			||||||
    return new CanSeeChangePredicate(args.db, args.permissionBackend, changeNotes);
 | 
					    return new CanSeeChangePredicate(args.permissionBackend, changeNotes);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static class AccountPredicate extends IndexPredicate<AccountState>
 | 
					  static class AccountPredicate extends IndexPredicate<AccountState>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -126,11 +126,7 @@ public class AccountQueryBuilder extends QueryBuilder<AccountState> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      args.permissionBackend
 | 
					      args.permissionBackend.user(args.getUser()).change(changeNotes).check(ChangePermission.READ);
 | 
				
			||||||
          .user(args.getUser())
 | 
					 | 
				
			||||||
          .database(args.db)
 | 
					 | 
				
			||||||
          .change(changeNotes)
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      throw error(String.format("change %s not found", change));
 | 
					      throw error(String.format("change %s not found", change));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,24 +16,19 @@ package com.google.gerrit.server.query.account;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import com.google.gerrit.extensions.restapi.AuthException;
 | 
					import com.google.gerrit.extensions.restapi.AuthException;
 | 
				
			||||||
import com.google.gerrit.index.query.PostFilterPredicate;
 | 
					import com.google.gerrit.index.query.PostFilterPredicate;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.account.AccountState;
 | 
					import com.google.gerrit.server.account.AccountState;
 | 
				
			||||||
import com.google.gerrit.server.notedb.ChangeNotes;
 | 
					import com.google.gerrit.server.notedb.ChangeNotes;
 | 
				
			||||||
import com.google.gerrit.server.permissions.ChangePermission;
 | 
					import com.google.gerrit.server.permissions.ChangePermission;
 | 
				
			||||||
import com.google.gerrit.server.permissions.PermissionBackend;
 | 
					import com.google.gerrit.server.permissions.PermissionBackend;
 | 
				
			||||||
import com.google.gerrit.server.permissions.PermissionBackendException;
 | 
					import com.google.gerrit.server.permissions.PermissionBackendException;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class CanSeeChangePredicate extends PostFilterPredicate<AccountState> {
 | 
					public class CanSeeChangePredicate extends PostFilterPredicate<AccountState> {
 | 
				
			||||||
  private final Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
  private final ChangeNotes changeNotes;
 | 
					  private final ChangeNotes changeNotes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CanSeeChangePredicate(
 | 
					  CanSeeChangePredicate(PermissionBackend permissionBackend, ChangeNotes changeNotes) {
 | 
				
			||||||
      Provider<ReviewDb> db, PermissionBackend permissionBackend, ChangeNotes changeNotes) {
 | 
					 | 
				
			||||||
    super(AccountQueryBuilder.FIELD_CAN_SEE, changeNotes.getChangeId().toString());
 | 
					    super(AccountQueryBuilder.FIELD_CAN_SEE, changeNotes.getChangeId().toString());
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
    this.changeNotes = changeNotes;
 | 
					    this.changeNotes = changeNotes;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -43,7 +38,6 @@ public class CanSeeChangePredicate extends PostFilterPredicate<AccountState> {
 | 
				
			|||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend
 | 
				
			||||||
          .absentUser(accountState.getAccount().getId())
 | 
					          .absentUser(accountState.getAccount().getId())
 | 
				
			||||||
          .database(db)
 | 
					 | 
				
			||||||
          .change(changeNotes)
 | 
					          .change(changeNotes)
 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					          .check(ChangePermission.READ);
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,6 @@ import com.google.common.flogger.FluentLogger;
 | 
				
			|||||||
import com.google.gerrit.extensions.restapi.AuthException;
 | 
					import com.google.gerrit.extensions.restapi.AuthException;
 | 
				
			||||||
import com.google.gerrit.index.query.IsVisibleToPredicate;
 | 
					import com.google.gerrit.index.query.IsVisibleToPredicate;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.AnonymousUser;
 | 
					import com.google.gerrit.server.AnonymousUser;
 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.index.IndexUtils;
 | 
					import com.google.gerrit.server.index.IndexUtils;
 | 
				
			||||||
@@ -37,7 +36,6 @@ import org.eclipse.jgit.errors.RepositoryNotFoundException;
 | 
				
			|||||||
public class ChangeIsVisibleToPredicate extends IsVisibleToPredicate<ChangeData> {
 | 
					public class ChangeIsVisibleToPredicate extends IsVisibleToPredicate<ChangeData> {
 | 
				
			||||||
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 | 
					  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected final Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
  protected final ChangeNotes.Factory notesFactory;
 | 
					  protected final ChangeNotes.Factory notesFactory;
 | 
				
			||||||
  protected final CurrentUser user;
 | 
					  protected final CurrentUser user;
 | 
				
			||||||
  protected final PermissionBackend permissionBackend;
 | 
					  protected final PermissionBackend permissionBackend;
 | 
				
			||||||
@@ -46,14 +44,12 @@ public class ChangeIsVisibleToPredicate extends IsVisibleToPredicate<ChangeData>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  public ChangeIsVisibleToPredicate(
 | 
					  public ChangeIsVisibleToPredicate(
 | 
				
			||||||
      Provider<ReviewDb> db,
 | 
					 | 
				
			||||||
      ChangeNotes.Factory notesFactory,
 | 
					      ChangeNotes.Factory notesFactory,
 | 
				
			||||||
      CurrentUser user,
 | 
					      CurrentUser user,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      ProjectCache projectCache,
 | 
					      ProjectCache projectCache,
 | 
				
			||||||
      Provider<AnonymousUser> anonymousUserProvider) {
 | 
					      Provider<AnonymousUser> anonymousUserProvider) {
 | 
				
			||||||
    super(ChangeQueryBuilder.FIELD_VISIBLETO, IndexUtils.describe(user));
 | 
					    super(ChangeQueryBuilder.FIELD_VISIBLETO, IndexUtils.describe(user));
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.notesFactory = notesFactory;
 | 
					    this.notesFactory = notesFactory;
 | 
				
			||||||
    this.user = user;
 | 
					    this.user = user;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
@@ -92,7 +88,7 @@ public class ChangeIsVisibleToPredicate extends IsVisibleToPredicate<ChangeData>
 | 
				
			|||||||
            ? permissionBackend.absentUser(user.getAccountId())
 | 
					            ? permissionBackend.absentUser(user.getAccountId())
 | 
				
			||||||
            : permissionBackend.user(anonymousUserProvider.get());
 | 
					            : permissionBackend.user(anonymousUserProvider.get());
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      withUser.indexedChange(cd, notes).database(db).check(ChangePermission.READ);
 | 
					      withUser.indexedChange(cd, notes).check(ChangePermission.READ);
 | 
				
			||||||
    } catch (PermissionBackendException e) {
 | 
					    } catch (PermissionBackendException e) {
 | 
				
			||||||
      Throwable cause = e.getCause();
 | 
					      Throwable cause = e.getCause();
 | 
				
			||||||
      if (cause instanceof RepositoryNotFoundException) {
 | 
					      if (cause instanceof RepositoryNotFoundException) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -931,7 +931,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  public Predicate<ChangeData> visibleto(CurrentUser user) {
 | 
					  public Predicate<ChangeData> visibleto(CurrentUser user) {
 | 
				
			||||||
    return new ChangeIsVisibleToPredicate(
 | 
					    return new ChangeIsVisibleToPredicate(
 | 
				
			||||||
        args.db,
 | 
					 | 
				
			||||||
        args.notesFactory,
 | 
					        args.notesFactory,
 | 
				
			||||||
        user,
 | 
					        user,
 | 
				
			||||||
        args.permissionBackend,
 | 
					        args.permissionBackend,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,6 @@ import com.google.gerrit.index.query.IndexPredicate;
 | 
				
			|||||||
import com.google.gerrit.index.query.Predicate;
 | 
					import com.google.gerrit.index.query.Predicate;
 | 
				
			||||||
import com.google.gerrit.index.query.QueryProcessor;
 | 
					import com.google.gerrit.index.query.QueryProcessor;
 | 
				
			||||||
import com.google.gerrit.metrics.MetricMaker;
 | 
					import com.google.gerrit.metrics.MetricMaker;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.AnonymousUser;
 | 
					import com.google.gerrit.server.AnonymousUser;
 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.DynamicOptions;
 | 
					import com.google.gerrit.server.DynamicOptions;
 | 
				
			||||||
@@ -66,7 +65,6 @@ public class ChangeQueryProcessor extends QueryProcessor<ChangeData>
 | 
				
			|||||||
    PluginDefinedInfo create(ChangeData a, ChangeQueryProcessor qp, String plugin);
 | 
					    PluginDefinedInfo create(ChangeData a, ChangeQueryProcessor qp, String plugin);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private final Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
  private final Provider<CurrentUser> userProvider;
 | 
					  private final Provider<CurrentUser> userProvider;
 | 
				
			||||||
  private final ChangeNotes.Factory notesFactory;
 | 
					  private final ChangeNotes.Factory notesFactory;
 | 
				
			||||||
  private final DynamicMap<ChangeAttributeFactory> attributeFactories;
 | 
					  private final DynamicMap<ChangeAttributeFactory> attributeFactories;
 | 
				
			||||||
@@ -92,7 +90,6 @@ public class ChangeQueryProcessor extends QueryProcessor<ChangeData>
 | 
				
			|||||||
      IndexConfig indexConfig,
 | 
					      IndexConfig indexConfig,
 | 
				
			||||||
      ChangeIndexCollection indexes,
 | 
					      ChangeIndexCollection indexes,
 | 
				
			||||||
      ChangeIndexRewriter rewriter,
 | 
					      ChangeIndexRewriter rewriter,
 | 
				
			||||||
      Provider<ReviewDb> db,
 | 
					 | 
				
			||||||
      ChangeNotes.Factory notesFactory,
 | 
					      ChangeNotes.Factory notesFactory,
 | 
				
			||||||
      DynamicMap<ChangeAttributeFactory> attributeFactories,
 | 
					      DynamicMap<ChangeAttributeFactory> attributeFactories,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
@@ -106,7 +103,6 @@ public class ChangeQueryProcessor extends QueryProcessor<ChangeData>
 | 
				
			|||||||
        rewriter,
 | 
					        rewriter,
 | 
				
			||||||
        FIELD_LIMIT,
 | 
					        FIELD_LIMIT,
 | 
				
			||||||
        () -> limitsFactory.create(userProvider.get()).getQueryLimit());
 | 
					        () -> limitsFactory.create(userProvider.get()).getQueryLimit());
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.userProvider = userProvider;
 | 
					    this.userProvider = userProvider;
 | 
				
			||||||
    this.notesFactory = notesFactory;
 | 
					    this.notesFactory = notesFactory;
 | 
				
			||||||
    this.attributeFactories = attributeFactories;
 | 
					    this.attributeFactories = attributeFactories;
 | 
				
			||||||
@@ -173,7 +169,6 @@ public class ChangeQueryProcessor extends QueryProcessor<ChangeData>
 | 
				
			|||||||
    return new AndChangeSource(
 | 
					    return new AndChangeSource(
 | 
				
			||||||
        pred,
 | 
					        pred,
 | 
				
			||||||
        new ChangeIsVisibleToPredicate(
 | 
					        new ChangeIsVisibleToPredicate(
 | 
				
			||||||
            db,
 | 
					 | 
				
			||||||
            notesFactory,
 | 
					            notesFactory,
 | 
				
			||||||
            userProvider.get(),
 | 
					            userProvider.get(),
 | 
				
			||||||
            permissionBackend,
 | 
					            permissionBackend,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,6 @@ import com.google.gerrit.reviewdb.client.Account;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
					import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
					import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.IdentifiedUser;
 | 
					import com.google.gerrit.server.IdentifiedUser;
 | 
				
			||||||
import com.google.gerrit.server.index.change.ChangeField;
 | 
					import com.google.gerrit.server.index.change.ChangeField;
 | 
				
			||||||
import com.google.gerrit.server.permissions.ChangePermission;
 | 
					import com.google.gerrit.server.permissions.ChangePermission;
 | 
				
			||||||
@@ -30,14 +29,12 @@ import com.google.gerrit.server.permissions.PermissionBackendException;
 | 
				
			|||||||
import com.google.gerrit.server.project.ProjectCache;
 | 
					import com.google.gerrit.server.project.ProjectCache;
 | 
				
			||||||
import com.google.gerrit.server.project.ProjectState;
 | 
					import com.google.gerrit.server.project.ProjectState;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class EqualsLabelPredicate extends ChangeIndexPredicate {
 | 
					public class EqualsLabelPredicate extends ChangeIndexPredicate {
 | 
				
			||||||
  protected final ProjectCache projectCache;
 | 
					  protected final ProjectCache projectCache;
 | 
				
			||||||
  protected final PermissionBackend permissionBackend;
 | 
					  protected final PermissionBackend permissionBackend;
 | 
				
			||||||
  protected final IdentifiedUser.GenericFactory userFactory;
 | 
					  protected final IdentifiedUser.GenericFactory userFactory;
 | 
				
			||||||
  protected final Provider<ReviewDb> dbProvider;
 | 
					 | 
				
			||||||
  protected final String label;
 | 
					  protected final String label;
 | 
				
			||||||
  protected final int expVal;
 | 
					  protected final int expVal;
 | 
				
			||||||
  protected final Account.Id account;
 | 
					  protected final Account.Id account;
 | 
				
			||||||
@@ -49,7 +46,6 @@ public class EqualsLabelPredicate extends ChangeIndexPredicate {
 | 
				
			|||||||
    this.permissionBackend = args.permissionBackend;
 | 
					    this.permissionBackend = args.permissionBackend;
 | 
				
			||||||
    this.projectCache = args.projectCache;
 | 
					    this.projectCache = args.projectCache;
 | 
				
			||||||
    this.userFactory = args.userFactory;
 | 
					    this.userFactory = args.userFactory;
 | 
				
			||||||
    this.dbProvider = args.dbProvider;
 | 
					 | 
				
			||||||
    this.group = args.group;
 | 
					    this.group = args.group;
 | 
				
			||||||
    this.label = label;
 | 
					    this.label = label;
 | 
				
			||||||
    this.expVal = expVal;
 | 
					    this.expVal = expVal;
 | 
				
			||||||
@@ -123,8 +119,7 @@ public class EqualsLabelPredicate extends ChangeIndexPredicate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Check the user has 'READ' permission.
 | 
					    // Check the user has 'READ' permission.
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      PermissionBackend.ForChange perm =
 | 
					      PermissionBackend.ForChange perm = permissionBackend.absentUser(approver).change(cd);
 | 
				
			||||||
          permissionBackend.absentUser(approver).database(dbProvider).change(cd);
 | 
					 | 
				
			||||||
      ProjectState projectState = projectCache.checkedGet(cd.project());
 | 
					      ProjectState projectState = projectCache.checkedGet(cd.project());
 | 
				
			||||||
      if (projectState == null || !projectState.statePermitsRead()) {
 | 
					      if (projectState == null || !projectState.statePermitsRead()) {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,7 +83,7 @@ public class Abandon extends RetryingRestModifyView<ChangeResource, AbandonInput
 | 
				
			|||||||
    // Not allowed to abandon if the current patch set is locked.
 | 
					    // Not allowed to abandon if the current patch set is locked.
 | 
				
			||||||
    patchSetUtil.checkPatchSetNotLocked(rsrc.getNotes());
 | 
					    patchSetUtil.checkPatchSetNotLocked(rsrc.getNotes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rsrc.permissions().database(dbProvider).check(ChangePermission.ABANDON);
 | 
					    rsrc.permissions().check(ChangePermission.ABANDON);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NotifyHandling notify = input.notify == null ? defaultNotify(rsrc.getChange()) : input.notify;
 | 
					    NotifyHandling notify = input.notify == null ? defaultNotify(rsrc.getChange()) : input.notify;
 | 
				
			||||||
    Change change =
 | 
					    Change change =
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,6 @@ import com.google.gerrit.extensions.restapi.RestView;
 | 
				
			|||||||
import com.google.gerrit.extensions.restapi.TopLevelResource;
 | 
					import com.google.gerrit.extensions.restapi.TopLevelResource;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.change.ChangeFinder;
 | 
					import com.google.gerrit.server.change.ChangeFinder;
 | 
				
			||||||
import com.google.gerrit.server.change.ChangeResource;
 | 
					import com.google.gerrit.server.change.ChangeResource;
 | 
				
			||||||
@@ -44,7 +43,6 @@ import java.util.List;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Singleton
 | 
					@Singleton
 | 
				
			||||||
public class ChangesCollection implements RestCollection<TopLevelResource, ChangeResource> {
 | 
					public class ChangesCollection implements RestCollection<TopLevelResource, ChangeResource> {
 | 
				
			||||||
  private final Provider<ReviewDb> db;
 | 
					 | 
				
			||||||
  private final Provider<CurrentUser> user;
 | 
					  private final Provider<CurrentUser> user;
 | 
				
			||||||
  private final Provider<QueryChanges> queryFactory;
 | 
					  private final Provider<QueryChanges> queryFactory;
 | 
				
			||||||
  private final DynamicMap<RestView<ChangeResource>> views;
 | 
					  private final DynamicMap<RestView<ChangeResource>> views;
 | 
				
			||||||
@@ -55,7 +53,6 @@ public class ChangesCollection implements RestCollection<TopLevelResource, Chang
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  public ChangesCollection(
 | 
					  public ChangesCollection(
 | 
				
			||||||
      Provider<ReviewDb> db,
 | 
					 | 
				
			||||||
      Provider<CurrentUser> user,
 | 
					      Provider<CurrentUser> user,
 | 
				
			||||||
      Provider<QueryChanges> queryFactory,
 | 
					      Provider<QueryChanges> queryFactory,
 | 
				
			||||||
      DynamicMap<RestView<ChangeResource>> views,
 | 
					      DynamicMap<RestView<ChangeResource>> views,
 | 
				
			||||||
@@ -63,7 +60,6 @@ public class ChangesCollection implements RestCollection<TopLevelResource, Chang
 | 
				
			|||||||
      ChangeResource.Factory changeResourceFactory,
 | 
					      ChangeResource.Factory changeResourceFactory,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      ProjectCache projectCache) {
 | 
					      ProjectCache projectCache) {
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.user = user;
 | 
					    this.user = user;
 | 
				
			||||||
    this.queryFactory = queryFactory;
 | 
					    this.queryFactory = queryFactory;
 | 
				
			||||||
    this.views = views;
 | 
					    this.views = views;
 | 
				
			||||||
@@ -129,7 +125,7 @@ public class ChangesCollection implements RestCollection<TopLevelResource, Chang
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  private boolean canRead(ChangeNotes notes) throws PermissionBackendException, IOException {
 | 
					  private boolean canRead(ChangeNotes notes) throws PermissionBackendException, IOException {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend.currentUser().change(notes).database(db).check(ChangePermission.READ);
 | 
					      permissionBackend.currentUser().change(notes).check(ChangePermission.READ);
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -221,7 +221,7 @@ public class CreateChange
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        ChangeNotes change = Iterables.getOnlyElement(notes);
 | 
					        ChangeNotes change = Iterables.getOnlyElement(notes);
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
          permissionBackend.currentUser().change(change).database(db).check(ChangePermission.READ);
 | 
					          permissionBackend.currentUser().change(change).check(ChangePermission.READ);
 | 
				
			||||||
        } catch (AuthException e) {
 | 
					        } catch (AuthException e) {
 | 
				
			||||||
          throw new UnprocessableEntityException("Read not permitted for " + input.baseChange);
 | 
					          throw new UnprocessableEntityException("Read not permitted for " + input.baseChange);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -130,7 +130,7 @@ public class CreateMergePatchSet
 | 
				
			|||||||
    // Not allowed to create a new patch set if the current patch set is locked.
 | 
					    // Not allowed to create a new patch set if the current patch set is locked.
 | 
				
			||||||
    psUtil.checkPatchSetNotLocked(rsrc.getNotes());
 | 
					    psUtil.checkPatchSetNotLocked(rsrc.getNotes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rsrc.permissions().database(db).check(ChangePermission.ADD_PATCH_SET);
 | 
					    rsrc.permissions().check(ChangePermission.ADD_PATCH_SET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ProjectState projectState = projectCache.checkedGet(rsrc.getProject());
 | 
					    ProjectState projectState = projectCache.checkedGet(rsrc.getProject());
 | 
				
			||||||
    projectState.checkStatePermitsWrite();
 | 
					    projectState.checkStatePermitsWrite();
 | 
				
			||||||
@@ -212,7 +212,7 @@ public class CreateMergePatchSet
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    ChangeNotes change = Iterables.getOnlyElement(notes);
 | 
					    ChangeNotes change = Iterables.getOnlyElement(notes);
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend.currentUser().change(change).database(db).check(ChangePermission.READ);
 | 
					      permissionBackend.currentUser().change(change).check(ChangePermission.READ);
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      throw new UnprocessableEntityException("Read not permitted for " + baseChange);
 | 
					      throw new UnprocessableEntityException("Read not permitted for " + baseChange);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,7 @@ public class DeleteChange extends RetryingRestModifyView<ChangeResource, Input,
 | 
				
			|||||||
    if (!isChangeDeletable(rsrc.getChange().getStatus())) {
 | 
					    if (!isChangeDeletable(rsrc.getChange().getStatus())) {
 | 
				
			||||||
      throw new MethodNotAllowedException("delete not permitted");
 | 
					      throw new MethodNotAllowedException("delete not permitted");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    rsrc.permissions().database(db).check(ChangePermission.DELETE);
 | 
					    rsrc.permissions().check(ChangePermission.DELETE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try (BatchUpdate bu =
 | 
					    try (BatchUpdate bu =
 | 
				
			||||||
        updateFactory.create(db.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
 | 
					        updateFactory.create(db.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
 | 
				
			||||||
@@ -74,7 +74,7 @@ public class DeleteChange extends RetryingRestModifyView<ChangeResource, Input,
 | 
				
			|||||||
  @Override
 | 
					  @Override
 | 
				
			||||||
  public UiAction.Description getDescription(ChangeResource rsrc) {
 | 
					  public UiAction.Description getDescription(ChangeResource rsrc) {
 | 
				
			||||||
    Change.Status status = rsrc.getChange().getStatus();
 | 
					    Change.Status status = rsrc.getChange().getStatus();
 | 
				
			||||||
    PermissionBackend.ForChange perm = rsrc.permissions().database(db);
 | 
					    PermissionBackend.ForChange perm = rsrc.permissions();
 | 
				
			||||||
    return new UiAction.Description()
 | 
					    return new UiAction.Description()
 | 
				
			||||||
        .setLabel("Delete")
 | 
					        .setLabel("Delete")
 | 
				
			||||||
        .setTitle("Delete change " + rsrc.getId())
 | 
					        .setTitle("Delete change " + rsrc.getId())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -151,8 +151,8 @@ public class Move extends RetryingRestModifyView<ChangeResource, MoveInput, Chan
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Move requires abandoning this change, and creating a new change.
 | 
					    // Move requires abandoning this change, and creating a new change.
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      rsrc.permissions().database(dbProvider).check(ABANDON);
 | 
					      rsrc.permissions().check(ABANDON);
 | 
				
			||||||
      permissionBackend.user(caller).database(dbProvider).ref(newDest).check(CREATE_CHANGE);
 | 
					      permissionBackend.user(caller).ref(newDest).check(CREATE_CHANGE);
 | 
				
			||||||
    } catch (AuthException denied) {
 | 
					    } catch (AuthException denied) {
 | 
				
			||||||
      throw new AuthException("move not permitted", denied);
 | 
					      throw new AuthException("move not permitted", denied);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -327,6 +327,6 @@ public class Move extends RetryingRestModifyView<ChangeResource, MoveInput, Chan
 | 
				
			|||||||
    return description.setVisible(
 | 
					    return description.setVisible(
 | 
				
			||||||
        and(
 | 
					        and(
 | 
				
			||||||
            permissionBackend.user(rsrc.getUser()).ref(change.getDest()).testCond(CREATE_CHANGE),
 | 
					            permissionBackend.user(rsrc.getUser()).ref(change.getDest()).testCond(CREATE_CHANGE),
 | 
				
			||||||
            rsrc.permissions().database(dbProvider).testCond(ABANDON)));
 | 
					            rsrc.permissions().testCond(ABANDON)));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -280,8 +280,7 @@ public class PostReview
 | 
				
			|||||||
        reviewerInput.notify = NotifyHandling.NONE;
 | 
					        reviewerInput.notify = NotifyHandling.NONE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ReviewerAddition result =
 | 
					        ReviewerAddition result =
 | 
				
			||||||
            reviewerAdder.prepare(
 | 
					            reviewerAdder.prepare(revision.getNotes(), revision.getUser(), reviewerInput, true);
 | 
				
			||||||
                db.get(), revision.getNotes(), revision.getUser(), reviewerInput, true);
 | 
					 | 
				
			||||||
        reviewerJsonResults.put(reviewerInput.reviewer, result.result);
 | 
					        reviewerJsonResults.put(reviewerInput.reviewer, result.result);
 | 
				
			||||||
        if (result.result.error != null) {
 | 
					        if (result.result.error != null) {
 | 
				
			||||||
          hasError = true;
 | 
					          hasError = true;
 | 
				
			||||||
@@ -467,7 +466,7 @@ public class PostReview
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CurrentUser caller = rev.getUser();
 | 
					    CurrentUser caller = rev.getUser();
 | 
				
			||||||
    PermissionBackend.ForChange perm = rev.permissions().database(db);
 | 
					    PermissionBackend.ForChange perm = rev.permissions();
 | 
				
			||||||
    Iterator<Map.Entry<String, Short>> itr = in.labels.entrySet().iterator();
 | 
					    Iterator<Map.Entry<String, Short>> itr = in.labels.entrySet().iterator();
 | 
				
			||||||
    while (itr.hasNext()) {
 | 
					    while (itr.hasNext()) {
 | 
				
			||||||
      Map.Entry<String, Short> ent = itr.next();
 | 
					      Map.Entry<String, Short> ent = itr.next();
 | 
				
			||||||
@@ -499,11 +498,7 @@ public class PostReview
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    IdentifiedUser reviewer = accountResolver.parseOnBehalfOf(caller, in.onBehalfOf);
 | 
					    IdentifiedUser reviewer = accountResolver.parseOnBehalfOf(caller, in.onBehalfOf);
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend.user(reviewer).change(rev.getNotes()).check(ChangePermission.READ);
 | 
				
			||||||
          .user(reviewer)
 | 
					 | 
				
			||||||
          .database(db)
 | 
					 | 
				
			||||||
          .change(rev.getNotes())
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      throw new UnprocessableEntityException(
 | 
					      throw new UnprocessableEntityException(
 | 
				
			||||||
          String.format("on_behalf_of account %s cannot see change", reviewer.getAccountId()));
 | 
					          String.format("on_behalf_of account %s cannot see change", reviewer.getAccountId()));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,8 +68,7 @@ public class PostReviewers
 | 
				
			|||||||
      throw new BadRequestException("missing reviewer field");
 | 
					      throw new BadRequestException("missing reviewer field");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ReviewerAddition addition =
 | 
					    ReviewerAddition addition = reviewerAdder.prepare(rsrc.getNotes(), rsrc.getUser(), input, true);
 | 
				
			||||||
        reviewerAdder.prepare(dbProvider.get(), rsrc.getNotes(), rsrc.getUser(), input, true);
 | 
					 | 
				
			||||||
    if (addition.op == null) {
 | 
					    if (addition.op == null) {
 | 
				
			||||||
      return addition.result;
 | 
					      return addition.result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,7 +96,6 @@ public class PutAssignee extends RetryingRestModifyView<ChangeResource, Assignee
 | 
				
			|||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend
 | 
				
			||||||
          .absentUser(assignee.getAccountId())
 | 
					          .absentUser(assignee.getAccountId())
 | 
				
			||||||
          .database(db)
 | 
					 | 
				
			||||||
          .change(rsrc.getNotes())
 | 
					          .change(rsrc.getNotes())
 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					          .check(ChangePermission.READ);
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
@@ -124,7 +123,7 @@ public class PutAssignee extends RetryingRestModifyView<ChangeResource, Assignee
 | 
				
			|||||||
    reviewerInput.state = ReviewerState.CC;
 | 
					    reviewerInput.state = ReviewerState.CC;
 | 
				
			||||||
    reviewerInput.confirmed = true;
 | 
					    reviewerInput.confirmed = true;
 | 
				
			||||||
    reviewerInput.notify = NotifyHandling.NONE;
 | 
					    reviewerInput.notify = NotifyHandling.NONE;
 | 
				
			||||||
    return reviewerAdder.prepare(db.get(), rsrc.getNotes(), rsrc.getUser(), reviewerInput, false);
 | 
					    return reviewerAdder.prepare(rsrc.getNotes(), rsrc.getUser(), reviewerInput, false);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Override
 | 
					  @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -188,7 +188,6 @@ public class PutMessage
 | 
				
			|||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend
 | 
				
			||||||
          .user(userProvider.get())
 | 
					          .user(userProvider.get())
 | 
				
			||||||
          .database(db.get())
 | 
					 | 
				
			||||||
          .change(changeNotes)
 | 
					          .change(changeNotes)
 | 
				
			||||||
          .check(ChangePermission.ADD_PATCH_SET);
 | 
					          .check(ChangePermission.ADD_PATCH_SET);
 | 
				
			||||||
      projectCache.checkedGet(changeNotes.getProjectName()).checkStatePermitsWrite();
 | 
					      projectCache.checkedGet(changeNotes.getProjectName()).checkStatePermitsWrite();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,7 +109,7 @@ public class Rebase extends RetryingRestModifyView<RevisionResource, RebaseInput
 | 
				
			|||||||
    // Not allowed to rebase if the current patch set is locked.
 | 
					    // Not allowed to rebase if the current patch set is locked.
 | 
				
			||||||
    patchSetUtil.checkPatchSetNotLocked(rsrc.getNotes());
 | 
					    patchSetUtil.checkPatchSetNotLocked(rsrc.getNotes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rsrc.permissions().database(dbProvider).check(ChangePermission.REBASE);
 | 
					    rsrc.permissions().check(ChangePermission.REBASE);
 | 
				
			||||||
    projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite();
 | 
					    projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Change change = rsrc.getChange();
 | 
					    Change change = rsrc.getChange();
 | 
				
			||||||
@@ -169,11 +169,7 @@ public class Rebase extends RetryingRestModifyView<RevisionResource, RebaseInput
 | 
				
			|||||||
      throw new ResourceConflictException("cannot rebase change onto itself");
 | 
					      throw new ResourceConflictException("cannot rebase change onto itself");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    permissionBackend
 | 
					    permissionBackend.user(rsrc.getUser()).change(base.notes()).check(ChangePermission.READ);
 | 
				
			||||||
        .user(rsrc.getUser())
 | 
					 | 
				
			||||||
        .database(dbProvider)
 | 
					 | 
				
			||||||
        .change(base.notes())
 | 
					 | 
				
			||||||
        .check(ChangePermission.READ);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Change baseChange = base.notes().getChange();
 | 
					    Change baseChange = base.notes().getChange();
 | 
				
			||||||
    if (!baseChange.getProject().equals(change.getProject())) {
 | 
					    if (!baseChange.getProject().equals(change.getProject())) {
 | 
				
			||||||
@@ -250,7 +246,7 @@ public class Rebase extends RetryingRestModifyView<RevisionResource, RebaseInput
 | 
				
			|||||||
      return description;
 | 
					      return description;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (rsrc.permissions().database(dbProvider).testOrFalse(ChangePermission.REBASE)) {
 | 
					    if (rsrc.permissions().testOrFalse(ChangePermission.REBASE)) {
 | 
				
			||||||
      return description.setVisible(true).setEnabled(enabled);
 | 
					      return description.setVisible(true).setEnabled(enabled);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return description;
 | 
					    return description;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,6 @@ import com.google.gerrit.extensions.restapi.AuthException;
 | 
				
			|||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.git.GitRepositoryManager;
 | 
					import com.google.gerrit.server.git.GitRepositoryManager;
 | 
				
			||||||
import com.google.gerrit.server.permissions.ChangePermission;
 | 
					import com.google.gerrit.server.permissions.ChangePermission;
 | 
				
			||||||
import com.google.gerrit.server.permissions.PermissionBackend;
 | 
					import com.google.gerrit.server.permissions.PermissionBackend;
 | 
				
			||||||
@@ -38,7 +37,6 @@ import com.google.gerrit.server.project.ProjectState;
 | 
				
			|||||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
					import com.google.gerrit.server.query.change.ChangeData;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.Singleton;
 | 
					import com.google.inject.Singleton;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.ArrayDeque;
 | 
					import java.util.ArrayDeque;
 | 
				
			||||||
@@ -61,18 +59,15 @@ import org.eclipse.jgit.revwalk.RevWalk;
 | 
				
			|||||||
class RelatedChangesSorter {
 | 
					class RelatedChangesSorter {
 | 
				
			||||||
  private final GitRepositoryManager repoManager;
 | 
					  private final GitRepositoryManager repoManager;
 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
  private final Provider<ReviewDb> dbProvider;
 | 
					 | 
				
			||||||
  private final ProjectCache projectCache;
 | 
					  private final ProjectCache projectCache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  RelatedChangesSorter(
 | 
					  RelatedChangesSorter(
 | 
				
			||||||
      GitRepositoryManager repoManager,
 | 
					      GitRepositoryManager repoManager,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      Provider<ReviewDb> dbProvider,
 | 
					 | 
				
			||||||
      ProjectCache projectCache) {
 | 
					      ProjectCache projectCache) {
 | 
				
			||||||
    this.repoManager = repoManager;
 | 
					    this.repoManager = repoManager;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
    this.dbProvider = dbProvider;
 | 
					 | 
				
			||||||
    this.projectCache = projectCache;
 | 
					    this.projectCache = projectCache;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -235,7 +230,7 @@ class RelatedChangesSorter {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private boolean isVisible(PatchSetData psd) throws PermissionBackendException, IOException {
 | 
					  private boolean isVisible(PatchSetData psd) throws PermissionBackendException, IOException {
 | 
				
			||||||
    PermissionBackend.WithUser perm = permissionBackend.currentUser().database(dbProvider);
 | 
					    PermissionBackend.WithUser perm = permissionBackend.currentUser();
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      perm.change(psd.data()).check(ChangePermission.READ);
 | 
					      perm.change(psd.data()).check(ChangePermission.READ);
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,7 +93,7 @@ public class Restore extends RetryingRestModifyView<ChangeResource, RestoreInput
 | 
				
			|||||||
    // Not allowed to restore if the current patch set is locked.
 | 
					    // Not allowed to restore if the current patch set is locked.
 | 
				
			||||||
    psUtil.checkPatchSetNotLocked(rsrc.getNotes());
 | 
					    psUtil.checkPatchSetNotLocked(rsrc.getNotes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rsrc.permissions().database(dbProvider).check(ChangePermission.RESTORE);
 | 
					    rsrc.permissions().check(ChangePermission.RESTORE);
 | 
				
			||||||
    projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite();
 | 
					    projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Op op = new Op(input);
 | 
					    Op op = new Op(input);
 | 
				
			||||||
@@ -192,7 +192,7 @@ public class Restore extends RetryingRestModifyView<ChangeResource, RestoreInput
 | 
				
			|||||||
      return description;
 | 
					      return description;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    boolean visible = rsrc.permissions().database(dbProvider).testOrFalse(ChangePermission.RESTORE);
 | 
					    boolean visible = rsrc.permissions().testOrFalse(ChangePermission.RESTORE);
 | 
				
			||||||
    return description.setVisible(visible);
 | 
					    return description.setVisible(visible);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,6 @@ import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 | 
				
			|||||||
import com.google.gerrit.extensions.restapi.RestView;
 | 
					import com.google.gerrit.extensions.restapi.RestView;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
					import com.google.gerrit.reviewdb.client.PatchSet;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.RevId;
 | 
					import com.google.gerrit.reviewdb.client.RevId;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.PatchSetUtil;
 | 
					import com.google.gerrit.server.PatchSetUtil;
 | 
				
			||||||
import com.google.gerrit.server.change.ChangeResource;
 | 
					import com.google.gerrit.server.change.ChangeResource;
 | 
				
			||||||
import com.google.gerrit.server.change.RevisionResource;
 | 
					import com.google.gerrit.server.change.RevisionResource;
 | 
				
			||||||
@@ -36,7 +35,6 @@ import com.google.gerrit.server.permissions.PermissionBackendException;
 | 
				
			|||||||
import com.google.gerrit.server.project.ProjectCache;
 | 
					import com.google.gerrit.server.project.ProjectCache;
 | 
				
			||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.inject.Inject;
 | 
					import com.google.inject.Inject;
 | 
				
			||||||
import com.google.inject.Provider;
 | 
					 | 
				
			||||||
import com.google.inject.Singleton;
 | 
					import com.google.inject.Singleton;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
@@ -48,7 +46,6 @@ import org.eclipse.jgit.lib.ObjectId;
 | 
				
			|||||||
@Singleton
 | 
					@Singleton
 | 
				
			||||||
public class Revisions implements ChildCollection<ChangeResource, RevisionResource> {
 | 
					public class Revisions implements ChildCollection<ChangeResource, RevisionResource> {
 | 
				
			||||||
  private final DynamicMap<RestView<RevisionResource>> views;
 | 
					  private final DynamicMap<RestView<RevisionResource>> views;
 | 
				
			||||||
  private final Provider<ReviewDb> dbProvider;
 | 
					 | 
				
			||||||
  private final ChangeEditUtil editUtil;
 | 
					  private final ChangeEditUtil editUtil;
 | 
				
			||||||
  private final PatchSetUtil psUtil;
 | 
					  private final PatchSetUtil psUtil;
 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
@@ -57,13 +54,11 @@ public class Revisions implements ChildCollection<ChangeResource, RevisionResour
 | 
				
			|||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  Revisions(
 | 
					  Revisions(
 | 
				
			||||||
      DynamicMap<RestView<RevisionResource>> views,
 | 
					      DynamicMap<RestView<RevisionResource>> views,
 | 
				
			||||||
      Provider<ReviewDb> dbProvider,
 | 
					 | 
				
			||||||
      ChangeEditUtil editUtil,
 | 
					      ChangeEditUtil editUtil,
 | 
				
			||||||
      PatchSetUtil psUtil,
 | 
					      PatchSetUtil psUtil,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
      ProjectCache projectCache) {
 | 
					      ProjectCache projectCache) {
 | 
				
			||||||
    this.views = views;
 | 
					    this.views = views;
 | 
				
			||||||
    this.dbProvider = dbProvider;
 | 
					 | 
				
			||||||
    this.editUtil = editUtil;
 | 
					    this.editUtil = editUtil;
 | 
				
			||||||
    this.psUtil = psUtil;
 | 
					    this.psUtil = psUtil;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
@@ -114,7 +109,6 @@ public class Revisions implements ChildCollection<ChangeResource, RevisionResour
 | 
				
			|||||||
      permissionBackend
 | 
					      permissionBackend
 | 
				
			||||||
          .user(change.getUser())
 | 
					          .user(change.getUser())
 | 
				
			||||||
          .change(change.getNotes())
 | 
					          .change(change.getNotes())
 | 
				
			||||||
          .database(dbProvider)
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					          .check(ChangePermission.READ);
 | 
				
			||||||
      return projectCache.checkedGet(change.getProject()).statePermitsRead();
 | 
					      return projectCache.checkedGet(change.getProject()).statePermitsRead();
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -261,7 +261,6 @@ public class Submit
 | 
				
			|||||||
        Set<ChangePermission> can =
 | 
					        Set<ChangePermission> can =
 | 
				
			||||||
            permissionBackend
 | 
					            permissionBackend
 | 
				
			||||||
                .user(user)
 | 
					                .user(user)
 | 
				
			||||||
                .database(dbProvider)
 | 
					 | 
				
			||||||
                .change(c)
 | 
					                .change(c)
 | 
				
			||||||
                .test(EnumSet.of(ChangePermission.READ, ChangePermission.SUBMIT));
 | 
					                .test(EnumSet.of(ChangePermission.READ, ChangePermission.SUBMIT));
 | 
				
			||||||
        if (!can.contains(ChangePermission.READ)) {
 | 
					        if (!can.contains(ChangePermission.READ)) {
 | 
				
			||||||
@@ -465,18 +464,14 @@ public class Submit
 | 
				
			|||||||
  private IdentifiedUser onBehalfOf(RevisionResource rsrc, SubmitInput in)
 | 
					  private IdentifiedUser onBehalfOf(RevisionResource rsrc, SubmitInput in)
 | 
				
			||||||
      throws AuthException, UnprocessableEntityException, OrmException, PermissionBackendException,
 | 
					      throws AuthException, UnprocessableEntityException, OrmException, PermissionBackendException,
 | 
				
			||||||
          IOException, ConfigInvalidException {
 | 
					          IOException, ConfigInvalidException {
 | 
				
			||||||
    PermissionBackend.ForChange perm = rsrc.permissions().database(dbProvider);
 | 
					    PermissionBackend.ForChange perm = rsrc.permissions();
 | 
				
			||||||
    perm.check(ChangePermission.SUBMIT);
 | 
					    perm.check(ChangePermission.SUBMIT);
 | 
				
			||||||
    perm.check(ChangePermission.SUBMIT_AS);
 | 
					    perm.check(ChangePermission.SUBMIT_AS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CurrentUser caller = rsrc.getUser();
 | 
					    CurrentUser caller = rsrc.getUser();
 | 
				
			||||||
    IdentifiedUser submitter = accountResolver.parseOnBehalfOf(caller, in.onBehalfOf);
 | 
					    IdentifiedUser submitter = accountResolver.parseOnBehalfOf(caller, in.onBehalfOf);
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend
 | 
					      permissionBackend.user(submitter).change(rsrc.getNotes()).check(ChangePermission.READ);
 | 
				
			||||||
          .user(submitter)
 | 
					 | 
				
			||||||
          .database(dbProvider)
 | 
					 | 
				
			||||||
          .change(rsrc.getNotes())
 | 
					 | 
				
			||||||
          .check(ChangePermission.READ);
 | 
					 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      throw new UnprocessableEntityException(
 | 
					      throw new UnprocessableEntityException(
 | 
				
			||||||
          String.format("on_behalf_of account %s cannot see change", submitter.getAccountId()));
 | 
					          String.format("on_behalf_of account %s cannot see change", submitter.getAccountId()));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,7 +90,6 @@ public class SuggestChangeReviewers extends SuggestReviewers
 | 
				
			|||||||
        // already a reviewer.
 | 
					        // already a reviewer.
 | 
				
			||||||
        return permissionBackend
 | 
					        return permissionBackend
 | 
				
			||||||
            .absentUser(account)
 | 
					            .absentUser(account)
 | 
				
			||||||
            .database(dbProvider)
 | 
					 | 
				
			||||||
            .ref(rsrc.getChange().getDest())
 | 
					            .ref(rsrc.getChange().getDest())
 | 
				
			||||||
            .testOrFalse(RefPermission.READ);
 | 
					            .testOrFalse(RefPermission.READ);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -123,7 +123,7 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
 | 
				
			|||||||
      List<RevCommit> visibleCommits = new ArrayList<>();
 | 
					      List<RevCommit> visibleCommits = new ArrayList<>();
 | 
				
			||||||
      List<RevCommit> nonVisibleCommits = new ArrayList<>();
 | 
					      List<RevCommit> nonVisibleCommits = new ArrayList<>();
 | 
				
			||||||
      for (ChangeData cd : bc.get(b)) {
 | 
					      for (ChangeData cd : bc.get(b)) {
 | 
				
			||||||
        boolean visible = isVisible(db, changeSet, cd, user);
 | 
					        boolean visible = isVisible(changeSet, cd, user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (submitType(cd) == SubmitType.CHERRY_PICK) {
 | 
					        if (submitType(cd) == SubmitType.CHERRY_PICK) {
 | 
				
			||||||
          if (visible) {
 | 
					          if (visible) {
 | 
				
			||||||
@@ -181,7 +181,7 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private boolean isVisible(ReviewDb db, ChangeSet changeSet, ChangeData cd, CurrentUser user)
 | 
					  private boolean isVisible(ChangeSet changeSet, ChangeData cd, CurrentUser user)
 | 
				
			||||||
      throws PermissionBackendException, IOException {
 | 
					      throws PermissionBackendException, IOException {
 | 
				
			||||||
    ProjectState projectState = projectCache.checkedGet(cd.project());
 | 
					    ProjectState projectState = projectCache.checkedGet(cd.project());
 | 
				
			||||||
    boolean visible =
 | 
					    boolean visible =
 | 
				
			||||||
@@ -193,7 +193,7 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend.user(user).change(cd).database(db).check(ChangePermission.READ);
 | 
					      permissionBackend.user(user).change(cd).check(ChangePermission.READ);
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      // We thought the change was visible, but it isn't.
 | 
					      // We thought the change was visible, but it isn't.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -110,7 +110,7 @@ public class MergeSuperSet {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (projectState.statePermitsRead()) {
 | 
					        if (projectState.statePermitsRead()) {
 | 
				
			||||||
          try {
 | 
					          try {
 | 
				
			||||||
            permissionBackend.user(user).change(cd).database(db).check(ChangePermission.READ);
 | 
					            permissionBackend.user(user).change(cd).check(ChangePermission.READ);
 | 
				
			||||||
            visible = true;
 | 
					            visible = true;
 | 
				
			||||||
          } catch (AuthException e) {
 | 
					          } catch (AuthException e) {
 | 
				
			||||||
            // Do nothing.
 | 
					            // Do nothing.
 | 
				
			||||||
@@ -147,11 +147,7 @@ public class MergeSuperSet {
 | 
				
			|||||||
   * @return the resulting larger {@link ChangeSet}
 | 
					   * @return the resulting larger {@link ChangeSet}
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  private ChangeSet topicClosure(
 | 
					  private ChangeSet topicClosure(
 | 
				
			||||||
      ReviewDb db,
 | 
					      ChangeSet changeSet, CurrentUser user, Set<String> topicsSeen, Set<String> visibleTopicsSeen)
 | 
				
			||||||
      ChangeSet changeSet,
 | 
					 | 
				
			||||||
      CurrentUser user,
 | 
					 | 
				
			||||||
      Set<String> topicsSeen,
 | 
					 | 
				
			||||||
      Set<String> visibleTopicsSeen)
 | 
					 | 
				
			||||||
      throws OrmException, PermissionBackendException, IOException {
 | 
					      throws OrmException, PermissionBackendException, IOException {
 | 
				
			||||||
    List<ChangeData> visibleChanges = new ArrayList<>();
 | 
					    List<ChangeData> visibleChanges = new ArrayList<>();
 | 
				
			||||||
    List<ChangeData> nonVisibleChanges = new ArrayList<>();
 | 
					    List<ChangeData> nonVisibleChanges = new ArrayList<>();
 | 
				
			||||||
@@ -163,7 +159,7 @@ public class MergeSuperSet {
 | 
				
			|||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      for (ChangeData topicCd : byTopicOpen(topic)) {
 | 
					      for (ChangeData topicCd : byTopicOpen(topic)) {
 | 
				
			||||||
        if (canRead(db, user, topicCd)) {
 | 
					        if (canRead(user, topicCd)) {
 | 
				
			||||||
          visibleChanges.add(topicCd);
 | 
					          visibleChanges.add(topicCd);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          nonVisibleChanges.add(topicCd);
 | 
					          nonVisibleChanges.add(topicCd);
 | 
				
			||||||
@@ -194,7 +190,7 @@ public class MergeSuperSet {
 | 
				
			|||||||
    int oldSeen;
 | 
					    int oldSeen;
 | 
				
			||||||
    int seen;
 | 
					    int seen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    changeSet = topicClosure(db, changeSet, user, topicsSeen, visibleTopicsSeen);
 | 
					    changeSet = topicClosure(changeSet, user, topicsSeen, visibleTopicsSeen);
 | 
				
			||||||
    seen = topicsSeen.size() + visibleTopicsSeen.size();
 | 
					    seen = topicsSeen.size() + visibleTopicsSeen.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
@@ -202,7 +198,7 @@ public class MergeSuperSet {
 | 
				
			|||||||
      try (TraceContext traceContext = PluginContext.newTrace(mergeSuperSetComputation)) {
 | 
					      try (TraceContext traceContext = PluginContext.newTrace(mergeSuperSetComputation)) {
 | 
				
			||||||
        changeSet = mergeSuperSetComputation.get().completeWithoutTopic(db, orm, changeSet, user);
 | 
					        changeSet = mergeSuperSetComputation.get().completeWithoutTopic(db, orm, changeSet, user);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      changeSet = topicClosure(db, changeSet, user, topicsSeen, visibleTopicsSeen);
 | 
					      changeSet = topicClosure(changeSet, user, topicsSeen, visibleTopicsSeen);
 | 
				
			||||||
      seen = topicsSeen.size() + visibleTopicsSeen.size();
 | 
					      seen = topicsSeen.size() + visibleTopicsSeen.size();
 | 
				
			||||||
    } while (seen != oldSeen);
 | 
					    } while (seen != oldSeen);
 | 
				
			||||||
    return changeSet;
 | 
					    return changeSet;
 | 
				
			||||||
@@ -212,7 +208,7 @@ public class MergeSuperSet {
 | 
				
			|||||||
    return queryProvider.get().byTopicOpen(topic);
 | 
					    return queryProvider.get().byTopicOpen(topic);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private boolean canRead(ReviewDb db, CurrentUser user, ChangeData cd)
 | 
					  private boolean canRead(CurrentUser user, ChangeData cd)
 | 
				
			||||||
      throws PermissionBackendException, IOException {
 | 
					      throws PermissionBackendException, IOException {
 | 
				
			||||||
    ProjectState projectState = projectCache.checkedGet(cd.project());
 | 
					    ProjectState projectState = projectCache.checkedGet(cd.project());
 | 
				
			||||||
    if (projectState == null || !projectState.statePermitsRead()) {
 | 
					    if (projectState == null || !projectState.statePermitsRead()) {
 | 
				
			||||||
@@ -220,7 +216,7 @@ public class MergeSuperSet {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      permissionBackend.user(user).change(cd).database(db).check(ChangePermission.READ);
 | 
					      permissionBackend.user(user).change(cd).check(ChangePermission.READ);
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } catch (AuthException e) {
 | 
					    } catch (AuthException e) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,6 @@ import com.google.gerrit.extensions.restapi.AuthException;
 | 
				
			|||||||
import com.google.gerrit.extensions.restapi.RestApiException;
 | 
					import com.google.gerrit.extensions.restapi.RestApiException;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Change;
 | 
					import com.google.gerrit.reviewdb.client.Change;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.change.ChangeFinder;
 | 
					import com.google.gerrit.server.change.ChangeFinder;
 | 
				
			||||||
import com.google.gerrit.server.change.ChangeResource;
 | 
					import com.google.gerrit.server.change.ChangeResource;
 | 
				
			||||||
import com.google.gerrit.server.notedb.ChangeNotes;
 | 
					import com.google.gerrit.server.notedb.ChangeNotes;
 | 
				
			||||||
@@ -40,7 +39,6 @@ import java.util.Map;
 | 
				
			|||||||
public class ChangeArgumentParser {
 | 
					public class ChangeArgumentParser {
 | 
				
			||||||
  private final ChangesCollection changesCollection;
 | 
					  private final ChangesCollection changesCollection;
 | 
				
			||||||
  private final ChangeFinder changeFinder;
 | 
					  private final ChangeFinder changeFinder;
 | 
				
			||||||
  private final ReviewDb db;
 | 
					 | 
				
			||||||
  private final ChangeNotes.Factory changeNotesFactory;
 | 
					  private final ChangeNotes.Factory changeNotesFactory;
 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,12 +46,10 @@ public class ChangeArgumentParser {
 | 
				
			|||||||
  ChangeArgumentParser(
 | 
					  ChangeArgumentParser(
 | 
				
			||||||
      ChangesCollection changesCollection,
 | 
					      ChangesCollection changesCollection,
 | 
				
			||||||
      ChangeFinder changeFinder,
 | 
					      ChangeFinder changeFinder,
 | 
				
			||||||
      ReviewDb db,
 | 
					 | 
				
			||||||
      ChangeNotes.Factory changeNotesFactory,
 | 
					      ChangeNotes.Factory changeNotesFactory,
 | 
				
			||||||
      PermissionBackend permissionBackend) {
 | 
					      PermissionBackend permissionBackend) {
 | 
				
			||||||
    this.changesCollection = changesCollection;
 | 
					    this.changesCollection = changesCollection;
 | 
				
			||||||
    this.changeFinder = changeFinder;
 | 
					    this.changeFinder = changeFinder;
 | 
				
			||||||
    this.db = db;
 | 
					 | 
				
			||||||
    this.changeNotesFactory = changeNotesFactory;
 | 
					    this.changeNotesFactory = changeNotesFactory;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -97,7 +93,7 @@ public class ChangeArgumentParser {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
          permissionBackend.currentUser().change(notes).database(db).check(ChangePermission.READ);
 | 
					          permissionBackend.currentUser().change(notes).check(ChangePermission.READ);
 | 
				
			||||||
          toAdd.add(notes);
 | 
					          toAdd.add(notes);
 | 
				
			||||||
        } catch (AuthException e) {
 | 
					        } catch (AuthException e) {
 | 
				
			||||||
          // Do nothing.
 | 
					          // Do nothing.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user