private void throwIfAdminOnlyParametersAreUsed(UsersSearchRestRequest usersSearchRestRequest) {
if (!userSession.isSystemAdministrator()) {
+ throwIfValuePresent("externalIdentity", usersSearchRestRequest.externalIdentity());
throwIfValuePresent("sonarLintLastConnectionDateFrom", usersSearchRestRequest.sonarLintLastConnectionDateFrom());
throwIfValuePresent("sonarLintLastConnectionDateTo", usersSearchRestRequest.sonarLintLastConnectionDateTo());
throwIfValuePresent("sonarQubeLastConnectionDateFrom", usersSearchRestRequest.sonarQubeLastConnectionDateFrom());
}
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) {
.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())
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
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;
.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")
ArgumentCaptor<UsersSearchRequest> 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
.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