@@ -31,6 +31,9 @@ import org.sonar.server.common.user.service.UserSearchResult; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonar.server.v2.api.response.PageRestResponse; | |||
import org.sonar.server.v2.api.user.model.RestUser; | |||
import org.sonar.server.v2.api.user.model.RestUserForAdmins; | |||
import org.sonar.server.v2.api.user.model.RestUserForAnonymousUsers; | |||
import org.sonar.server.v2.api.user.model.RestUserForLoggedInUsers; | |||
import org.sonar.server.v2.api.user.response.UsersSearchRestResponse; | |||
public class UsersSearchRestResponseGenerator implements UsersSearchResponseGenerator<UsersSearchRestResponse> { | |||
@@ -72,13 +75,14 @@ public class UsersSearchRestResponseGenerator implements UsersSearchResponseGene | |||
Integer tokensCount = null; | |||
List<String> scmAccounts = null; | |||
if (userSession.isLoggedIn()) { | |||
avatar = userSearchResult.avatar().orElse(null); | |||
active = userDto.isActive(); | |||
local = userDto.isLocal(); | |||
email = userDto.getEmail(); | |||
externalIdentityProvider = userDto.getExternalIdentityProvider(); | |||
if (!userSession.isLoggedIn()) { | |||
return new RestUserForAnonymousUsers(login, login, name); | |||
} | |||
avatar = userSearchResult.avatar().orElse(null); | |||
active = userDto.isActive(); | |||
local = userDto.isLocal(); | |||
email = userDto.getEmail(); | |||
externalIdentityProvider = userDto.getExternalIdentityProvider(); | |||
if (userSession.isSystemAdministrator() || Objects.equals(userSession.getUuid(), userDto.getUuid())) { | |||
externalLogin = userDto.getExternalLogin(); | |||
managed = userSearchResult.managed(); | |||
@@ -87,24 +91,24 @@ public class UsersSearchRestResponseGenerator implements UsersSearchResponseGene | |||
groupSize = userSearchResult.groups().size(); | |||
tokensCount = userSearchResult.tokensCount(); | |||
scmAccounts = userSearchResult.userDto().getSortedScmAccounts(); | |||
return new RestUserForAdmins( | |||
login, | |||
login, | |||
name, | |||
email, | |||
active, | |||
local, | |||
managed, | |||
externalLogin, | |||
externalIdentityProvider, | |||
avatar, | |||
sqLastConnectionDate, | |||
slLastConnectionDate, | |||
groupSize, | |||
tokensCount, | |||
scmAccounts); | |||
} | |||
return new RestUser( | |||
login, | |||
login, | |||
name, | |||
email, | |||
active, | |||
local, | |||
managed, | |||
externalLogin, | |||
externalIdentityProvider, | |||
avatar, | |||
sqLastConnectionDate, | |||
slLastConnectionDate, | |||
groupSize, | |||
tokensCount, | |||
scmAccounts); | |||
return new RestUserForLoggedInUsers(login, login, name, email, active, local, externalIdentityProvider, avatar); | |||
} | |||
private static String toDateTime(@Nullable Long dateTimeMs) { |
@@ -19,36 +19,5 @@ | |||
*/ | |||
package org.sonar.server.v2.api.user.model; | |||
import java.util.List; | |||
import javax.annotation.Nullable; | |||
public record RestUser( | |||
String id, | |||
String login, | |||
String name, | |||
@Nullable | |||
String email, | |||
@Nullable | |||
Boolean active, | |||
@Nullable | |||
Boolean local, | |||
@Nullable | |||
Boolean managed, | |||
@Nullable | |||
String externalLogin, | |||
@Nullable | |||
String externalProvider, | |||
@Nullable | |||
String avatar, | |||
@Nullable | |||
String sonarQubeLastConnectionDate, | |||
@Nullable | |||
String sonarLintLastConnectionDate, | |||
@Nullable | |||
Integer groupsCount, | |||
@Nullable | |||
Integer tokensCount, | |||
@Nullable | |||
List<String> scmAccounts | |||
) { | |||
public interface RestUser { | |||
} |
@@ -0,0 +1,54 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2023 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.v2.api.user.model; | |||
import java.util.List; | |||
import javax.annotation.Nullable; | |||
public record RestUserForAdmins( | |||
String id, | |||
String login, | |||
String name, | |||
@Nullable | |||
String email, | |||
@Nullable | |||
Boolean active, | |||
@Nullable | |||
Boolean local, | |||
@Nullable | |||
Boolean managed, | |||
@Nullable | |||
String externalLogin, | |||
@Nullable | |||
String externalProvider, | |||
@Nullable | |||
String avatar, | |||
@Nullable | |||
String sonarQubeLastConnectionDate, | |||
@Nullable | |||
String sonarLintLastConnectionDate, | |||
@Nullable | |||
Integer groupsCount, | |||
@Nullable | |||
Integer tokensCount, | |||
@Nullable | |||
List<String> scmAccounts | |||
) implements RestUser { | |||
} |
@@ -0,0 +1,28 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2023 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.v2.api.user.model; | |||
public record RestUserForAnonymousUsers( | |||
String id, | |||
String login, | |||
String name | |||
) implements RestUser { | |||
} |
@@ -0,0 +1,40 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2023 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.v2.api.user.model; | |||
import javax.annotation.Nullable; | |||
public record RestUserForLoggedInUsers( | |||
String id, | |||
String login, | |||
String name, | |||
@Nullable | |||
String email, | |||
@Nullable | |||
Boolean active, | |||
@Nullable | |||
Boolean local, | |||
@Nullable | |||
String externalProvider, | |||
@Nullable | |||
String avatar | |||
) implements RestUser { | |||
} |
@@ -39,6 +39,7 @@ import org.sonar.server.v2.api.ControllerTester; | |||
import org.sonar.server.v2.api.response.PageRestResponse; | |||
import org.sonar.server.v2.api.user.converter.UsersSearchRestResponseGenerator; | |||
import org.sonar.server.v2.api.user.model.RestUser; | |||
import org.sonar.server.v2.api.user.model.RestUserForAdmins; | |||
import org.sonar.server.v2.api.user.request.UserCreateRestRequest; | |||
import org.sonar.server.v2.api.user.response.UsersSearchRestResponse; | |||
import org.springframework.http.MediaType; | |||
@@ -146,8 +147,8 @@ public class DefaultUserControllerTest { | |||
List<UserSearchResult> users = List.of(user1, user2, user3, user4); | |||
SearchResults<UserSearchResult> searchResult = new SearchResults<>(users, users.size()); | |||
when(userService.findUsers(any())).thenReturn(searchResult); | |||
List<RestUser> restUsers = List.of(toRestUser(user1), toRestUser(user2), toRestUser(user3), toRestUser(user4)); | |||
when(responseGenerator.toUsersForResponse(eq(searchResult.searchResults()), any())).thenReturn(new UsersSearchRestResponse(restUsers, new PageRestResponse(1, 50, 4))); | |||
List<RestUser> restUserForAdmins = List.of(toRestUser(user1), toRestUser(user2), toRestUser(user3), toRestUser(user4)); | |||
when(responseGenerator.toUsersForResponse(eq(searchResult.searchResults()), any())).thenReturn(new UsersSearchRestResponse(restUserForAdmins, new PageRestResponse(1, 50, 4))); | |||
userSession.logIn().setSystemAdministrator(); | |||
MvcResult mvcResult = mockMvc.perform(get(USER_ENDPOINT)) | |||
@@ -156,7 +157,7 @@ public class DefaultUserControllerTest { | |||
UsersSearchRestResponse actualUsersSearchRestResponse = gson.fromJson(mvcResult.getResponse().getContentAsString(), UsersSearchRestResponse.class); | |||
assertThat(actualUsersSearchRestResponse.users()) | |||
.containsExactlyElementsOf(restUsers); | |||
.containsExactlyElementsOf(restUserForAdmins); | |||
assertThat(actualUsersSearchRestResponse.page().total()).isEqualTo(users.size()); | |||
} | |||
@@ -181,8 +182,8 @@ public class DefaultUserControllerTest { | |||
return new UserSearchResult(userDto, managed, Optional.of("avatar_" + id), groups, tokensCount); | |||
} | |||
private RestUser toRestUser(UserSearchResult userSearchResult) { | |||
return new RestUser( | |||
private RestUserForAdmins toRestUser(UserSearchResult userSearchResult) { | |||
return new RestUserForAdmins( | |||
userSearchResult.userDto().getLogin(), | |||
userSearchResult.userDto().getLogin(), | |||
userSearchResult.userDto().getName(), | |||
@@ -295,14 +296,14 @@ public class DefaultUserControllerTest { | |||
@Test | |||
public void fetchUser_whenUserExists_shouldReturnUser() throws Exception { | |||
UserSearchResult user = generateUserSearchResult("user1", true, true, false, 2, 3); | |||
RestUser restUser = toRestUser(user); | |||
RestUserForAdmins restUserForAdmins = toRestUser(user); | |||
when(userService.fetchUser("userLogin")).thenReturn(user); | |||
when(responseGenerator.toRestUser(user)).thenReturn(restUser); | |||
when(responseGenerator.toRestUser(user)).thenReturn(restUserForAdmins); | |||
MvcResult mvcResult = mockMvc.perform(get(USER_ENDPOINT + "/userLogin")) | |||
.andExpect(status().isOk()) | |||
.andReturn(); | |||
RestUser responseUser = gson.fromJson(mvcResult.getResponse().getContentAsString(), RestUser.class); | |||
assertThat(responseUser).isEqualTo(restUser); | |||
RestUserForAdmins responseUser = gson.fromJson(mvcResult.getResponse().getContentAsString(), RestUserForAdmins.class); | |||
assertThat(responseUser).isEqualTo(restUserForAdmins); | |||
} | |||
@Test | |||
@@ -373,7 +374,7 @@ public class DefaultUserControllerTest { | |||
userDto.getEmail(), userDto.isLocal(), userDto.getLogin(), userDto.getName(), "password", userDto.getSortedScmAccounts())))) | |||
.andExpect(status().isOk()) | |||
.andReturn(); | |||
RestUser responseUser = gson.fromJson(mvcResult.getResponse().getContentAsString(), RestUser.class); | |||
RestUserForAdmins responseUser = gson.fromJson(mvcResult.getResponse().getContentAsString(), RestUserForAdmins.class); | |||
assertThat(responseUser).isEqualTo(toRestUser(userSearchResult)); | |||
} | |||
@@ -33,7 +33,9 @@ import org.sonar.db.user.UserDto; | |||
import org.sonar.server.common.user.service.UserSearchResult; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonar.server.v2.api.response.PageRestResponse; | |||
import org.sonar.server.v2.api.user.model.RestUser; | |||
import org.sonar.server.v2.api.user.model.RestUserForAdmins; | |||
import org.sonar.server.v2.api.user.model.RestUserForAnonymousUsers; | |||
import org.sonar.server.v2.api.user.model.RestUserForLoggedInUsers; | |||
import org.sonar.server.v2.api.user.response.UsersSearchRestResponse; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -72,15 +74,15 @@ public class UsersSearchRestResponseGeneratorTest { | |||
UsersSearchRestResponse usersForResponse = usersSearchRestResponseGenerator.toUsersForResponse(List.of(userSearchResult1, userSearchResult2), paging); | |||
RestUser expectUser1 = buildExpectedResponseForAdmin(userSearchResult1); | |||
RestUser expectUser2 = buildExpectedResponseForAdmin(userSearchResult2); | |||
RestUserForAdmins expectUser1 = buildExpectedResponseForAdmin(userSearchResult1); | |||
RestUserForAdmins expectUser2 = buildExpectedResponseForAdmin(userSearchResult2); | |||
assertThat(usersForResponse.users()).containsExactly(expectUser1, expectUser2); | |||
assertPaginationInformationAreCorrect(paging, usersForResponse.page()); | |||
} | |||
private static RestUser buildExpectedResponseForAdmin(UserSearchResult userSearchResult) { | |||
private static RestUserForAdmins buildExpectedResponseForAdmin(UserSearchResult userSearchResult) { | |||
UserDto userDto = userSearchResult.userDto(); | |||
return new RestUser( | |||
return new RestUserForAdmins( | |||
userDto.getLogin(), | |||
userDto.getLogin(), | |||
userDto.getName(), | |||
@@ -110,30 +112,23 @@ public class UsersSearchRestResponseGeneratorTest { | |||
UsersSearchRestResponse usersForResponse = usersSearchRestResponseGenerator.toUsersForResponse(List.of(userSearchResult1, userSearchResult2), paging); | |||
RestUser expectUser1 = buildExpectedResponseForUser(userSearchResult1); | |||
RestUser expectUser2 = buildExpectedResponseForUser(userSearchResult2); | |||
RestUserForLoggedInUsers expectUser1 = buildExpectedResponseForUser(userSearchResult1); | |||
RestUserForLoggedInUsers expectUser2 = buildExpectedResponseForUser(userSearchResult2); | |||
assertThat(usersForResponse.users()).containsExactly(expectUser1, expectUser2); | |||
assertPaginationInformationAreCorrect(paging, usersForResponse.page()); | |||
} | |||
private static RestUser buildExpectedResponseForUser(UserSearchResult userSearchResult) { | |||
private static RestUserForLoggedInUsers buildExpectedResponseForUser(UserSearchResult userSearchResult) { | |||
UserDto userDto = userSearchResult.userDto(); | |||
return new RestUser( | |||
return new RestUserForLoggedInUsers( | |||
userDto.getLogin(), | |||
userDto.getLogin(), | |||
userDto.getName(), | |||
userDto.getEmail(), | |||
userDto.isActive(), | |||
userDto.isLocal(), | |||
null, | |||
null, | |||
userDto.getExternalIdentityProvider(), | |||
userSearchResult.avatar().orElse(null), | |||
null, | |||
null, | |||
null, | |||
null, | |||
null | |||
userSearchResult.avatar().orElse(null) | |||
); | |||
} | |||
@@ -146,30 +141,18 @@ public class UsersSearchRestResponseGeneratorTest { | |||
UsersSearchRestResponse usersForResponse = usersSearchRestResponseGenerator.toUsersForResponse(List.of(userSearchResult1, userSearchResult2), paging); | |||
RestUser expectUser1 = buildExpectedResponseForAnonymous(userSearchResult1); | |||
RestUser expectUser2 = buildExpectedResponseForAnonymous(userSearchResult2); | |||
RestUserForAnonymousUsers expectUser1 = buildExpectedResponseForAnonymous(userSearchResult1); | |||
RestUserForAnonymousUsers expectUser2 = buildExpectedResponseForAnonymous(userSearchResult2); | |||
assertThat(usersForResponse.users()).containsExactly(expectUser1, expectUser2); | |||
assertPaginationInformationAreCorrect(paging, usersForResponse.page()); | |||
} | |||
private static RestUser buildExpectedResponseForAnonymous(UserSearchResult userSearchResult) { | |||
private static RestUserForAnonymousUsers buildExpectedResponseForAnonymous(UserSearchResult userSearchResult) { | |||
UserDto userDto = userSearchResult.userDto(); | |||
return new RestUser( | |||
return new RestUserForAnonymousUsers( | |||
userDto.getLogin(), | |||
userDto.getLogin(), | |||
userDto.getName(), | |||
null, | |||
null, | |||
null, | |||
null, | |||
null, | |||
null, | |||
null, | |||
null, | |||
null, | |||
null, | |||
null, | |||
null | |||
userDto.getName() | |||
); | |||
} | |||