Fix LabelPredicate group matching for included external groups
The same problem fixed for the ownerin and uploaderin predicates in
Change I5cee8556be23 applies to the LabelPredicate when a group arg is
given. Share the approach and code from Change I5cee8556be23 to check if
an internal group includes any external groups.
Change-Id: I6526299e8eb92fbab44869f72889fb1595ae284f
Release-Notes: Fixed label:...,group= for internal groups that include external groups
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index 5b6f044..c090aa0 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -1241,9 +1241,7 @@
public Predicate<ChangeData> ownerin(String group) throws QueryParseException, IOException {
GroupReference g = parseGroup(group);
AccountGroup.UUID groupId = g.getUUID();
- GroupDescription.Basic groupDescription = args.groupBackend.get(groupId);
- if (!(groupDescription instanceof GroupDescription.Internal)
- || containsExternalSubGroups((GroupDescription.Internal) groupDescription)) {
+ if (isOrContainsExternalGroup(args.groupBackend, groupId)) {
return new OwnerinPredicate(args.userFactory, groupId);
}
@@ -1263,9 +1261,7 @@
GroupReference g = parseGroup(group);
AccountGroup.UUID groupId = g.getUUID();
- GroupDescription.Basic groupDescription = args.groupBackend.get(groupId);
- if (!(groupDescription instanceof GroupDescription.Internal)
- || containsExternalSubGroups((GroupDescription.Internal) groupDescription)) {
+ if (isOrContainsExternalGroup(args.groupBackend, groupId)) {
return new UploaderinPredicate(args.userFactory, groupId);
}
@@ -1636,13 +1632,28 @@
return Predicate.and(predicates);
}
- private boolean containsExternalSubGroups(GroupDescription.Internal internalGroup) {
+ protected static boolean isOrContainsExternalGroup(
+ GroupBackend groupBackend, AccountGroup.UUID groupId) {
+ if (groupId != null) {
+ GroupDescription.Basic groupDescription = groupBackend.get(groupId);
+ if (!(groupDescription instanceof GroupDescription.Internal)
+ || containsExternalSubGroups(
+ groupBackend, (GroupDescription.Internal) groupDescription)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected static boolean containsExternalSubGroups(
+ GroupBackend groupBackend, GroupDescription.Internal internalGroup) {
for (AccountGroup.UUID subGroupUuid : internalGroup.getSubgroups()) {
- GroupDescription.Basic subGroupDescription = args.groupBackend.get(subGroupUuid);
+ GroupDescription.Basic subGroupDescription = groupBackend.get(subGroupUuid);
if (!(subGroupDescription instanceof GroupDescription.Internal)) {
return true;
}
- if (containsExternalSubGroups((GroupDescription.Internal) subGroupDescription)) {
+ if (containsExternalSubGroups(
+ groupBackend, (GroupDescription.Internal) subGroupDescription)) {
return true;
}
}
diff --git a/java/com/google/gerrit/server/query/change/LabelPredicate.java b/java/com/google/gerrit/server/query/change/LabelPredicate.java
index cbf5df4..f50cd04 100644
--- a/java/com/google/gerrit/server/query/change/LabelPredicate.java
+++ b/java/com/google/gerrit/server/query/change/LabelPredicate.java
@@ -23,6 +23,7 @@
import com.google.gerrit.index.query.RangeUtil;
import com.google.gerrit.index.query.RangeUtil.Range;
import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.util.LabelVote;
@@ -40,6 +41,7 @@
protected final String value;
protected final Set<Account.Id> accounts;
protected final AccountGroup.UUID group;
+ protected final GroupBackend groupBackend;
protected Args(
ProjectCache projectCache,
@@ -47,13 +49,15 @@
IdentifiedUser.GenericFactory userFactory,
String value,
Set<Account.Id> accounts,
- AccountGroup.UUID group) {
+ AccountGroup.UUID group,
+ GroupBackend groupBackend) {
this.projectCache = projectCache;
this.permissionBackend = permissionBackend;
this.userFactory = userFactory;
this.value = value;
this.accounts = accounts;
this.group = group;
+ this.groupBackend = groupBackend;
}
}
@@ -78,7 +82,14 @@
AccountGroup.UUID group) {
super(
predicates(
- new Args(a.projectCache, a.permissionBackend, a.userFactory, value, accounts, group)));
+ new Args(
+ a.projectCache,
+ a.permissionBackend,
+ a.userFactory,
+ value,
+ accounts,
+ group,
+ a.groupBackend)));
this.value = value;
}
@@ -147,7 +158,7 @@
}
protected static Predicate<ChangeData> equalsLabelPredicate(Args args, String label, int expVal) {
- if (args.group != null && !args.group.isInternalGroup()) {
+ if (ChangeQueryBuilder.isOrContainsExternalGroup(args.groupBackend, args.group)) {
// We can only get members of internal groups and negating an index search that doesn't
// include the external group information leads to incorrect query results. Use a
// PostFilterPredicate in this case instead.
@@ -164,7 +175,7 @@
}
protected static Predicate<ChangeData> magicLabelPredicate(Args args, MagicLabelVote mlv) {
- if (args.group != null && !args.group.isInternalGroup()) {
+ if (ChangeQueryBuilder.isOrContainsExternalGroup(args.groupBackend, args.group)) {
// We can only get members of internal groups and negating an index search that doesn't
// include the external group information leads to incorrect query results. Use a
// PostFilterPredicate in this case instead.
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index 74929ad..bda17da 100644
--- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -1356,12 +1356,25 @@
// create group and add users
AccountGroup.UUID external_group1 = AccountGroup.uuid("testbackend:group1");
AccountGroup.UUID external_group2 = AccountGroup.uuid("testbackend:group2");
+ String nameOfGroupThatContainsExternalGroupAsSubgroup = "test-group-1";
+ String nameOfGroupThatContainsExternalGroupAsSubSubgroup = "test-group-2";
testGroupBackend.create(external_group1);
testGroupBackend.create(external_group2);
testGroupBackend.setMembershipsOf(
user1, new ListGroupMembership(ImmutableList.of(external_group1)));
testGroupBackend.setMembershipsOf(
user2, new ListGroupMembership(ImmutableList.of(external_group2)));
+ AccountGroup.UUID uuidOfGroupThatContainsExternalGroupAsSubgroup =
+ groupOperations
+ .newGroup()
+ .name(nameOfGroupThatContainsExternalGroupAsSubgroup)
+ .addSubgroup(external_group1)
+ .create();
+ groupOperations
+ .newGroup()
+ .name(nameOfGroupThatContainsExternalGroupAsSubSubgroup)
+ .addSubgroup(uuidOfGroupThatContainsExternalGroupAsSubgroup)
+ .create();
Change change1 = insert(repo, newChange(repo), user1);
Change change2 = insert(repo, newChange(repo), user1);
@@ -1380,6 +1393,10 @@
assertQuery("label:Code-Review=+1," + external_group1.get(), change1);
assertQuery("label:Code-Review=+1,group=" + external_group1.get(), change1);
+ assertQuery(
+ "label:Code-Review=+1,group=" + nameOfGroupThatContainsExternalGroupAsSubgroup, change1);
+ assertQuery(
+ "label:Code-Review=+1,group=" + nameOfGroupThatContainsExternalGroupAsSubSubgroup, change1);
assertQuery("label:Code-Review=+1,user=user1", change1);
assertQuery("label:Code-Review=+1,user=user2");
assertQuery("label:Code-Review=+1,group=" + external_group2.get());
@@ -1387,6 +1404,11 @@
// Negated operator tests
assertQuery("-label:Code-Review=+1," + external_group1.get(), change2);
assertQuery("-label:Code-Review=+1,group=" + external_group1.get(), change2);
+ assertQuery(
+ "-label:Code-Review=+1,group=" + nameOfGroupThatContainsExternalGroupAsSubgroup, change2);
+ assertQuery(
+ "-label:Code-Review=+1,group=" + nameOfGroupThatContainsExternalGroupAsSubSubgroup,
+ change2);
assertQuery("-label:Code-Review=+1,user=user1", change2);
assertQuery("-label:Code-Review=+1,group=" + external_group2.get(), change2, change1);
assertQuery("-label:Code-Review=+1,user=user2", change2, change1);