import org.sonar.db.DbTester;
import org.sonar.db.user.GroupDto;
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.tester.UserSessionRule;
import org.sonar.server.usergroups.DefaultGroupFinder;
import org.sonar.server.ws.TestRequest;
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.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import static org.sonar.db.permission.GlobalPermission.ADMINISTER;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN;
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
- private final WsActionTester ws = new WsActionTester(new AddUserAction(db.getDbClient(), userSession, newGroupWsSupport()));
+ private ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
+
+ private final WsActionTester ws = new WsActionTester(new AddUserAction(db.getDbClient(), userSession, newGroupWsSupport(), managedInstanceChecker));
@Test
public void verify_definition() {
.hasMessage("Default group cannot be found");
}
+ @Test
+ public void fail_if_instance_is_externally_managed() {
+ loginAsAdmin();
+ BadRequestException exception = BadRequestException.create("Not allowed");
+ doThrow(exception).when(managedInstanceChecker).throwIfInstanceIsManaged();
+ TestRequest testRequest = newRequest()
+ .setParam("name", "long-desc");
+ assertThatThrownBy(testRequest::execute)
+ .isEqualTo(exception);
+ }
+
private void executeRequest(GroupDto groupDto, UserDto userDto) {
newRequest()
.setParam(PARAM_GROUP_NAME, groupDto.getName())
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.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
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.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import static org.sonar.db.permission.GlobalPermission.ADMINISTER;
public class CreateActionIT {
public DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
+ private ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
- private final CreateAction underTest = new CreateAction(db.getDbClient(), userSession, newGroupService());
+ private final CreateAction underTest = new CreateAction(db.getDbClient(), userSession, newGroupService(), managedInstanceChecker);
private final WsActionTester tester = new WsActionTester(underTest);
@Test
.isInstanceOf(IllegalArgumentException.class);
}
+ @Test
+ public void fail_if_instance_is_externally_managed() {
+ loginAsAdmin();
+ BadRequestException exception = BadRequestException.create("Not allowed");
+ doThrow(exception).when(managedInstanceChecker).throwIfInstanceIsManaged();
+ TestRequest testRequest = tester.newRequest();
+ assertThatThrownBy(testRequest::execute)
+ .isEqualTo(exception);
+ }
+
private void loginAsAdmin() {
userSession.logIn().addPermission(ADMINISTER);
}
*/
package org.sonar.server.usergroups.ws;
+import java.util.Map;
+import java.util.Set;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
import org.sonar.api.server.ws.WebService.Action;
import org.sonar.api.web.UserRole;
import org.sonar.core.util.UuidFactoryImpl;
+import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.management.ManagedInstanceService;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
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.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import static org.sonar.db.permission.GlobalPermission.ADMINISTER;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME;
private final ComponentDbTester componentTester = new ComponentDbTester(db);
private final GroupService groupService = new GroupService(db.getDbClient(), UuidFactoryImpl.INSTANCE);
- private final WsActionTester ws = new WsActionTester(new DeleteAction(db.getDbClient(), userSession, groupService));
+
+ private final ManagedInstanceService managedInstanceService = mock(ManagedInstanceService.class);
+ private final WsActionTester ws = new WsActionTester(new DeleteAction(db.getDbClient(), userSession, groupService, managedInstanceService));
@Test
public void verify_definition() {
assertThat(db.users().selectGroupPermissions(adminGroup2, null)).hasSize(1);
}
+ @Test
+ public void delete_local_group_when_instance_is_managed_shouldSucceed() {
+ when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(true);
+
+ addAdmin();
+ insertDefaultGroup();
+ GroupDto group = insertGroupAndMockIsManaged(false);
+
+ loginAsAdmin();
+ TestResponse response = newRequest()
+ .setParam(PARAM_GROUP_NAME, group.getName())
+ .execute();
+
+ assertThat(response.getStatus()).isEqualTo(204);
+ }
+
+ @Test
+ public void fail_to_delete_managed_group_when_instance_is_managed() {
+ when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(true);
+ addAdmin();
+ insertDefaultGroup();
+ GroupDto group = insertGroupAndMockIsManaged(true);
+
+ loginAsAdmin();
+ TestRequest request = newRequest()
+ .setParam(PARAM_GROUP_NAME, group.getName());
+
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(BadRequestException.class)
+ .hasMessage("Deleting managed groups is not allowed.");
+
+ }
+
+ private GroupDto insertGroupAndMockIsManaged(boolean isManaged) {
+ GroupDto group = db.users().insertGroup();
+ when(managedInstanceService.getGroupUuidToManaged(any(DbSession.class), eq(Set.of(group.getUuid()))))
+ .thenReturn(Map.of(group.getUuid(), isManaged));
+ return group;
+ }
+
private void executeDeleteGroupRequest(GroupDto adminGroup1) {
newRequest()
.setParam(PARAM_GROUP_NAME, adminGroup1.getName())
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.tester.UserSessionRule;
import org.sonar.server.usergroups.DefaultGroupFinder;
import org.sonar.server.ws.TestRequest;
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.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import static org.sonar.db.permission.GlobalPermission.ADMINISTER;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN;
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
+ private ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
private final WsActionTester ws = new WsActionTester(
- new RemoveUserAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient()))));
+ new RemoveUserAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())), managedInstanceChecker));
@Test
public void verify_definition() {
.hasMessage("Default group 'sonar-users' cannot be used to perform this action");
}
+ @Test
+ public void fail_if_instance_is_externally_managed() {
+ loginAsAdmin();
+ BadRequestException exception = BadRequestException.create("Not allowed");
+ doThrow(exception).when(managedInstanceChecker).throwIfInstanceIsManaged();
+ TestRequest testRequest = newRequest();
+ assertThatThrownBy(testRequest::execute)
+ .isEqualTo(exception);
+ }
+
private TestRequest newRequest() {
return ws.newRequest();
}
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.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import static org.sonar.db.permission.GlobalPermission.ADMINISTER;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_CURRENT_NAME;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_DESCRIPTION;
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
+ private ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
+
private final WsActionTester ws = new WsActionTester(
- new UpdateAction(db.getDbClient(), userSession, new GroupService(db.getDbClient(), UuidFactoryImpl.INSTANCE)));
+ new UpdateAction(db.getDbClient(), userSession, new GroupService(db.getDbClient(), UuidFactoryImpl.INSTANCE), managedInstanceChecker));
@Test
public void verify_definition() {
TestRequest request = newRequest()
.setParam(PARAM_GROUP_NAME, "newname");
+ loginAsAdmin();
assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("The 'currentName' parameter is missing");
.hasMessage("Default group 'sonar-users' cannot be used to perform this action");
}
+ @Test
+ public void fail_if_instance_is_externally_managed() {
+ loginAsAdmin();
+ BadRequestException exception = BadRequestException.create("Not allowed");
+ doThrow(exception).when(managedInstanceChecker).throwIfInstanceIsManaged();
+ TestRequest testRequest = newRequest();
+ assertThatThrownBy(testRequest::execute)
+ .isEqualTo(exception);
+ }
+
private TestRequest newRequest() {
return ws.newRequest();
}
--- /dev/null
+/*
+ * 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.management;
+
+import org.sonar.server.exceptions.BadRequestException;
+
+public class ManagedInstanceChecker {
+
+ private final ManagedInstanceService managedInstanceService;
+
+ public ManagedInstanceChecker(ManagedInstanceService managedInstanceService) {
+ this.managedInstanceService = managedInstanceService;
+ }
+
+ public void throwIfInstanceIsManaged() {
+ BadRequestException.checkRequest(!managedInstanceService.isInstanceExternallyManaged(), "Operation not allowed when the instance is externally managed.");
+ }
+}
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.user.UserSession;
import static java.lang.String.format;
private final DbClient dbClient;
private final UserSession userSession;
private final GroupWsSupport support;
+ private final ManagedInstanceChecker managedInstanceChecker;
- public AddUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) {
+ public AddUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support, ManagedInstanceChecker managedInstanceChecker) {
this.dbClient = dbClient;
this.userSession = userSession;
this.support = support;
+ this.managedInstanceChecker = managedInstanceChecker;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
- GroupDto group = support.findGroupDto(dbSession, request);
userSession.checkLoggedIn().checkPermission(ADMINISTER);
+ managedInstanceChecker.throwIfInstanceIsManaged();
+ GroupDto group = support.findGroupDto(dbSession, request);
String login = request.mandatoryParam(PARAM_LOGIN);
UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, login);
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.user.UserSession;
import org.sonarqube.ws.UserGroups;
private final DbClient dbClient;
private final UserSession userSession;
private final GroupService groupService;
+ private final ManagedInstanceChecker managedInstanceChecker;
- public CreateAction(DbClient dbClient, UserSession userSession, GroupService groupService) {
+ public CreateAction(DbClient dbClient, UserSession userSession, GroupService groupService, ManagedInstanceChecker managedInstanceService) {
this.dbClient = dbClient;
this.userSession = userSession;
this.groupService = groupService;
+ this.managedInstanceChecker = managedInstanceService;
}
@Override
try (DbSession dbSession = dbClient.openSession(false)) {
userSession.checkPermission(ADMINISTER);
-
+ managedInstanceChecker.throwIfInstanceIsManaged();
String groupName = request.mandatoryParam(PARAM_GROUP_NAME);
String groupDescription = request.param(PARAM_GROUP_DESCRIPTION);
GroupDto group = groupService.createGroup(dbSession, groupName, groupDescription);
*/
package org.sonar.server.usergroups.ws;
+import java.util.Set;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.db.DbSession;
import org.sonar.db.permission.GlobalPermission;
import org.sonar.db.user.GroupDto;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.management.ManagedInstanceService;
import org.sonar.server.user.UserSession;
import static java.lang.String.format;
private final DbClient dbClient;
private final UserSession userSession;
private final GroupService groupService;
+ private final ManagedInstanceService managedInstanceService;
- public DeleteAction(DbClient dbClient, UserSession userSession, GroupService groupService) {
+ public DeleteAction(DbClient dbClient, UserSession userSession, GroupService groupService, ManagedInstanceService managedInstanceService) {
this.dbClient = dbClient;
this.userSession = userSession;
this.groupService = groupService;
+ this.managedInstanceService = managedInstanceService;
}
@Override
public void handle(Request request, Response response) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
userSession.checkPermission(GlobalPermission.ADMINISTER);
-
GroupDto group = findGroupOrThrow(request, dbSession);
+ checkIfInstanceAndGroupAreManaged(dbSession, group);
groupService.delete(dbSession, group);
dbSession.commit();
}
}
+ private void checkIfInstanceAndGroupAreManaged(DbSession dbSession, GroupDto group) {
+ boolean isGroupManaged = managedInstanceService.getGroupUuidToManaged(dbSession, Set.of(group.getUuid())).getOrDefault(group.getUuid(), false);
+ if (isGroupManaged) {
+ throw BadRequestException.create("Deleting managed groups is not allowed.");
+ }
+ }
+
private GroupDto findGroupOrThrow(Request request, DbSession dbSession) {
String groupName = request.mandatoryParam(PARAM_GROUP_NAME);
return groupService.findGroup(dbSession, groupName)
+++ /dev/null
-package org.sonar.server.usergroups.ws;
-
-import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.management.ManagedInstanceService;
-
-public class ManagedInstanceChecker {
-
- private final ManagedInstanceService managedInstanceService;
-
- public ManagedInstanceChecker(ManagedInstanceService managedInstanceService) {
- this.managedInstanceService = managedInstanceService;
- }
-
- public void checkInstanceIsNotExternallyManaged() {
- BadRequestException.checkRequest(!managedInstanceService.isInstanceExternallyManaged(), "Operation not allowed when instance is externally managed.");
- }
-}
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.user.UserSession;
import static java.lang.String.format;
private final UserSession userSession;
private final GroupWsSupport support;
- public RemoveUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) {
+ private final ManagedInstanceChecker managedInstanceChecker;
+
+ public RemoveUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support, ManagedInstanceChecker managedInstanceChecker) {
this.dbClient = dbClient;
this.userSession = userSession;
this.support = support;
+ this.managedInstanceChecker = managedInstanceChecker;
}
@Override
userSession.checkLoggedIn();
try (DbSession dbSession = dbClient.openSession(false)) {
- GroupDto group = support.findGroupDto(dbSession, request);
userSession.checkPermission(GlobalPermission.ADMINISTER);
+ managedInstanceChecker.throwIfInstanceIsManaged();
+ GroupDto group = support.findGroupDto(dbSession, request);
support.checkGroupIsNotDefault(dbSession, group);
String login = request.mandatoryParam(PARAM_LOGIN);
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.user.UserSession;
import org.sonarqube.ws.UserGroups;
private final UserSession userSession;
private final GroupService groupService;
- public UpdateAction(DbClient dbClient, UserSession userSession, GroupService groupService) {
+ private final ManagedInstanceChecker managedInstanceChecker;
+
+ public UpdateAction(DbClient dbClient, UserSession userSession, GroupService groupService, ManagedInstanceChecker managedInstanceChecker) {
this.dbClient = dbClient;
this.userSession = userSession;
this.groupService = groupService;
+ this.managedInstanceChecker = managedInstanceChecker;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
+ userSession.checkPermission(ADMINISTER);
+ managedInstanceChecker.throwIfInstanceIsManaged();
String currentName = request.mandatoryParam(PARAM_GROUP_CURRENT_NAME);
GroupDto group = dbClient.groupDao().selectByName(dbSession, currentName)
.orElseThrow(() -> new NotFoundException(format("Could not find a user group with name '%s'.", currentName)));
- userSession.checkPermission(ADMINISTER);
String newName = request.param(PARAM_GROUP_NAME);
String description = request.param(PARAM_GROUP_DESCRIPTION);
package org.sonar.server.usergroups.ws;
import org.sonar.core.platform.Module;
+import org.sonar.server.management.ManagedInstanceChecker;
public class UserGroupsModule extends Module {
add(
UserGroupsWs.class,
GroupWsSupport.class,
+ ManagedInstanceChecker.class,
GroupService.class,
// actions
SearchAction.class,
--- /dev/null
+/*
+ * 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.management;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.sonar.server.exceptions.BadRequestException;
+
+import static org.assertj.core.api.Assertions.assertThatNoException;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ManagedInstanceCheckerTest {
+
+ @Mock
+ private ManagedInstanceService managedInstanceService;
+
+ @InjectMocks
+ private ManagedInstanceChecker managedInstanceChecker;
+
+ @Test
+ public void throwIfInstanceIsManaged_whenInstanceExternallyManaged_throws() {
+ when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(true);
+ assertThatThrownBy(() -> managedInstanceChecker.throwIfInstanceIsManaged())
+ .isInstanceOf(BadRequestException.class)
+ .hasMessage("Operation not allowed when the instance is externally managed.");
+ }
+
+ @Test
+ public void throwIfInstanceIsManaged_whenInstanceNotExternallyManaged_doesntThrow() {
+ when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(false);
+ assertThatNoException().isThrownBy(() -> managedInstanceChecker.throwIfInstanceIsManaged());
+ }
+}