Merge changes I8ec3c7d4,I4b8d69fd
* changes: Don't add users from footers as CC if they can't see the change Add tests for pushing commit with footer of other user
This commit is contained in:
@@ -41,6 +41,7 @@ import com.google.gerrit.acceptance.GitUtil;
|
|||||||
import com.google.gerrit.acceptance.NoHttpd;
|
import com.google.gerrit.acceptance.NoHttpd;
|
||||||
import com.google.gerrit.acceptance.PushOneCommit;
|
import com.google.gerrit.acceptance.PushOneCommit;
|
||||||
import com.google.gerrit.acceptance.TestProjectInput;
|
import com.google.gerrit.acceptance.TestProjectInput;
|
||||||
|
import com.google.gerrit.common.FooterConstants;
|
||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.common.data.Permission;
|
import com.google.gerrit.common.data.Permission;
|
||||||
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
|
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
|
||||||
@@ -611,6 +612,76 @@ public class ChangeIT extends AbstractDaemonTest {
|
|||||||
assertThat(sender.getMessages()).isEmpty();
|
assertThat(sender.getMessages()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pushCommitWithFooterOfOtherUser() throws Exception {
|
||||||
|
// admin pushes commit that references 'user' in a footer
|
||||||
|
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
|
||||||
|
PushOneCommit.SUBJECT + "\n\n"
|
||||||
|
+ FooterConstants.REVIEWED_BY.getName() + ": "
|
||||||
|
+ user.getIdent().toExternalString(),
|
||||||
|
PushOneCommit.FILE_NAME, PushOneCommit.FILE_CONTENT);
|
||||||
|
PushOneCommit.Result result = push.to("refs/for/master");
|
||||||
|
result.assertOkStatus();
|
||||||
|
|
||||||
|
// check that 'user' was added as reviewer
|
||||||
|
ChangeInfo change = gApi.changes().id(result.getChangeId()).get();
|
||||||
|
Collection<AccountInfo> reviewers = change.reviewers.get(REVIEWER);
|
||||||
|
assertThat(reviewers).isNotNull();
|
||||||
|
assertThat(reviewers).hasSize(1);
|
||||||
|
assertThat(reviewers.iterator().next()._accountId)
|
||||||
|
.isEqualTo(user.getId().get());
|
||||||
|
assertThat(change.reviewers.get(CC)).isNull();
|
||||||
|
|
||||||
|
List<Message> messages = sender.getMessages();
|
||||||
|
assertThat(messages).hasSize(1);
|
||||||
|
Message m = messages.get(0);
|
||||||
|
assertThat(m.rcpt()).containsExactly(user.emailAddress);
|
||||||
|
assertThat(m.body()).contains("Hello " + user.fullName + ",\n");
|
||||||
|
assertThat(m.body()).contains("I'd like you to do a code review.");
|
||||||
|
assertThat(m.body())
|
||||||
|
.contains("Change subject: " + PushOneCommit.SUBJECT + "\n");
|
||||||
|
assertMailFrom(m, admin.email);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pushCommitWithFooterOfOtherUserThatCannotSeeChange()
|
||||||
|
throws Exception {
|
||||||
|
// create hidden project that is only visible to administrators
|
||||||
|
Project.NameKey p = createProject("p");
|
||||||
|
ProjectConfig cfg = projectCache.checkedGet(p).getConfig();
|
||||||
|
Util.allow(cfg,
|
||||||
|
Permission.READ, groupCache
|
||||||
|
.get(new AccountGroup.NameKey("Administrators")).getGroupUUID(),
|
||||||
|
"refs/*");
|
||||||
|
Util.block(cfg, Permission.READ, REGISTERED_USERS, "refs/*");
|
||||||
|
saveProjectConfig(p, cfg);
|
||||||
|
|
||||||
|
// admin pushes commit that references 'user' in a footer
|
||||||
|
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
|
||||||
|
PushOneCommit push = pushFactory.create(db, admin.getIdent(), repo,
|
||||||
|
PushOneCommit.SUBJECT + "\n\n" + FooterConstants.REVIEWED_BY.getName()
|
||||||
|
+ ": " + user.getIdent().toExternalString(),
|
||||||
|
PushOneCommit.FILE_NAME, PushOneCommit.FILE_CONTENT);
|
||||||
|
PushOneCommit.Result result = push.to("refs/for/master");
|
||||||
|
result.assertOkStatus();
|
||||||
|
|
||||||
|
// check that 'user' cannot see the change
|
||||||
|
setApiUser(user);
|
||||||
|
try {
|
||||||
|
gApi.changes().id(result.getChangeId()).get();
|
||||||
|
fail("Expected ResourceNotFoundException");
|
||||||
|
} catch (ResourceNotFoundException e) {
|
||||||
|
// Expected.
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that 'user' was NOT added as cc ('user' can't see the change)
|
||||||
|
setApiUser(admin);
|
||||||
|
ChangeInfo change = gApi.changes().id(result.getChangeId()).get();
|
||||||
|
assertThat(change.reviewers.get(REVIEWER)).isNull();
|
||||||
|
assertThat(change.reviewers.get(CC)).isNull();
|
||||||
|
assertThat(sender.getMessages()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addReviewerThatCannotSeeChange() throws Exception {
|
public void addReviewerThatCannotSeeChange() throws Exception {
|
||||||
// create hidden project that is only visible to administrators
|
// create hidden project that is only visible to administrators
|
||||||
|
@@ -19,6 +19,8 @@ import static com.google.common.base.Preconditions.checkState;
|
|||||||
import static com.google.gerrit.reviewdb.client.Change.INITIAL_PATCH_SET_ID;
|
import static com.google.gerrit.reviewdb.client.Change.INITIAL_PATCH_SET_ID;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.google.gerrit.common.FooterConstants;
|
import com.google.gerrit.common.FooterConstants;
|
||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.common.data.LabelTypes;
|
import com.google.gerrit.common.data.LabelTypes;
|
||||||
@@ -34,6 +36,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
|
|||||||
import com.google.gerrit.server.ApprovalsUtil;
|
import com.google.gerrit.server.ApprovalsUtil;
|
||||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||||
import com.google.gerrit.server.ChangeUtil;
|
import com.google.gerrit.server.ChangeUtil;
|
||||||
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.PatchSetUtil;
|
import com.google.gerrit.server.PatchSetUtil;
|
||||||
import com.google.gerrit.server.events.CommitReceivedEvent;
|
import com.google.gerrit.server.events.CommitReceivedEvent;
|
||||||
import com.google.gerrit.server.extensions.events.CommentAdded;
|
import com.google.gerrit.server.extensions.events.CommentAdded;
|
||||||
@@ -48,6 +51,7 @@ import com.google.gerrit.server.git.SendEmailExecutor;
|
|||||||
import com.google.gerrit.server.git.validators.CommitValidationException;
|
import com.google.gerrit.server.git.validators.CommitValidationException;
|
||||||
import com.google.gerrit.server.git.validators.CommitValidators;
|
import com.google.gerrit.server.git.validators.CommitValidators;
|
||||||
import com.google.gerrit.server.mail.CreateChangeSender;
|
import com.google.gerrit.server.mail.CreateChangeSender;
|
||||||
|
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||||
import com.google.gerrit.server.project.ChangeControl;
|
import com.google.gerrit.server.project.ChangeControl;
|
||||||
@@ -86,6 +90,7 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
|
|||||||
LoggerFactory.getLogger(ChangeInserter.class);
|
LoggerFactory.getLogger(ChangeInserter.class);
|
||||||
|
|
||||||
private final ProjectControl.GenericFactory projectControlFactory;
|
private final ProjectControl.GenericFactory projectControlFactory;
|
||||||
|
private final IdentifiedUser.GenericFactory userFactory;
|
||||||
private final ChangeControl.GenericFactory changeControlFactory;
|
private final ChangeControl.GenericFactory changeControlFactory;
|
||||||
private final PatchSetInfoFactory patchSetInfoFactory;
|
private final PatchSetInfoFactory patchSetInfoFactory;
|
||||||
private final PatchSetUtil psUtil;
|
private final PatchSetUtil psUtil;
|
||||||
@@ -128,6 +133,7 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ChangeInserter(ProjectControl.GenericFactory projectControlFactory,
|
ChangeInserter(ProjectControl.GenericFactory projectControlFactory,
|
||||||
|
IdentifiedUser.GenericFactory userFactory,
|
||||||
ChangeControl.GenericFactory changeControlFactory,
|
ChangeControl.GenericFactory changeControlFactory,
|
||||||
PatchSetInfoFactory patchSetInfoFactory,
|
PatchSetInfoFactory patchSetInfoFactory,
|
||||||
PatchSetUtil psUtil,
|
PatchSetUtil psUtil,
|
||||||
@@ -142,6 +148,7 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
|
|||||||
@Assisted RevCommit commit,
|
@Assisted RevCommit commit,
|
||||||
@Assisted String refName) {
|
@Assisted String refName) {
|
||||||
this.projectControlFactory = projectControlFactory;
|
this.projectControlFactory = projectControlFactory;
|
||||||
|
this.userFactory = userFactory;
|
||||||
this.changeControlFactory = changeControlFactory;
|
this.changeControlFactory = changeControlFactory;
|
||||||
this.patchSetInfoFactory = patchSetInfoFactory;
|
this.patchSetInfoFactory = patchSetInfoFactory;
|
||||||
this.psUtil = psUtil;
|
this.psUtil = psUtil;
|
||||||
@@ -353,8 +360,10 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
|
|||||||
update.fixStatus(change.getStatus());
|
update.fixStatus(change.getStatus());
|
||||||
|
|
||||||
LabelTypes labelTypes = ctl.getProjectControl().getLabelTypes();
|
LabelTypes labelTypes = ctl.getProjectControl().getLabelTypes();
|
||||||
approvalsUtil.addReviewers(db, update, labelTypes, change,
|
approvalsUtil.addReviewers(db, update, labelTypes, change, patchSet,
|
||||||
patchSet, patchSetInfo, reviewers, Collections.<Account.Id> emptySet());
|
patchSetInfo,
|
||||||
|
filterOnChangeVisibility(db, ctx.getNotes(), reviewers),
|
||||||
|
Collections.<Account.Id> emptySet());
|
||||||
approvalsUtil.addApprovals(db, update, labelTypes, patchSet,
|
approvalsUtil.addApprovals(db, update, labelTypes, patchSet,
|
||||||
ctx.getControl(), approvals);
|
ctx.getControl(), approvals);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
@@ -368,6 +377,25 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<Account.Id> filterOnChangeVisibility(final ReviewDb db,
|
||||||
|
final ChangeNotes notes, Set<Account.Id> accounts) {
|
||||||
|
return Sets.filter(accounts, new Predicate<Account.Id>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Account.Id accountId) {
|
||||||
|
try {
|
||||||
|
IdentifiedUser user = userFactory.create(accountId);
|
||||||
|
return changeControlFactory.controlFor(notes, user).isVisible(db);
|
||||||
|
} catch (OrmException | NoSuchChangeException e) {
|
||||||
|
log.warn(
|
||||||
|
String.format("Failed to check if account %d can see change %d",
|
||||||
|
accountId.get(), notes.getChangeId().get()),
|
||||||
|
e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postUpdate(Context ctx) throws OrmException, NoSuchChangeException {
|
public void postUpdate(Context ctx) throws OrmException, NoSuchChangeException {
|
||||||
if (sendMail) {
|
if (sendMail) {
|
||||||
|
Reference in New Issue
Block a user