Avoid passing ChangeResource through PostReviewers
The end goal is to make PostReviewers usable from contexts where a ChangeResource is not available, such as ReceiveCommits. After some massaging, it turns out that the ChangeResource was only used for the following reasons, all of which can be avoided: * As a holder of change + user, which saves a bit of boilerplate in passing around to internal methods. This isn't actually necessary, and this refactoring is in general moving away from tying the PostReviewersOp functionality to the REST API. * To use the ChangeNotes within the body of PostReviewersOp; this usage was recently removed. Change-Id: Id9d1ed998677f056aaa9f81488b3c12f82e09e6a
This commit is contained in:
@@ -279,7 +279,8 @@ public class PostReview
|
|||||||
reviewerInput.notify = NotifyHandling.NONE;
|
reviewerInput.notify = NotifyHandling.NONE;
|
||||||
|
|
||||||
PostReviewers.Addition result =
|
PostReviewers.Addition result =
|
||||||
postReviewers.prepareApplication(revision.getChangeResource(), reviewerInput, true);
|
postReviewers.prepareApplication(
|
||||||
|
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;
|
||||||
@@ -379,7 +380,8 @@ public class PostReview
|
|||||||
bu.execute();
|
bu.execute();
|
||||||
|
|
||||||
for (PostReviewers.Addition reviewerResult : reviewerResults) {
|
for (PostReviewers.Addition reviewerResult : reviewerResults) {
|
||||||
reviewerResult.gatherResults();
|
// TODO(dborowitz): Should this be re-read to take updates into account?
|
||||||
|
reviewerResult.gatherResults(revision.getNotes());
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean readyForReview =
|
boolean readyForReview =
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.server.restapi.change;
|
package com.google.gerrit.server.restapi.change;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static com.google.gerrit.extensions.client.ReviewerState.CC;
|
import static com.google.gerrit.extensions.client.ReviewerState.CC;
|
||||||
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
|
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
|
||||||
|
|
||||||
@@ -155,7 +156,7 @@ public class PostReviewers
|
|||||||
throw new BadRequestException("missing reviewer field");
|
throw new BadRequestException("missing reviewer field");
|
||||||
}
|
}
|
||||||
|
|
||||||
Addition addition = prepareApplication(rsrc, input, true);
|
Addition addition = prepareApplication(rsrc.getNotes(), rsrc.getUser(), input, true);
|
||||||
if (addition.op == null) {
|
if (addition.op == null) {
|
||||||
return addition.result;
|
return addition.result;
|
||||||
}
|
}
|
||||||
@@ -165,14 +166,31 @@ public class PostReviewers
|
|||||||
Change.Id id = rsrc.getChange().getId();
|
Change.Id id = rsrc.getChange().getId();
|
||||||
bu.addOp(id, addition.op);
|
bu.addOp(id, addition.op);
|
||||||
bu.execute();
|
bu.execute();
|
||||||
addition.gatherResults();
|
// TODO(dborowitz): Should this be re-read to take updates into account?
|
||||||
|
addition.gatherResults(rsrc.getNotes());
|
||||||
}
|
}
|
||||||
return addition.result;
|
return addition.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare application of a single {@link AddReviewerInput}.
|
||||||
|
*
|
||||||
|
* @param notes change notes.
|
||||||
|
* @param user user performing the reviewer addition.
|
||||||
|
* @param input input describing user or group to add as a reviewer.
|
||||||
|
* @param allowGroup whether to allow
|
||||||
|
* @return handle describing the addition operation. If the {@code op} field is present, this
|
||||||
|
* operation may be added to a {@code BatchUpdate}. Otherwise, the {@code error} field
|
||||||
|
* contains information about an error that occurred
|
||||||
|
* @throws OrmException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws PermissionBackendException
|
||||||
|
* @throws ConfigInvalidException
|
||||||
|
*/
|
||||||
public Addition prepareApplication(
|
public Addition prepareApplication(
|
||||||
ChangeResource rsrc, AddReviewerInput input, boolean allowGroup)
|
ChangeNotes notes, CurrentUser user, AddReviewerInput input, boolean allowGroup)
|
||||||
throws OrmException, IOException, PermissionBackendException, ConfigInvalidException {
|
throws OrmException, IOException, PermissionBackendException, ConfigInvalidException {
|
||||||
|
Branch.NameKey dest = notes.getChange().getDest();
|
||||||
String reviewer = input.reviewer;
|
String reviewer = input.reviewer;
|
||||||
ReviewerState state = input.state();
|
ReviewerState state = input.state();
|
||||||
NotifyHandling notify = input.notify;
|
NotifyHandling notify = input.notify;
|
||||||
@@ -185,17 +203,26 @@ public class PostReviewers
|
|||||||
boolean confirmed = input.confirmed();
|
boolean confirmed = input.confirmed();
|
||||||
boolean allowByEmail =
|
boolean allowByEmail =
|
||||||
projectCache
|
projectCache
|
||||||
.checkedGet(rsrc.getProject())
|
.checkedGet(dest.getParentKey())
|
||||||
.is(BooleanProjectConfig.ENABLE_REVIEWER_BY_EMAIL);
|
.is(BooleanProjectConfig.ENABLE_REVIEWER_BY_EMAIL);
|
||||||
|
|
||||||
Addition byAccountId =
|
Addition byAccountId =
|
||||||
addByAccountId(reviewer, rsrc, state, notify, accountsToNotify, allowGroup, allowByEmail);
|
addByAccountId(
|
||||||
|
reviewer, dest, user, state, notify, accountsToNotify, allowGroup, allowByEmail);
|
||||||
|
|
||||||
Addition wholeGroup = null;
|
Addition wholeGroup = null;
|
||||||
if (byAccountId == null || !byAccountId.exactMatchFound) {
|
if (byAccountId == null || !byAccountId.exactMatchFound) {
|
||||||
wholeGroup =
|
wholeGroup =
|
||||||
addWholeGroup(
|
addWholeGroup(
|
||||||
reviewer, rsrc, state, notify, accountsToNotify, confirmed, allowGroup, allowByEmail);
|
reviewer,
|
||||||
|
dest,
|
||||||
|
user,
|
||||||
|
state,
|
||||||
|
notify,
|
||||||
|
accountsToNotify,
|
||||||
|
confirmed,
|
||||||
|
allowGroup,
|
||||||
|
allowByEmail);
|
||||||
if (wholeGroup != null && wholeGroup.exactMatchFound) {
|
if (wholeGroup != null && wholeGroup.exactMatchFound) {
|
||||||
return wholeGroup;
|
return wholeGroup;
|
||||||
}
|
}
|
||||||
@@ -208,13 +235,13 @@ public class PostReviewers
|
|||||||
return wholeGroup;
|
return wholeGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
return addByEmail(reviewer, rsrc, state, notify, accountsToNotify);
|
return addByEmail(reviewer, notes, user, state, notify, accountsToNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
Addition ccCurrentUser(CurrentUser user, RevisionResource revision) {
|
Addition ccCurrentUser(CurrentUser user, RevisionResource revision) {
|
||||||
return new Addition(
|
return new Addition(
|
||||||
user.getUserName().orElse(null),
|
user.getUserName().orElse(null),
|
||||||
revision.getChangeResource(),
|
revision.getUser(),
|
||||||
ImmutableSet.of(user.getAccountId()),
|
ImmutableSet.of(user.getAccountId()),
|
||||||
null,
|
null,
|
||||||
CC,
|
CC,
|
||||||
@@ -226,7 +253,8 @@ public class PostReviewers
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Addition addByAccountId(
|
private Addition addByAccountId(
|
||||||
String reviewer,
|
String reviewer,
|
||||||
ChangeResource rsrc,
|
Branch.NameKey dest,
|
||||||
|
CurrentUser user,
|
||||||
ReviewerState state,
|
ReviewerState state,
|
||||||
NotifyHandling notify,
|
NotifyHandling notify,
|
||||||
ListMultimap<RecipientType, Account.Id> accountsToNotify,
|
ListMultimap<RecipientType, Account.Id> accountsToNotify,
|
||||||
@@ -251,10 +279,10 @@ public class PostReviewers
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValidReviewer(rsrc.getChange().getDest(), reviewerUser.getAccount())) {
|
if (isValidReviewer(dest, reviewerUser.getAccount())) {
|
||||||
return new Addition(
|
return new Addition(
|
||||||
reviewer,
|
reviewer,
|
||||||
rsrc,
|
user,
|
||||||
ImmutableSet.of(reviewerUser.getAccountId()),
|
ImmutableSet.of(reviewerUser.getAccountId()),
|
||||||
null,
|
null,
|
||||||
state,
|
state,
|
||||||
@@ -275,7 +303,8 @@ public class PostReviewers
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Addition addWholeGroup(
|
private Addition addWholeGroup(
|
||||||
String reviewer,
|
String reviewer,
|
||||||
ChangeResource rsrc,
|
Branch.NameKey dest,
|
||||||
|
CurrentUser user,
|
||||||
ReviewerState state,
|
ReviewerState state,
|
||||||
NotifyHandling notify,
|
NotifyHandling notify,
|
||||||
ListMultimap<RecipientType, Account.Id> accountsToNotify,
|
ListMultimap<RecipientType, Account.Id> accountsToNotify,
|
||||||
@@ -307,7 +336,7 @@ public class PostReviewers
|
|||||||
Set<Account.Id> reviewers = new HashSet<>();
|
Set<Account.Id> reviewers = new HashSet<>();
|
||||||
Set<Account> members;
|
Set<Account> members;
|
||||||
try {
|
try {
|
||||||
members = groupMembers.listAccounts(group.getGroupUUID(), rsrc.getProject());
|
members = groupMembers.listAccounts(group.getGroupUUID(), dest.getParentKey());
|
||||||
} catch (NoSuchProjectException e) {
|
} catch (NoSuchProjectException e) {
|
||||||
return fail(reviewer, e.getMessage());
|
return fail(reviewer, e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -333,18 +362,19 @@ public class PostReviewers
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Account member : members) {
|
for (Account member : members) {
|
||||||
if (isValidReviewer(rsrc.getChange().getDest(), member)) {
|
if (isValidReviewer(dest, member)) {
|
||||||
reviewers.add(member.getId());
|
reviewers.add(member.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Addition(reviewer, rsrc, reviewers, null, state, notify, accountsToNotify, true);
|
return new Addition(reviewer, user, reviewers, null, state, notify, accountsToNotify, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Addition addByEmail(
|
private Addition addByEmail(
|
||||||
String reviewer,
|
String reviewer,
|
||||||
ChangeResource rsrc,
|
ChangeNotes notes,
|
||||||
|
CurrentUser user,
|
||||||
ReviewerState state,
|
ReviewerState state,
|
||||||
NotifyHandling notify,
|
NotifyHandling notify,
|
||||||
ListMultimap<RecipientType, Account.Id> accountsToNotify)
|
ListMultimap<RecipientType, Account.Id> accountsToNotify)
|
||||||
@@ -352,8 +382,8 @@ public class PostReviewers
|
|||||||
try {
|
try {
|
||||||
permissionBackend
|
permissionBackend
|
||||||
.user(anonymousProvider.get())
|
.user(anonymousProvider.get())
|
||||||
.change(rsrc.getNotes())
|
|
||||||
.database(dbProvider)
|
.database(dbProvider)
|
||||||
|
.change(notes)
|
||||||
.check(ChangePermission.READ);
|
.check(ChangePermission.READ);
|
||||||
} catch (AuthException e) {
|
} catch (AuthException e) {
|
||||||
return fail(
|
return fail(
|
||||||
@@ -370,7 +400,7 @@ public class PostReviewers
|
|||||||
return fail(reviewer, MessageFormat.format(ChangeMessages.get().reviewerInvalid, reviewer));
|
return fail(reviewer, MessageFormat.format(ChangeMessages.get().reviewerInvalid, reviewer));
|
||||||
}
|
}
|
||||||
return new Addition(
|
return new Addition(
|
||||||
reviewer, rsrc, null, ImmutableList.of(adr), state, notify, accountsToNotify, true);
|
reviewer, user, null, ImmutableList.of(adr), state, notify, accountsToNotify, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidReviewer(Branch.NameKey branch, Account member)
|
private boolean isValidReviewer(Branch.NameKey branch, Account member)
|
||||||
@@ -379,9 +409,10 @@ public class PostReviewers
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does not account for draft status as a user might want to let a
|
|
||||||
// reviewer see a draft.
|
|
||||||
try {
|
try {
|
||||||
|
// 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
|
||||||
|
// see private changes.
|
||||||
permissionBackend
|
permissionBackend
|
||||||
.absentUser(member.getId())
|
.absentUser(member.getId())
|
||||||
.database(dbProvider)
|
.database(dbProvider)
|
||||||
@@ -405,13 +436,12 @@ public class PostReviewers
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Addition {
|
public class Addition {
|
||||||
final AddReviewerResult result;
|
public final AddReviewerResult result;
|
||||||
final PostReviewersOp op;
|
@Nullable public final PostReviewersOp op;
|
||||||
final Set<Account.Id> reviewers;
|
final Set<Account.Id> reviewers;
|
||||||
final Collection<Address> reviewersByEmail;
|
final Collection<Address> reviewersByEmail;
|
||||||
final ReviewerState state;
|
final ReviewerState state;
|
||||||
final ChangeNotes notes;
|
@Nullable final IdentifiedUser caller;
|
||||||
final IdentifiedUser caller;
|
|
||||||
final boolean exactMatchFound;
|
final boolean exactMatchFound;
|
||||||
|
|
||||||
Addition(String reviewer) {
|
Addition(String reviewer) {
|
||||||
@@ -420,14 +450,13 @@ public class PostReviewers
|
|||||||
reviewers = ImmutableSet.of();
|
reviewers = ImmutableSet.of();
|
||||||
reviewersByEmail = ImmutableSet.of();
|
reviewersByEmail = ImmutableSet.of();
|
||||||
state = REVIEWER;
|
state = REVIEWER;
|
||||||
notes = null;
|
|
||||||
caller = null;
|
caller = null;
|
||||||
exactMatchFound = false;
|
exactMatchFound = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Addition(
|
Addition(
|
||||||
String reviewer,
|
String reviewer,
|
||||||
ChangeResource rsrc,
|
CurrentUser caller,
|
||||||
@Nullable Set<Account.Id> reviewers,
|
@Nullable Set<Account.Id> reviewers,
|
||||||
@Nullable Collection<Address> reviewersByEmail,
|
@Nullable Collection<Address> reviewersByEmail,
|
||||||
ReviewerState state,
|
ReviewerState state,
|
||||||
@@ -442,20 +471,16 @@ public class PostReviewers
|
|||||||
this.reviewers = reviewers == null ? ImmutableSet.of() : reviewers;
|
this.reviewers = reviewers == null ? ImmutableSet.of() : reviewers;
|
||||||
this.reviewersByEmail = reviewersByEmail == null ? ImmutableList.of() : reviewersByEmail;
|
this.reviewersByEmail = reviewersByEmail == null ? ImmutableList.of() : reviewersByEmail;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
notes = rsrc.getNotes();
|
this.caller = caller.asIdentifiedUser();
|
||||||
caller = rsrc.getUser().asIdentifiedUser();
|
|
||||||
op =
|
op =
|
||||||
postReviewersOpFactory.create(
|
postReviewersOpFactory.create(
|
||||||
this.reviewers, this.reviewersByEmail, state, notify, accountsToNotify);
|
this.reviewers, this.reviewersByEmail, state, notify, accountsToNotify);
|
||||||
this.exactMatchFound = exactMatchFound;
|
this.exactMatchFound = exactMatchFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gatherResults() throws OrmException, PermissionBackendException {
|
void gatherResults(ChangeNotes notes) throws OrmException, PermissionBackendException {
|
||||||
if (notes == null || caller == null) {
|
checkState(op != null, "addition did not result in an update op");
|
||||||
// When notes or caller is missing this is likely just carrying an error message
|
checkState(op.getResult() != null, "op did not return a result");
|
||||||
// in the contained AddReviewerResult.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChangeData cd = changeDataFactory.create(dbProvider.get(), notes);
|
ChangeData cd = changeDataFactory.create(dbProvider.get(), notes);
|
||||||
// Generate result details and fill AccountLoader. This occurs outside
|
// Generate result details and fill AccountLoader. This occurs outside
|
||||||
|
|||||||
@@ -123,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 postReviewers.prepareApplication(rsrc, reviewerInput, false);
|
return postReviewers.prepareApplication(rsrc.getNotes(), rsrc.getUser(), reviewerInput, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user