Respect the suggest.skipServiceUsers config when suggesting code owners
By default Gerrit doesn't suggest service users, but this behavior can
be overriden by setting suggest.skipServiceUsers=false in the gerrit
config. When this setting was added the code-owners plugin was not
adapted to respect it. Fix this now.
Bug: Google b/352467354
Change-Id: I234fddf7386979e0848abd911cca9d85281e15fa
Signed-off-by: Edwin Kempin <ekempin@google.com>
Reviewed-on: https://gerrit-review.googlesource.com/c/plugins/code-owners/+/433118
Reviewed-by: Nitzan Gur-Furman <nitzan@google.com>
Tested-by: Zuul <zuul-63@gerritcodereview-ci.iam.gserviceaccount.com>
diff --git a/java/com/google/gerrit/plugins/codeowners/restapi/GetCodeOwnersForPathInChange.java b/java/com/google/gerrit/plugins/codeowners/restapi/GetCodeOwnersForPathInChange.java
index b7149c5..bcd0072 100644
--- a/java/com/google/gerrit/plugins/codeowners/restapi/GetCodeOwnersForPathInChange.java
+++ b/java/com/google/gerrit/plugins/codeowners/restapi/GetCodeOwnersForPathInChange.java
@@ -39,14 +39,17 @@
import com.google.gerrit.server.account.AccountControl;
import com.google.gerrit.server.account.Accounts;
import com.google.gerrit.server.account.ServiceUserClassifier;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.restapi.change.SuggestReviewers;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
+import org.eclipse.jgit.lib.Config;
/**
* REST endpoint that gets the code owners for an arbitrary path in a revision of a change.
@@ -59,10 +62,12 @@
public class GetCodeOwnersForPathInChange
extends AbstractGetCodeOwnersForPath<CodeOwnersInChangeCollection.PathResource> {
+ private final Config cfg;
private final ServiceUserClassifier serviceUserClassifier;
@Inject
GetCodeOwnersForPathInChange(
+ @GerritServerConfig Config cfg,
AccountVisibility accountVisibility,
Accounts accounts,
AccountControl.Factory accountControlFactory,
@@ -87,6 +92,7 @@
codeOwnerResolver,
codeOwnerJsonFactory,
codeOwnerConfigFileJson);
+ this.cfg = cfg;
this.serviceUserClassifier = serviceUserClassifier;
}
@@ -222,6 +228,13 @@
}
private Predicate<CodeOwner> filterOutServiceUsers(ImmutableList.Builder<String> debugLogs) {
+ if (!cfg.getBoolean(
+ "suggest", "skipServiceUsers", SuggestReviewers.DEFAULT_SKIP_SERVICE_USERS)) {
+ // Returning true from the Predicate here means that the code owner should not be filtered
+ // out.
+ return codeOwner -> true;
+ }
+
return codeOwner -> {
if (!isServiceUser(codeOwner)) {
// Returning true from the Predicate here means that the code owner should be kept.
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnersForPathInChangeIT.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnersForPathInChangeIT.java
index a4d69f4..7d60771 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnersForPathInChangeIT.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/GetCodeOwnersForPathInChangeIT.java
@@ -300,6 +300,37 @@
}
@Test
+ @GerritConfig(name = "suggest.skipServiceUsers", value = "false")
+ public void codeOwnersThatAreServiceUsersAreNotFilteredOutIfSkippingServiceUsersIsDisabled()
+ throws Exception {
+ TestAccount serviceUser =
+ accountCreator.create("serviceUser", "service.user@example.com", "Service User", null);
+
+ // Create a code owner config with 2 code owners.
+ codeOwnerConfigOperations
+ .newCodeOwnerConfig()
+ .project(project)
+ .branch("master")
+ .folderPath("/")
+ .addCodeOwnerEmail(admin.email())
+ .addCodeOwnerEmail(serviceUser.email())
+ .create();
+
+ // Make 'serviceUser' a service user.
+ groupOperations
+ .group(groupCache.get(AccountGroup.nameKey("Service Users")).get().getGroupUUID())
+ .forUpdate()
+ .addMember(serviceUser.id())
+ .update();
+
+ // Check that both code owners are suggested, i.e. the service user is not filtered out.
+ assertThat(queryCodeOwners("/foo/bar/baz.md"))
+ .hasCodeOwnersThat()
+ .comparingElementsUsing(hasAccountId())
+ .containsExactly(admin.id(), serviceUser.id());
+ }
+
+ @Test
@GerritConfig(name = "plugin.code-owners.globalCodeOwner", value = "service.user@example.com")
public void globalCodeOwnersThatAreServiceUsersAreFilteredOut() throws Exception {
TestAccount serviceUser =
diff --git a/resources/Documentation/rest-api.md b/resources/Documentation/rest-api.md
index c97ba2c..ace28a0 100644
--- a/resources/Documentation/rest-api.md
+++ b/resources/Documentation/rest-api.md
@@ -742,7 +742,9 @@
The following code owners are filtered out additionally:
-* [service users](#serviceUsers) (members of the `Service Users` group)
+* [service users](#serviceUsers) (members of the `Service Users` group), unless
+ Gerrit is [configured](../../../Documentation/config-gerrit.html#suggest.skipServiceUsers)
+ to not skip service users
* the change owner (since the change owner cannot be added as reviewer)
* code owners that are annotated with
[LAST_RESORT_SUGGESTION](backend-find-owners.html#lastResortSuggestion),