From 12743ddd2aadacb6f36ee062b61614b26355bd2e Mon Sep 17 00:00:00 2001 From: Wojtek Wajerowicz <115081248+wojciech-wajerowicz-sonarsource@users.noreply.github.com> Date: Tue, 25 Jul 2023 19:58:03 +0200 Subject: [PATCH] SONAR-19965 DELETE /api/v2/users/:login endpoint --- server/sonar-webserver-common/build.gradle | 1 + .../common/user/service/UserServiceIT.java | 65 +++++++-- .../management/ManagedInstanceChecker.java | 4 +- .../common}/management/package-info.java | 2 +- .../server/common/user}/UserAnonymizer.java | 2 +- .../server/common/user}/UserDeactivator.java | 2 +- .../common/user/service/UserService.java | 44 ++++-- .../ManagedInstanceCheckerTest.java | 5 +- .../controller/DefaultUserControllerIT.java | 135 ++++++++++++++++++ .../controller/DefaultUserControllerTest.java | 28 ---- .../v2/config/MockConfigForControllers.java | 7 +- .../controller/DefaultUserController.java | 12 +- .../api/user/controller/UserController.java | 12 ++ .../v2/config/PlatformLevel4WebConfig.java | 5 +- .../permission/ws/AddGroupActionIT.java | 2 +- .../server/permission/ws/AddUserActionIT.java | 2 +- .../permission/ws/RemoveGroupActionIT.java | 2 +- .../permission/ws/RemoveUserActionIT.java | 2 +- .../ws/template/ApplyTemplateActionIT.java | 2 +- .../project/ws/UpdateVisibilityActionIT.java | 2 +- .../server/user/ws/AnonymizeActionIT.java | 1 + .../sonar/server/user/ws/CreateActionIT.java | 2 +- .../server/user/ws/DeactivateActionIT.java | 12 +- .../sonar/server/user/ws/SearchActionIT.java | 20 +-- .../sonar/server/user/ws/UpdateActionIT.java | 2 +- .../ws/UpdateIdentityProviderActionIT.java | 2 +- .../server/user/ws/UpdateLoginActionIT.java | 2 +- .../server/user/ws/UserAnonymizerIT.java | 1 + .../server/usergroups/ws/AddUserActionIT.java | 2 +- .../server/usergroups/ws/CreateActionIT.java | 2 +- .../usergroups/ws/RemoveUserActionIT.java | 2 +- .../server/usergroups/ws/UpdateActionIT.java | 2 +- .../server/permission/ws/AddGroupAction.java | 2 +- .../server/permission/ws/AddUserAction.java | 2 +- .../permission/ws/RemoveGroupAction.java | 2 +- .../permission/ws/RemoveUserAction.java | 2 +- .../ws/template/ApplyTemplateAction.java | 2 +- .../project/ws/UpdateVisibilityAction.java | 2 +- .../sonar/server/user/ws/AnonymizeAction.java | 1 + .../sonar/server/user/ws/CreateAction.java | 2 +- .../server/user/ws/DeactivateAction.java | 27 +--- .../sonar/server/user/ws/UpdateAction.java | 2 +- .../user/ws/UpdateIdentityProviderAction.java | 2 +- .../server/user/ws/UpdateLoginAction.java | 2 +- .../sonar/server/user/ws/UsersWsModule.java | 2 + .../server/usergroups/ws/AddUserAction.java | 2 +- .../server/usergroups/ws/CreateAction.java | 2 +- .../usergroups/ws/RemoveUserAction.java | 2 +- .../server/usergroups/ws/UpdateAction.java | 2 +- .../usergroups/ws/UserGroupsModule.java | 2 +- 50 files changed, 326 insertions(+), 120 deletions(-) rename server/{sonar-webserver-webapi/src/main/java/org/sonar/server => sonar-webserver-common/src/main/java/org/sonar/server/common}/management/ManagedInstanceChecker.java (94%) rename server/{sonar-webserver-webapi/src/main/java/org/sonar/server => sonar-webserver-common/src/main/java/org/sonar/server/common}/management/package-info.java (95%) rename server/{sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws => sonar-webserver-common/src/main/java/org/sonar/server/common/user}/UserAnonymizer.java (98%) rename server/{sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws => sonar-webserver-common/src/main/java/org/sonar/server/common/user}/UserDeactivator.java (99%) rename server/{sonar-webserver-webapi/src/test/java/org/sonar/server => sonar-webserver-common/src/test/java/com/sonar/server/common}/management/ManagedInstanceCheckerTest.java (97%) create mode 100644 server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerIT.java delete mode 100644 server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java diff --git a/server/sonar-webserver-common/build.gradle b/server/sonar-webserver-common/build.gradle index 21daee76c7a..4a37f9dfdf6 100644 --- a/server/sonar-webserver-common/build.gradle +++ b/server/sonar-webserver-common/build.gradle @@ -9,6 +9,7 @@ dependencies { api 'com.google.guava:guava' api project(':server:sonar-db-dao') + api project(':server:sonar-webserver-auth') api project(':server:sonar-webserver-ws') compileOnlyApi 'com.google.code.findbugs:jsr305' diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/user/service/UserServiceIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/user/service/UserServiceIT.java index 769af7dcb7c..6b4c5d34d77 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/user/service/UserServiceIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/user/service/UserServiceIT.java @@ -35,6 +35,10 @@ import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; import org.sonar.server.common.SearchResults; import org.sonar.server.common.avatar.AvatarResolverImpl; +import org.sonar.server.common.management.ManagedInstanceChecker; +import org.sonar.server.common.user.UserDeactivator; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.management.ManagedInstanceService; import static java.util.Arrays.asList; @@ -42,10 +46,15 @@ import static java.util.Collections.singletonList; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class UserServiceIT { @@ -56,7 +65,11 @@ public class UserServiceIT { private final ManagedInstanceService managedInstanceService = mock(ManagedInstanceService.class); - private final UserService userService = new UserService(db.getDbClient(), new AvatarResolverImpl(), managedInstanceService); + private final ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class); + + private final UserDeactivator userDeactivator = mock(UserDeactivator.class); + + private final UserService userService = new UserService(db.getDbClient(), new AvatarResolverImpl(), managedInstanceService, managedInstanceChecker, userDeactivator); @Test public void search_for_all_active_users() { @@ -133,8 +146,7 @@ public class UserServiceIT { .extracting(r -> r.userDto().getLogin(), UserSearchResult::managed) .containsExactlyInAnyOrder( tuple(managedUser.getLogin(), true), - tuple(nonManagedUser.getLogin(), false) - ); + tuple(nonManagedUser.getLogin(), false)); } @@ -151,8 +163,7 @@ public class UserServiceIT { assertThat(users.searchResults()) .extracting(r -> r.userDto().getLogin(), UserSearchResult::managed) .containsExactlyInAnyOrder( - tuple(managedUser.getLogin(), true) - ); + tuple(managedUser.getLogin(), true)); } @@ -169,8 +180,7 @@ public class UserServiceIT { assertThat(users.searchResults()) .extracting(r -> r.userDto().getLogin(), UserSearchResult::managed) .containsExactlyInAnyOrder( - tuple(nonManagedUser.getLogin(), false) - ); + tuple(nonManagedUser.getLogin(), false)); } private void mockInstanceExternallyManagedAndFilterForManagedUsers() { @@ -243,8 +253,7 @@ public class UserServiceIT { .extracting( r -> r.userDto().getLogin(), userSearchResult -> userSearchResult.userDto().getExternalLogin(), - userSearchResult -> userSearchResult.userDto().getExternalIdentityProvider() - ) + userSearchResult -> userSearchResult.userDto().getExternalIdentityProvider()) .containsExactlyInAnyOrder(tuple(user.getLogin(), user.getExternalLogin(), user.getExternalIdentityProvider())); } @@ -371,7 +380,45 @@ public class UserServiceIT { assertUserWithFilter(b -> b.setSonarLintLastConnectionDateFrom(DateUtils.formatDateTime(lastConnection.toEpochMilli())), user.getLogin(), false); assertUserWithFilter(b -> b.setSonarLintLastConnectionDateTo(DateUtils.formatDateTime(lastConnection.toEpochMilli())), user.getLogin(), true); + } + + @Test + public void deactivate_whenUserIsNotFound_shouldThrowNotFoundException() { + assertThatThrownBy(() -> userService.deactivate("userToDelete", false)) + .isInstanceOf(NotFoundException.class) + .hasMessage("User 'userToDelete' not found"); + } + + @Test + public void deactivate_whenInstanceIsManagedAndUserIsManaged_shouldThrowBadRequestException() { + UserDto user = db.users().insertUser(); + BadRequestException badRequestException = BadRequestException.create("Not allowed"); + doThrow(badRequestException).when(managedInstanceChecker).throwIfUserIsManaged(any(), eq(user.getUuid())); + assertThatThrownBy(() -> userService.deactivate(user.getLogin(), false)) + .isEqualTo(badRequestException); + + } + + @Test + public void deactivate_whenAnonymizeIsFalse_shouldDeactivateUser() { + UserDto user = db.users().insertUser(); + + userService.deactivate(user.getLogin(), false); + verify(managedInstanceChecker).throwIfUserIsManaged(any(), eq(user.getUuid())); + + verify(userDeactivator).deactivateUser(any(), eq(user.getLogin())); + verify(userDeactivator, never()).deactivateUserWithAnonymization(any(), eq(user.getLogin())); + } + + @Test + public void deactivate_whenAnonymizeIsTrue_shouldDeactivateUserWithAnonymization() { + UserDto user = db.users().insertUser(); + + userService.deactivate(user.getLogin(), true); + verify(managedInstanceChecker).throwIfUserIsManaged(any(), eq(user.getUuid())); + verify(userDeactivator).deactivateUserWithAnonymization(any(), eq(user.getLogin())); + verify(userDeactivator, never()).deactivateUser(any(), eq(user.getLogin())); } private void assertUserWithFilter(Function query, String userLogin, boolean isExpectedToBeThere) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/management/ManagedInstanceChecker.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/management/ManagedInstanceChecker.java similarity index 94% rename from server/sonar-webserver-webapi/src/main/java/org/sonar/server/management/ManagedInstanceChecker.java rename to server/sonar-webserver-common/src/main/java/org/sonar/server/common/management/ManagedInstanceChecker.java index b5183f5a000..95a24ac46ba 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/management/ManagedInstanceChecker.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/management/ManagedInstanceChecker.java @@ -17,10 +17,12 @@ * 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.management; +package org.sonar.server.common.management; import org.sonar.db.DbSession; import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.management.ManagedInstanceService; +import org.sonar.server.management.ManagedProjectService; public class ManagedInstanceChecker { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/management/package-info.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/management/package-info.java similarity index 95% rename from server/sonar-webserver-webapi/src/main/java/org/sonar/server/management/package-info.java rename to server/sonar-webserver-common/src/main/java/org/sonar/server/common/management/package-info.java index 22b8574d3b3..d9de13f7610 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/management/package-info.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/management/package-info.java @@ -18,6 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @ParametersAreNonnullByDefault -package org.sonar.server.management; +package org.sonar.server.common.management; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserAnonymizer.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/UserAnonymizer.java similarity index 98% rename from server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserAnonymizer.java rename to server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/UserAnonymizer.java index cd406ef6c2d..f5094e8b43e 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserAnonymizer.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/UserAnonymizer.java @@ -17,7 +17,7 @@ * 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.user.ws; +package org.sonar.server.common.user; import java.util.function.Supplier; import javax.inject.Inject; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserDeactivator.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/UserDeactivator.java similarity index 99% rename from server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserDeactivator.java rename to server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/UserDeactivator.java index 127a8bafbdf..9c5fd4d5801 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserDeactivator.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/UserDeactivator.java @@ -17,7 +17,7 @@ * 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.user.ws; +package org.sonar.server.common.user; import org.sonar.db.DbClient; import org.sonar.db.DbSession; diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/service/UserService.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/service/UserService.java index 9c5bc4cbe4d..744e41f7df1 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/service/UserService.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/user/service/UserService.java @@ -32,21 +32,33 @@ import org.sonar.db.user.UserDto; import org.sonar.db.user.UserQuery; import org.sonar.server.common.SearchResults; import org.sonar.server.common.avatar.AvatarResolver; +import org.sonar.server.common.management.ManagedInstanceChecker; +import org.sonar.server.common.user.UserDeactivator; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.management.ManagedInstanceService; import static java.util.Comparator.comparing; +import static org.sonar.server.exceptions.NotFoundException.checkFound; public class UserService { private final DbClient dbClient; private final AvatarResolver avatarResolver; private final ManagedInstanceService managedInstanceService; - - public UserService(DbClient dbClient, AvatarResolver avatarResolver, ManagedInstanceService managedInstanceService) { + private final ManagedInstanceChecker managedInstanceChecker; + private final UserDeactivator userDeactivator; + + public UserService( + DbClient dbClient, + AvatarResolver avatarResolver, + ManagedInstanceService managedInstanceService, + ManagedInstanceChecker managedInstanceChecker, + UserDeactivator userDeactivator) { this.dbClient = dbClient; this.avatarResolver = avatarResolver; this.managedInstanceService = managedInstanceService; + this.managedInstanceChecker = managedInstanceChecker; + this.userDeactivator = userDeactivator; } public SearchResults findUsers(UsersSearchRequest request) { @@ -89,12 +101,11 @@ public class UserService { Map userUuidToIsManaged = managedInstanceService.getUserUuidToManaged(dbSession, getUserUuids(userDtos)); return userDtos.stream() .map(userDto -> toUserSearchResult( - groupsByLogin.get(userDto.getLogin()), - tokenCountsByLogin.getOrDefault(userDto.getUuid(), 0), - userUuidToIsManaged.getOrDefault(userDto.getUuid(), false), - userDto - ) - ).toList(); + groupsByLogin.get(userDto.getLogin()), + tokenCountsByLogin.getOrDefault(userDto.getUuid(), 0), + userUuidToIsManaged.getOrDefault(userDto.getUuid(), false), + userDto)) + .toList(); } private UserSearchResult toUserSearchResult(Collection groups, int tokenCount, boolean managed, UserDto userDto) { @@ -103,8 +114,7 @@ public class UserService { managed, findAvatar(userDto), groups, - tokenCount - ); + tokenCount); } private List findUsersAndSortByLogin(DbSession dbSession, UserQuery userQuery, int page, int pageSize) { @@ -122,4 +132,18 @@ public class UserService { return users.stream().map(UserDto::getUuid).collect(Collectors.toSet()); } + public UserDto deactivate(String login, Boolean anonymize) { + try (DbSession dbSession = dbClient.openSession(false)) { + UserDto userDto = checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' not found", login); + managedInstanceChecker.throwIfUserIsManaged(dbSession, userDto.getUuid()); + UserDto deactivatedUser; + if (Boolean.TRUE.equals(anonymize)) { + deactivatedUser = userDeactivator.deactivateUserWithAnonymization(dbSession, login); + } else { + deactivatedUser = userDeactivator.deactivateUser(dbSession, login); + } + dbSession.commit(); + return deactivatedUser; + } + } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/management/ManagedInstanceCheckerTest.java b/server/sonar-webserver-common/src/test/java/com/sonar/server/common/management/ManagedInstanceCheckerTest.java similarity index 97% rename from server/sonar-webserver-webapi/src/test/java/org/sonar/server/management/ManagedInstanceCheckerTest.java rename to server/sonar-webserver-common/src/test/java/com/sonar/server/common/management/ManagedInstanceCheckerTest.java index 16959847dcb..4efc91291da 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/management/ManagedInstanceCheckerTest.java +++ b/server/sonar-webserver-common/src/test/java/com/sonar/server/common/management/ManagedInstanceCheckerTest.java @@ -17,7 +17,7 @@ * 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.management; +package com.sonar.server.common.management; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,7 +28,10 @@ import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.management.ManagedInstanceService; +import org.sonar.server.management.ManagedProjectService; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerIT.java b/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerIT.java new file mode 100644 index 00000000000..5298c355060 --- /dev/null +++ b/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerIT.java @@ -0,0 +1,135 @@ +/* + * 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.controller; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.sonar.db.DbClient; +import org.sonar.db.user.UserDao; +import org.sonar.server.common.user.service.UserService; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.user.AbstractUserSession; +import org.sonar.server.user.UserSession; +import org.sonar.server.v2.common.ControllerIT; + +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.sonar.server.v2.WebApiEndpoints.USER_ENDPOINT; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class DefaultUserControllerIT extends ControllerIT { + + @After + public void resetUsedMocks() { + Mockito.reset(webAppContext.getBean(UserService.class)); + Mockito.reset(webAppContext.getBean(UserSession.class)); + } + + @Before + public void setUp() { + UserSession userSession = webAppContext.getBean(UserSession.class); + when(userSession.checkLoggedIn()).thenReturn(userSession); + } + + @Test + public void deactivate_whenUserIsNotLoggedIn_shouldReturnForbidden() throws Exception { + when(webAppContext.getBean(UserSession.class).checkLoggedIn()).thenThrow(new UnauthorizedException("unauthorized")); + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete")) + .andExpectAll( + status().isUnauthorized(), + content().string("{\"message\":\"unauthorized\"}")); + } + + @Test + public void deactivate_whenUserIsNotAdministrator_shouldReturnForbidden() throws Exception { + when(webAppContext.getBean(UserSession.class).checkIsSystemAdministrator()).thenThrow(AbstractUserSession.insufficientPrivilegesException()); + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete")) + .andExpectAll( + status().isForbidden(), + content().json("{\"message\":\"Insufficient privileges\"}")); + } + + @Test + public void deactivate_whenUserServiceThrowsNotFoundException_shouldReturnNotFound() throws Exception { + doThrow(new NotFoundException("User not found.")).when(webAppContext.getBean(UserService.class)).deactivate("userToDelete", false); + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete")) + .andExpectAll( + status().isNotFound(), + content().json("{\"message\":\"User not found.\"}")); + } + + @Test + public void deactivate_whenUserServiceThrowsBadRequestException_shouldReturnBadRequest() throws Exception { + doThrow(BadRequestException.create("Not allowed")).when(webAppContext.getBean(UserService.class)).deactivate("userToDelete", false); + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete")) + .andExpectAll( + status().isBadRequest(), + content().json("{\"message\":\"Not allowed\"}")); + } + + @Test + public void deactivate_whenUserTryingToDeactivateThemself_shouldReturnBadRequest() throws Exception { + when(webAppContext.getBean(DbClient.class).userDao()).thenReturn(mock(UserDao.class)); + when(webAppContext.getBean(UserSession.class).getLogin()).thenReturn("userToDelete"); + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete")) + .andExpectAll( + status().isBadRequest(), + content().json("{\"message\":\"Self-deactivation is not possible\"}")); + } + + @Test + public void deactivate_whenAnonymizeParameterIsNotBoolean_shouldReturnBadRequest() throws Exception { + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete?anonymize=maybe")) + .andExpect( + status().isBadRequest()); + } + + @Test + public void deactivate_whenAnonymizeIsNotSpecified_shouldDeactivateUserWithoutAnonymization() throws Exception { + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete")) + .andExpect(status().isNoContent()); + + verify(webAppContext.getBean(UserService.class)).deactivate("userToDelete", false); + } + + @Test + public void deactivate_whenAnonymizeFalse_shouldDeactivateUserWithoutAnonymization() throws Exception { + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete?anonymize=false")) + .andExpect(status().isNoContent()); + + verify(webAppContext.getBean(UserService.class)).deactivate("userToDelete", false); + } + + @Test + public void deactivate_whenAnonymizeTrue_shouldDeactivateUserWithAnonymization() throws Exception { + mockMvc.perform(delete(USER_ENDPOINT + "/userToDelete?anonymize=true")) + .andExpect(status().isNoContent()); + + verify(webAppContext.getBean(UserService.class)).deactivate("userToDelete", true); + } +} diff --git a/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java b/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java deleted file mode 100644 index 9073d3b25b8..00000000000 --- a/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/api/user/controller/DefaultUserControllerTest.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.controller; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class DefaultUserControllerTest { - -} diff --git a/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/config/MockConfigForControllers.java b/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/config/MockConfigForControllers.java index 12bfee0eb87..cee83db8349 100644 --- a/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/config/MockConfigForControllers.java +++ b/server/sonar-webserver-webapi-v2/src/it/java/org/sonar/server/v2/config/MockConfigForControllers.java @@ -26,7 +26,6 @@ import org.sonar.server.health.DbConnectionNodeCheck; import org.sonar.server.health.EsStatusNodeCheck; import org.sonar.server.health.HealthChecker; import org.sonar.server.health.WebServerStatusNodeCheck; -import org.sonar.server.management.ManagedInstanceChecker; import org.sonar.server.platform.NodeInformation; import org.sonar.server.platform.ws.LivenessChecker; import org.sonar.server.user.SystemPasscode; @@ -95,13 +94,9 @@ public class MockConfigForControllers { return mock(UserUpdater.class); } - @Bean - ManagedInstanceChecker managedInstanceChecker() { - return mock(ManagedInstanceChecker.class); - } - @Bean UserService userService() { return mock(UserService.class); } + } 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 c095a720cd1..4aa6fed9ed0 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 @@ -34,13 +34,17 @@ import org.sonar.server.v2.api.user.request.UsersSearchRestRequest; import org.sonar.server.v2.api.user.response.UsersSearchRestResponse; import static org.sonar.api.utils.Paging.forPageIndex; +import static org.sonar.server.exceptions.BadRequestException.checkRequest; public class DefaultUserController implements UserController { private final UsersSearchRestResponseGenerator usersSearchResponseGenerator; private final UserService userService; private final UserSession userSession; - public DefaultUserController(UserSession userSession, UserService userService, UsersSearchRestResponseGenerator usersSearchResponseGenerator) { + public DefaultUserController( + UserSession userSession, + UserService userService, + UsersSearchRestResponseGenerator usersSearchResponseGenerator) { this.userSession = userSession; this.usersSearchResponseGenerator = usersSearchResponseGenerator; this.userService = userService; @@ -87,4 +91,10 @@ public class DefaultUserController implements UserController { .build(); } + @Override + public void deactivate(String login, Boolean anonymize) { + userSession.checkLoggedIn().checkIsSystemAdministrator(); + checkRequest(!login.equals(userSession.getLogin()), "Self-deactivation is not possible"); + userService.deactivate(login, anonymize); + } } diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/controller/UserController.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/controller/UserController.java index 03181b3438a..fc4e35c4ebd 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/controller/UserController.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/user/controller/UserController.java @@ -20,6 +20,8 @@ package org.sonar.server.v2.api.user.controller; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; import javax.validation.Valid; import org.sonar.server.v2.api.model.RestPage; import org.sonar.server.v2.api.user.request.UsersSearchRestRequest; @@ -27,8 +29,11 @@ import org.sonar.server.v2.api.user.response.UsersSearchRestResponse; import org.springdoc.api.annotations.ParameterObject; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -53,4 +58,11 @@ public interface UserController { Field 'sonarqubeLastConnectionDate' is only updated every hour, so it may not be accurate, for instance when a user authenticates many times in less than one hour. """) UsersSearchRestResponse search(@ParameterObject UsersSearchRestRequest usersSearchRestRequest, @Valid @ParameterObject RestPage restPage); + + @DeleteMapping(path = "/{login}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Deactivate a user", description = "Deactivate a user. Requires Administer System permission.") + void deactivate( + @PathVariable("login") @Parameter(description = "The login of the user to delete.", required = true, in = ParameterIn.PATH) String login, + @RequestParam(value = "anonymize", required = false, defaultValue = "false") @Parameter(description = "Anonymize user in addition to deactivating it.") Boolean anonymize); } diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/PlatformLevel4WebConfig.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/PlatformLevel4WebConfig.java index d6c133308df..fc29d481951 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/PlatformLevel4WebConfig.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/PlatformLevel4WebConfig.java @@ -68,7 +68,10 @@ public class PlatformLevel4WebConfig { } @Bean - public UserController userController(UserSession userSession, UsersSearchRestResponseGenerator usersSearchResponseGenerator, UserService userService) { + public UserController userController( + UserSession userSession, + UsersSearchRestResponseGenerator usersSearchResponseGenerator, + UserService userService) { return new DefaultUserController(userSession, userService, usersSearchResponseGenerator); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddGroupActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddGroupActionIT.java index 43de8249cda..2aa463a7cd6 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddGroupActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddGroupActionIT.java @@ -36,7 +36,7 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.ServerException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.ws.TestRequest; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddUserActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddUserActionIT.java index 6e8cb3c838f..50856df0e55 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddUserActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddUserActionIT.java @@ -35,7 +35,7 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.ServerException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.ws.TestRequest; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveGroupActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveGroupActionIT.java index b5e85e7be69..9a550e33db2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveGroupActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveGroupActionIT.java @@ -40,7 +40,7 @@ import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.ws.TestRequest; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveUserActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveUserActionIT.java index 8af083dccb3..9f6744f0a0c 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveUserActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveUserActionIT.java @@ -33,7 +33,7 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.ServerException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.ws.TestRequest; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/ApplyTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/ApplyTemplateActionIT.java index 594d47573bf..69c3ae7db57 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/ApplyTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/ApplyTemplateActionIT.java @@ -38,7 +38,7 @@ import org.sonar.server.es.TestIndexers; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.management.ManagedProjectService; import org.sonar.server.permission.DefaultTemplatesResolver; import org.sonar.server.permission.DefaultTemplatesResolverImpl; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateVisibilityActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateVisibilityActionIT.java index 6f68d7cba98..48c186e6456 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateVisibilityActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateVisibilityActionIT.java @@ -59,7 +59,7 @@ import org.sonar.server.es.TestIndexers; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.permission.index.FooIndexDefinition; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/AnonymizeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/AnonymizeActionIT.java index a03f4399b57..85bebb1673f 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/AnonymizeActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/AnonymizeActionIT.java @@ -30,6 +30,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.user.UserDto; import org.sonar.db.user.UserQuery; +import org.sonar.server.common.user.UserAnonymizer; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.UnauthorizedException; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CreateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CreateActionIT.java index 5af7f5a8c5e..5071be725cd 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CreateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CreateActionIT.java @@ -36,7 +36,7 @@ import org.sonar.server.authentication.CredentialsLocalAuthentication; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.user.NewUserNotifier; import org.sonar.server.user.UserUpdater; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DeactivateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DeactivateActionIT.java index 2afc43c82d4..129f5561d38 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DeactivateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DeactivateActionIT.java @@ -44,11 +44,16 @@ import org.sonar.db.user.GroupDto; import org.sonar.db.user.SessionTokenDto; import org.sonar.db.user.UserDismissedMessageDto; import org.sonar.db.user.UserDto; +import org.sonar.server.common.avatar.AvatarResolver; +import org.sonar.server.common.management.ManagedInstanceChecker; +import org.sonar.server.common.user.UserAnonymizer; +import org.sonar.server.common.user.UserDeactivator; +import org.sonar.server.common.user.service.UserService; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.management.ManagedInstanceService; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.user.ExternalIdentity; import org.sonar.server.ws.TestRequest; @@ -80,7 +85,8 @@ public class DeactivateActionIT { private final UserDeactivator userDeactivator = new UserDeactivator(dbClient, userAnonymizer); private final ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class); - private final WsActionTester ws = new WsActionTester(new DeactivateAction(dbClient, userSession, new UserJsonWriter(userSession), userDeactivator, managedInstanceChecker)); + private final UserService userService = new UserService(dbClient, mock(AvatarResolver.class), mock(ManagedInstanceService.class), managedInstanceChecker, userDeactivator); + private final WsActionTester ws = new WsActionTester(new DeactivateAction(dbClient, userSession, new UserJsonWriter(userSession), userService)); @Test public void deactivate_user_and_delete_their_related_data() { @@ -342,7 +348,7 @@ public class DeactivateActionIT { deactivate("someone"); }) .isInstanceOf(NotFoundException.class) - .hasMessage("User 'someone' doesn't exist"); + .hasMessage("User 'someone' not found"); } @Test diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/SearchActionIT.java index f75975c1c66..732d219d5a0 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/SearchActionIT.java @@ -37,6 +37,8 @@ import org.sonar.db.scim.ScimUserDao; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; import org.sonar.server.common.avatar.AvatarResolverImpl; +import org.sonar.server.common.management.ManagedInstanceChecker; +import org.sonar.server.common.user.UserDeactivator; import org.sonar.server.common.user.service.UserService; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ServerException; @@ -74,7 +76,12 @@ public class SearchActionIT { private final ManagedInstanceService managedInstanceService = mock(ManagedInstanceService.class); - private final UserService userService = new UserService(db.getDbClient(), new AvatarResolverImpl(), managedInstanceService); + private final UserService userService = new UserService( + db.getDbClient(), + new AvatarResolverImpl(), + managedInstanceService, + mock(ManagedInstanceChecker.class), + mock(UserDeactivator.class)); private final SearchWsReponseGenerator searchWsReponseGenerator = new SearchWsReponseGenerator(userSession); @@ -168,8 +175,7 @@ public class SearchActionIT { .extracting(User::getLogin, User::getManaged) .containsExactlyInAnyOrder( tuple(managedUser.getLogin(), true), - tuple(nonManagedUser.getLogin(), false) - ); + tuple(nonManagedUser.getLogin(), false)); } @Test @@ -200,8 +206,7 @@ public class SearchActionIT { assertThat(response.getUsersList()) .extracting(User::getLogin, User::getManaged) .containsExactlyInAnyOrder( - tuple(managedUser.getLogin(), true) - ); + tuple(managedUser.getLogin(), true)); } @Test @@ -220,8 +225,7 @@ public class SearchActionIT { assertThat(response.getUsersList()) .extracting(User::getLogin, User::getManaged) .containsExactlyInAnyOrder( - tuple(nonManagedUser.getLogin(), false) - ); + tuple(nonManagedUser.getLogin(), false)); } private void mockInstanceExternallyManagedAndFilterForManagedUsers() { @@ -558,7 +562,7 @@ public class SearchActionIT { userSession.logIn(); Stream.of(SearchAction.LAST_CONNECTION_DATE_FROM, SearchAction.LAST_CONNECTION_DATE_TO, - SearchAction.SONAR_LINT_LAST_CONNECTION_DATE_FROM, SearchAction.SONAR_LINT_LAST_CONNECTION_DATE_TO) + SearchAction.SONAR_LINT_LAST_CONNECTION_DATE_FROM, SearchAction.SONAR_LINT_LAST_CONNECTION_DATE_TO) .map(param -> ws.newRequest().setParam(param, formatDateTime(OffsetDateTime.now()))) .forEach(SearchActionIT::assertForbiddenException); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateActionIT.java index cf0f8bfee69..78a7a1097d5 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateActionIT.java @@ -36,7 +36,7 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.user.NewUserNotifier; import org.sonar.server.user.UserUpdater; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateIdentityProviderActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateIdentityProviderActionIT.java index 125339b82ba..1149597c0fa 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateIdentityProviderActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateIdentityProviderActionIT.java @@ -33,7 +33,7 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.user.NewUserNotifier; import org.sonar.server.user.UserUpdater; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateLoginActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateLoginActionIT.java index ef372d567d0..9853b0b3979 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateLoginActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UpdateLoginActionIT.java @@ -30,7 +30,7 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.user.NewUserNotifier; import org.sonar.server.user.UserUpdater; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UserAnonymizerIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UserAnonymizerIT.java index e10daea53a4..8097985ce56 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UserAnonymizerIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/UserAnonymizerIT.java @@ -27,6 +27,7 @@ import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.user.UserDto; +import org.sonar.server.common.user.UserAnonymizer; import org.sonar.server.user.ExternalIdentity; import static org.assertj.core.api.Assertions.assertThat; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/AddUserActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/AddUserActionIT.java index eae0bc78ecb..99f386075fa 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/AddUserActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/AddUserActionIT.java @@ -30,7 +30,7 @@ import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.usergroups.DefaultGroupFinder; import org.sonar.server.ws.TestRequest; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/CreateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/CreateActionIT.java index 42043b7af36..3541a23cfb0 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/CreateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/CreateActionIT.java @@ -31,7 +31,7 @@ import org.sonar.db.user.GroupDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.ServerException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/RemoveUserActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/RemoveUserActionIT.java index 088f91aef2d..69a3c6913db 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/RemoveUserActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/RemoveUserActionIT.java @@ -30,7 +30,7 @@ import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.usergroups.DefaultGroupFinder; import org.sonar.server.ws.TestRequest; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/UpdateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/UpdateActionIT.java index c065b8e5300..787af00f823 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/UpdateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/UpdateActionIT.java @@ -32,7 +32,7 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.ServerException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java index eb71e9b5799..f0265f8a32a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java @@ -28,7 +28,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.db.user.GroupDto; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.GroupPermissionChange; import org.sonar.server.permission.PermissionChange; import org.sonar.server.permission.PermissionService; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/AddUserAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/AddUserAction.java index f8a013befc8..e119759bb02 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/AddUserAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/AddUserAction.java @@ -27,7 +27,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.db.user.UserId; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionChange; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionUpdater; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java index 39c38f84c39..60d429f55eb 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java @@ -27,7 +27,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.db.user.GroupDto; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.GroupPermissionChange; import org.sonar.server.permission.GroupUuidOrAnyone; import org.sonar.server.permission.PermissionChange; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/RemoveUserAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/RemoveUserAction.java index 17f8b875b94..d688ad8d78a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/RemoveUserAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/RemoveUserAction.java @@ -26,7 +26,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.db.user.UserId; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionChange; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionUpdater; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java index 0e90558f9dc..41cdd943605 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java @@ -32,7 +32,7 @@ import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java index 5148c6b6ea5..cb5f87b7230 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java @@ -27,7 +27,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.project.Visibility; import org.sonar.server.project.VisibilityService; import org.sonar.server.user.UserSession; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/AnonymizeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/AnonymizeAction.java index d26ffd9eeeb..a79942645b5 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/AnonymizeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/AnonymizeAction.java @@ -26,6 +26,7 @@ import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.user.UserDto; +import org.sonar.server.common.user.UserAnonymizer; import org.sonar.server.user.UserSession; import static org.sonar.server.exceptions.NotFoundException.checkFound; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CreateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CreateAction.java index c7c11e916ae..839e2697918 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CreateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CreateAction.java @@ -31,7 +31,7 @@ import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.user.UserDto; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.user.ExternalIdentity; import org.sonar.server.user.NewUser; import org.sonar.server.user.UserSession; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DeactivateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DeactivateAction.java index 3dfa62dab2b..b154e0cece8 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DeactivateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DeactivateAction.java @@ -29,7 +29,7 @@ import org.sonar.api.utils.text.JsonWriter; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.user.UserDto; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.user.service.UserService; import org.sonar.server.user.UserSession; import static java.util.Collections.singletonList; @@ -44,16 +44,13 @@ public class DeactivateAction implements UsersWsAction { private final DbClient dbClient; private final UserSession userSession; private final UserJsonWriter userWriter; - private final UserDeactivator userDeactivator; - private final ManagedInstanceChecker managedInstanceChecker; + private final UserService userService; - public DeactivateAction(DbClient dbClient, UserSession userSession, UserJsonWriter userWriter, - UserDeactivator userDeactivator, ManagedInstanceChecker managedInstanceChecker) { + public DeactivateAction(DbClient dbClient, UserSession userSession, UserJsonWriter userWriter, UserService userService) { this.dbClient = dbClient; this.userSession = userSession; this.userWriter = userWriter; - this.userDeactivator = userDeactivator; - this.managedInstanceChecker = managedInstanceChecker; + this.userService = userService; } @Override @@ -83,17 +80,9 @@ public class DeactivateAction implements UsersWsAction { userSession.checkLoggedIn().checkIsSystemAdministrator(); String login = request.mandatoryParam(PARAM_LOGIN); checkRequest(!login.equals(userSession.getLogin()), "Self-deactivation is not possible"); - try (DbSession dbSession = dbClient.openSession(false)) { - UserDto userDto = dbClient.userDao().selectByLogin(dbSession, login); - if (userDto != null) { - managedInstanceChecker.throwIfUserIsManaged(dbSession, userDto.getUuid()); - } - boolean shouldAnonymize = request.mandatoryParamAsBoolean(PARAM_ANONYMIZE); - userDto = shouldAnonymize - ? userDeactivator.deactivateUserWithAnonymization(dbSession, login) - : userDeactivator.deactivateUser(dbSession, login); - writeResponse(response, userDto.getLogin()); - } + boolean shouldAnonymize = request.mandatoryParamAsBoolean(PARAM_ANONYMIZE); + UserDto deactivatedUser = userService.deactivate(login, shouldAnonymize); + writeResponse(response, deactivatedUser.getLogin()); } private void writeResponse(Response response, String login) { @@ -113,6 +102,4 @@ public class DeactivateAction implements UsersWsAction { } } - - } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateAction.java index 73af1722dc6..08cba756840 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateAction.java @@ -34,7 +34,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.user.UpdateUser; import org.sonar.server.user.UserSession; import org.sonar.server.user.UserUpdater; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateIdentityProviderAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateIdentityProviderAction.java index e4d4f89e95d..d2b9404c8e1 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateIdentityProviderAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateIdentityProviderAction.java @@ -32,7 +32,7 @@ import org.sonar.db.DbSession; import org.sonar.db.user.UserDto; import org.sonar.server.authentication.IdentityProviderRepository; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.user.ExternalIdentity; import org.sonar.server.user.UpdateUser; import org.sonar.server.user.UserSession; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java index 570cdc8c4cd..ac4bee4d28f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java @@ -26,7 +26,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.user.UpdateUser; import org.sonar.server.user.UserSession; import org.sonar.server.user.UserUpdater; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UsersWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UsersWsModule.java index b625c8c3744..936a6302ebf 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UsersWsModule.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UsersWsModule.java @@ -20,6 +20,8 @@ package org.sonar.server.user.ws; import org.sonar.core.platform.Module; +import org.sonar.server.common.user.UserAnonymizer; +import org.sonar.server.common.user.UserDeactivator; import org.sonar.server.common.user.service.UserService; public class UsersWsModule extends Module { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java index dfd97224ee6..abc7d8577fd 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/AddUserAction.java @@ -29,7 +29,7 @@ import org.sonar.db.DbSession; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; import org.sonar.db.user.UserGroupDto; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.user.UserSession; import static java.lang.String.format; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java index cfc53523bfb..a728d4704a9 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java @@ -27,7 +27,7 @@ import org.sonar.api.server.ws.WebService.NewController; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.user.GroupDto; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.user.UserSession; import org.sonarqube.ws.UserGroups; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java index 7e4d301fd76..c0ca2d56bc8 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java @@ -29,7 +29,7 @@ import org.sonar.db.DbSession; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.user.UserSession; import static java.lang.String.format; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java index e67a3ae8887..8113fa13afd 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java @@ -29,7 +29,7 @@ import org.sonar.db.DbSession; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserMembershipQuery; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.user.UserSession; import org.sonarqube.ws.UserGroups; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java index b4dd9c03a1f..22ea5abe0bf 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UserGroupsModule.java @@ -20,7 +20,7 @@ package org.sonar.server.usergroups.ws; import org.sonar.core.platform.Module; -import org.sonar.server.management.ManagedInstanceChecker; +import org.sonar.server.common.management.ManagedInstanceChecker; public class UserGroupsModule extends Module { -- 2.39.5