Sfoglia il codice sorgente

SONAR-20181 ommit from /api/user/search answer the field non-compliant with access-level

tags/10.2.0.77647
Aurelien Poscia 10 mesi fa
parent
commit
c4b18ef962

+ 27
- 23
server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/converter/UsersSearchRestResponseGenerator.java Vedi File

@@ -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) {

+ 1
- 32
server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/model/RestUser.java Vedi File

@@ -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 {
}

+ 54
- 0
server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/model/RestUserForAdmins.java Vedi File

@@ -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 {
}

+ 28
- 0
server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/model/RestUserForAnonymousUsers.java Vedi File

@@ -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 {
}

+ 40
- 0
server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/model/RestUserForLoggedInUsers.java Vedi File

@@ -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 {
}

+ 11
- 10
server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java Vedi File

@@ -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));
}


+ 17
- 34
server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/user/converter/UsersSearchRestResponseGeneratorTest.java Vedi File

@@ -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()
);
}


Loading…
Annulla
Salva