From: Antoine Vigneau Date: Thu, 16 Nov 2023 10:10:17 +0000 (+0100) Subject: SONAR-20944 Add externalIdentity filter in apiv2 GET users endpoint X-Git-Tag: 10.4.0.87286~461 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f6bb53e6c073921fe03718bbc64794be482a3304;p=sonarqube.git SONAR-20944 Add externalIdentity filter in apiv2 GET users endpoint --- diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/controller/DefaultUserController.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/controller/DefaultUserController.java index 485a9cbaf60..b869e40b4b7 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/controller/DefaultUserController.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/controller/DefaultUserController.java @@ -67,6 +67,7 @@ public class DefaultUserController implements UserController { private void throwIfAdminOnlyParametersAreUsed(UsersSearchRestRequest usersSearchRestRequest) { if (!userSession.isSystemAdministrator()) { + throwIfValuePresent("externalIdentity", usersSearchRestRequest.externalIdentity()); throwIfValuePresent("sonarLintLastConnectionDateFrom", usersSearchRestRequest.sonarLintLastConnectionDateFrom()); throwIfValuePresent("sonarLintLastConnectionDateTo", usersSearchRestRequest.sonarLintLastConnectionDateTo()); throwIfValuePresent("sonarQubeLastConnectionDateFrom", usersSearchRestRequest.sonarQubeLastConnectionDateFrom()); @@ -79,7 +80,7 @@ public class DefaultUserController implements UserController { } private static void throwForbiddenFor(String parameterName) { - throw new ForbiddenException("parameter " + parameterName + " requires Administer System permission."); + throw new ForbiddenException("Parameter " + parameterName + " requires Administer System permission."); } private static UsersSearchRequest toUserSearchRequest(UsersSearchRestRequest usersSearchRestRequest, RestPage page) { @@ -87,6 +88,7 @@ public class DefaultUserController implements UserController { .setDeactivated(Optional.ofNullable(usersSearchRestRequest.active()).map(active -> !active).orElse(false)) .setManaged(usersSearchRestRequest.managed()) .setQuery(usersSearchRestRequest.q()) + .setExternalLogin(usersSearchRestRequest.externalIdentity()) .setLastConnectionDateFrom(usersSearchRestRequest.sonarQubeLastConnectionDateFrom()) .setLastConnectionDateTo(usersSearchRestRequest.sonarQubeLastConnectionDateTo()) .setSonarLintLastConnectionDateFrom(usersSearchRestRequest.sonarLintLastConnectionDateFrom()) diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/request/UsersSearchRestRequest.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/request/UsersSearchRestRequest.java index 7c372ee2fb7..7cf37e83c41 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/request/UsersSearchRestRequest.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/request/UsersSearchRestRequest.java @@ -25,30 +25,41 @@ import javax.annotation.Nullable; public record UsersSearchRestRequest( @Schema(defaultValue = "true", description = "Return active/inactive users") Boolean active, + @Nullable @Schema(description = "Return managed or non-managed users. Only available for managed instances, throws for non-managed instances") Boolean managed, + @Nullable @Schema(description = "Filter on login, name and email.\n" + "This parameter can either perform an exact match, or a partial match (contains), it is case insensitive.") String q, + + @Nullable + @Schema(description = "Filter on externalIdentity.\n" + + "This parameter perform a case-sensitive exact match") + String externalIdentity, + @Nullable - @Schema(description = "Filter the users based on the last connection date field. Only users who interacted with this instance at or after the date will be returned. " + @Schema(description = "Filter users based on the last connection date field. Only users who interacted with this instance at or after the date will be returned. " + "The format must be ISO 8601 datetime format (YYYY-MM-DDThh:mm:ss±hhmm)", example = "2020-01-01T00:00:00+0100") String sonarQubeLastConnectionDateFrom, + @Nullable - @Schema(description = "Filter the users based on the last connection date field. Only users that never connected or who interacted with this instance at " + @Schema(description = "Filter users based on the last connection date field. Only users that never connected or who interacted with this instance at " + "or before the date will be returned. The format must be ISO 8601 datetime format (YYYY-MM-DDThh:mm:ss±hhmm)", example = "2020-01-01T00:00:00+0100") String sonarQubeLastConnectionDateTo, + @Nullable - @Schema(description = "Filter the users based on the sonar lint last connection date field Only users who interacted with this instance using SonarLint at or after " + @Schema(description = "Filter users based on the SonarLint last connection date field Only users who interacted with this instance using SonarLint at or after " + "the date will be returned. The format must be ISO 8601 datetime format (YYYY-MM-DDThh:mm:ss±hhmm)", example = "2020-01-01T00:00:00+0100") String sonarLintLastConnectionDateFrom, + @Nullable - @Schema(description = "Filter the users based on the sonar lint last connection date field. Only users that never connected or who interacted with this instance " + @Schema(description = "Filter users based on the SonarLint last connection date field. Only users that never connected or who interacted with this instance " + "using SonarLint at or before the date will be returned. The format must be ISO 8601 datetime format (YYYY-MM-DDThh:mm:ss±hhmm)", example = "2020-01-01T00:00:00+0100") String sonarLintLastConnectionDateTo diff --git a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java index 3c6efc91b4e..0c8ce6ef211 100644 --- a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java +++ b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java @@ -60,6 +60,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.sonar.api.utils.DateUtils.formatDateTime; +import static org.sonar.api.utils.DateUtils.parseOffsetDateTime; import static org.sonar.server.v2.WebApiEndpoints.JSON_MERGE_PATCH_CONTENT_TYPE; import static org.sonar.server.v2.WebApiEndpoints.USER_ENDPOINT; import static org.sonar.server.v2.api.model.RestPage.DEFAULT_PAGE_INDEX; @@ -104,6 +105,7 @@ public class DefaultUserControllerTest { .param("active", "false") .param("managed", "true") .param("q", "q") + .param("externalIdentity", "externalIdentity") .param("sonarQubeLastConnectionDateFrom", "2020-01-01T00:00:00+0100") .param("sonarQubeLastConnectionDateTo", "2020-01-01T00:00:00+0100") .param("sonarLintLastConnectionDateFrom", "2020-01-01T00:00:00+0100") @@ -114,9 +116,17 @@ public class DefaultUserControllerTest { ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(UsersSearchRequest.class); verify(userService).findUsers(requestCaptor.capture()); + + assertThat(requestCaptor.getValue().isDeactivated()).isTrue(); + assertThat(requestCaptor.getValue().isManaged()).isTrue(); + assertThat(requestCaptor.getValue().getQuery()).isEqualTo("q"); + assertThat(requestCaptor.getValue().getExternalLogin()).contains("externalIdentity"); + assertThat(requestCaptor.getValue().getLastConnectionDateFrom()).contains(parseOffsetDateTime("2020-01-01T00:00:00+0100")); + assertThat(requestCaptor.getValue().getLastConnectionDateTo()).contains(parseOffsetDateTime("2020-01-01T00:00:00+0100")); + assertThat(requestCaptor.getValue().getSonarLintLastConnectionDateFrom()).contains(parseOffsetDateTime("2020-01-01T00:00:00+0100")); + assertThat(requestCaptor.getValue().getSonarLintLastConnectionDateTo()).contains(parseOffsetDateTime("2020-01-01T00:00:00+0100")); assertThat(requestCaptor.getValue().getPageSize()).isEqualTo(100); assertThat(requestCaptor.getValue().getPage()).isEqualTo(2); - assertThat(requestCaptor.getValue().isDeactivated()).isTrue(); } @Test @@ -125,25 +135,31 @@ public class DefaultUserControllerTest { .param("sonarQubeLastConnectionDateFrom", "2020-01-01T00:00:00+0100")) .andExpectAll( status().isForbidden(), - content().string("{\"message\":\"parameter sonarQubeLastConnectionDateFrom requires Administer System permission.\"}")); + content().string("{\"message\":\"Parameter sonarQubeLastConnectionDateFrom requires Administer System permission.\"}")); mockMvc.perform(get(USER_ENDPOINT) .param("sonarQubeLastConnectionDateTo", "2020-01-01T00:00:00+0100")) .andExpectAll( status().isForbidden(), - content().string("{\"message\":\"parameter sonarQubeLastConnectionDateTo requires Administer System permission.\"}")); + content().string("{\"message\":\"Parameter sonarQubeLastConnectionDateTo requires Administer System permission.\"}")); mockMvc.perform(get(USER_ENDPOINT) .param("sonarLintLastConnectionDateFrom", "2020-01-01T00:00:00+0100")) .andExpectAll( status().isForbidden(), - content().string("{\"message\":\"parameter sonarLintLastConnectionDateFrom requires Administer System permission.\"}")); + content().string("{\"message\":\"Parameter sonarLintLastConnectionDateFrom requires Administer System permission.\"}")); mockMvc.perform(get(USER_ENDPOINT) .param("sonarLintLastConnectionDateTo", "2020-01-01T00:00:00+0100")) .andExpectAll( status().isForbidden(), - content().string("{\"message\":\"parameter sonarLintLastConnectionDateTo requires Administer System permission.\"}")); + content().string("{\"message\":\"Parameter sonarLintLastConnectionDateTo requires Administer System permission.\"}")); + + mockMvc.perform(get(USER_ENDPOINT) + .param("externalIdentity", "externalIdentity")) + .andExpectAll( + status().isForbidden(), + content().string("{\"message\":\"Parameter externalIdentity requires Administer System permission.\"}")); } @Test