import org.sonar.server.authentication.CredentialsLocalAuthentication;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.EsTester;
+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.tester.UserSessionRule;
import org.sonar.server.user.NewUserNotifier;
import org.sonar.server.user.UserUpdater;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+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.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.user.index.UserIndexDefinition.FIELD_EMAIL;
import static org.sonar.server.user.index.UserIndexDefinition.FIELD_LOGIN;
private final UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());
private GroupDto defaultGroup;
private final CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient(), settings.asConfig());
+
+ private final ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
private final WsActionTester tester = new WsActionTester(new CreateAction(db.getDbClient(), new UserUpdater(mock(NewUserNotifier.class),
- db.getDbClient(), userIndexer, new DefaultGroupFinder(db.getDbClient()), settings.asConfig(), new NoOpAuditPersister(), localAuthentication), userSessionRule));
+ db.getDbClient(), userIndexer, new DefaultGroupFinder(db.getDbClient()), settings.asConfig(), new NoOpAuditPersister(), localAuthentication), userSessionRule, managedInstanceChecker));
@Before
public void setUp() {
.hasMessage("Insufficient privileges");
}
+ @Test
+ public void handle_whenInstanceManaged_shouldThrowBadRequestException() {
+ BadRequestException badRequestException = BadRequestException.create("message");
+ doThrow(badRequestException).when(managedInstanceChecker).throwIfInstanceIsManaged();
+
+ logInAsSystemAdministrator();
+
+ CreateRequest request = CreateRequest.builder()
+ .setLogin("pipo")
+ .setName("John")
+ .setPassword("1234")
+ .build();
+
+ assertThatThrownBy(() -> call(request))
+ .isEqualTo(badRequestException);
+ }
+
+ @Test
+ public void handle_whenInstanceManagedAndNotSystemAdministrator_shouldThrowUnauthorizedException() {
+ CreateRequest request = CreateRequest.builder()
+ .setLogin("pipo")
+ .setName("John")
+ .setPassword("1234")
+ .build();
+
+ assertThatThrownBy(() -> call(request))
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Authentication is required");
+ verify(managedInstanceChecker, never()).throwIfInstanceIsManaged();
+ }
+
@Test
public void test_definition() {
WebService.Action action = tester.getDef();
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.tester.UserSessionRule;
import org.sonar.server.user.ExternalIdentity;
import org.sonar.server.user.index.UserIndexDefinition;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+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.sonar.db.property.PropertyTesting.newUserPropertyDto;
import static org.sonar.server.user.index.UserIndexDefinition.FIELD_ACTIVE;
import static org.sonar.server.user.index.UserIndexDefinition.FIELD_UUID;
private final DbSession dbSession = db.getSession();
private final UserAnonymizer userAnonymizer = new UserAnonymizer(db.getDbClient(), () -> "anonymized");
private final UserDeactivator userDeactivator = new UserDeactivator(dbClient, userIndexer, userSession, userAnonymizer);
- private final WsActionTester ws = new WsActionTester(new DeactivateAction(dbClient, userSession, new UserJsonWriter(userSession), userDeactivator));
+ private final ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
+ private final WsActionTester ws = new WsActionTester(new DeactivateAction(dbClient, userSession, new UserJsonWriter(userSession), userDeactivator, managedInstanceChecker));
@Test
public void deactivate_user_and_delete_their_related_data() {
assertThat(db.getDbClient().scimUserDao().findByUserUuid(dbSession, user.getUuid())).isEmpty();
}
+ @Test
+ public void handle_whenUserManagedAndInstanceManaged_shouldThrowBadRequestException() {
+ BadRequestException badRequestException = BadRequestException.create("message");
+ doThrow(badRequestException).when(managedInstanceChecker).throwIfInstanceIsManaged();
+
+ createAdminUser();
+ logInAsSystemAdministrator();
+ UserDto user = db.users().insertUser(u -> u.setLocal(false));
+
+ assertThatThrownBy(() -> deactivate(user.getLogin()))
+ .isEqualTo(badRequestException);
+ }
+
+ @Test
+ public void handle_whenInstanceManagedAndNotSystemAdministrator_shouldThrowUnauthorizedException() {
+ UserDto userDto = db.users().insertUser();
+ String login = userDto.getLogin();
+
+ assertThatThrownBy(() -> deactivate(login))
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Authentication is required");
+ verify(managedInstanceChecker, never()).throwIfInstanceIsManaged();
+ }
+
private void logInAsSystemAdministrator() {
userSession.logIn().setSystemAdministrator();
}
import org.sonar.db.user.UserDto;
import org.sonar.server.authentication.CredentialsLocalAuthentication;
import org.sonar.server.es.EsTester;
+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.tester.UserSessionRule;
import org.sonar.server.user.NewUserNotifier;
import org.sonar.server.user.UserUpdater;
import static java.util.Collections.singletonList;
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.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.sonar.db.user.UserTesting.newUserDto;
public class UpdateActionIT {
private final DbSession dbSession = db.getSession();
private final UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
private final CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient(), settings.asConfig());
+ private final ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
private final WsActionTester ws = new WsActionTester(new UpdateAction(
new UserUpdater(mock(NewUserNotifier.class), dbClient, userIndexer, new DefaultGroupFinder(db.getDbClient()), settings.asConfig(), null, localAuthentication),
- userSession, new UserJsonWriter(userSession), dbClient));
+ userSession, new UserJsonWriter(userSession), dbClient, managedInstanceChecker));
@Before
public void setUp() {
.hasMessage("Email 'invalid-email' is not valid");
}
+ @Test
+ public void handle_whenInstanceManaged_shouldThrowBadRequestException() {
+ BadRequestException badRequestException = BadRequestException.create("message");
+ doThrow(badRequestException).when(managedInstanceChecker).throwIfInstanceIsManaged();
+
+ TestRequest updateRequest = ws.newRequest();
+
+ assertThatThrownBy(updateRequest::execute)
+ .isEqualTo(badRequestException);
+ }
+
+ @Test
+ public void handle_whenInstanceManagedAndNotSystemAdministrator_shouldThrowUnauthorizedException() {
+ userSession.anonymous();
+
+ TestRequest updateRequest = ws.newRequest();
+
+ assertThatThrownBy(updateRequest::execute)
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Authentication is required");
+ verify(managedInstanceChecker, never()).throwIfInstanceIsManaged();
+ }
+
@Test
public void test_definition() {
WebService.Action action = ws.getDef();
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.internal.MapSettings;
-import org.sonar.auth.ldap.LdapSettingsManager;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.server.authentication.IdentityProviderRepositoryRule;
import org.sonar.server.authentication.TestIdentityProvider;
import org.sonar.server.es.EsTester;
+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.tester.UserSessionRule;
import org.sonar.server.user.NewUserNotifier;
import org.sonar.server.user.UserUpdater;
import static com.google.common.collect.Lists.newArrayList;
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.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.sonar.db.user.UserTesting.newUserDto;
public class UpdateIdentityProviderActionIT {
private final UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
private final CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(dbClient, settings.asConfig());
- private final LdapSettingsManager ldapSettingsManager = mock(LdapSettingsManager.class);
+ private final ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
private final WsActionTester underTest = new WsActionTester(new UpdateIdentityProviderAction(dbClient, identityProviderRepository,
new UserUpdater(mock(NewUserNotifier.class), dbClient, userIndexer, new DefaultGroupFinder(db.getDbClient()), settings.asConfig(), null, localAuthentication),
- userSession));
+ userSession, managedInstanceChecker));
@Test
public void change_identity_provider_of_a_local_user_all_params() {
.isInstanceOf(ForbiddenException.class);
}
+ @Test
+ public void handle_whenInstanceManaged_shouldThrowBadRequestException() {
+ BadRequestException badRequestException = BadRequestException.create("message");
+ doThrow(badRequestException).when(managedInstanceChecker).throwIfInstanceIsManaged();
+
+ TestRequest request = underTest.newRequest();
+
+ assertThatThrownBy(request::execute)
+ .isEqualTo(badRequestException);
+ }
+
+ @Test
+ public void handle_whenInstanceManagedAndNotSystemAdministrator_shouldThrowUnauthorizedException() {
+ userSession.anonymous();
+
+ TestRequest request = underTest.newRequest();
+
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Authentication is required");
+ verify(managedInstanceChecker, never()).throwIfInstanceIsManaged();
+ }
+
private void createUser(boolean local, String login, String externalLogin, String externalIdentityProvider) {
UserDto userDto = newUserDto()
.setEmail("john@email.com")
import org.sonar.db.DbTester;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
+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.tester.UserSessionRule;
import org.sonar.server.user.NewUserNotifier;
import org.sonar.server.user.UserUpdater;
import org.sonar.server.user.index.UserIndexer;
+import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
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.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
public class UpdateLoginActionIT {
@Rule
public UserSessionRule userSession = UserSessionRule.standalone().logIn().setSystemAdministrator();
+ private final ManagedInstanceChecker managedInstanceChecker = mock(ManagedInstanceChecker.class);
private final WsActionTester ws = new WsActionTester(new UpdateLoginAction(db.getDbClient(), userSession,
- new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), new UserIndexer(db.getDbClient(), es.client()), null, null, null, null)));
+ new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), new UserIndexer(db.getDbClient(), es.client()), null, null, null, null), managedInstanceChecker));
@Test
public void update_login_from_sonarqube_account_when_user_is_local() {
assertThat(response.getInput()).isEmpty();
}
+ @Test
+ public void handle_whenInstanceManaged_shouldThrowBadRequestException() {
+ BadRequestException badRequestException = BadRequestException.create("message");
+ doThrow(badRequestException).when(managedInstanceChecker).throwIfInstanceIsManaged();
+
+ TestRequest request = ws.newRequest();
+
+ assertThatThrownBy(request::execute)
+ .isEqualTo(badRequestException);
+ }
+
+ @Test
+ public void handle_whenInstanceManagedAndNotSystemAdministrator_shouldThrowUnauthorizedException() {
+ userSession.anonymous();
+
+ TestRequest request = ws.newRequest();
+
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Authentication is required");
+ verify(managedInstanceChecker, never()).throwIfInstanceIsManaged();
+ }
+
@Test
public void test_definition() {
WebService.Action def = ws.getDef();
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.user.ExternalIdentity;
import org.sonar.server.user.NewUser;
import org.sonar.server.user.UserSession;
private final DbClient dbClient;
private final UserUpdater userUpdater;
private final UserSession userSession;
+ private final ManagedInstanceChecker managedInstanceChecker;
- public CreateAction(DbClient dbClient, UserUpdater userUpdater, UserSession userSession) {
+ public CreateAction(DbClient dbClient, UserUpdater userUpdater, UserSession userSession, ManagedInstanceChecker managedInstanceService) {
this.dbClient = dbClient;
this.userUpdater = userUpdater;
this.userSession = userSession;
+ this.managedInstanceChecker = managedInstanceService;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
userSession.checkLoggedIn().checkIsSystemAdministrator();
+ managedInstanceChecker.throwIfInstanceIsManaged();
CreateRequest createRequest = toWsRequest(request);
checkArgument(isValidIfPresent(createRequest.getEmail()), "Email '%s' is not valid", createRequest.getEmail());
writeProtobuf(doHandle(createRequest), request, response);
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.user.UserSession;
import static java.util.Collections.singletonList;
private final UserSession userSession;
private final UserJsonWriter userWriter;
private final UserDeactivator userDeactivator;
+ private final ManagedInstanceChecker managedInstanceChecker;
public DeactivateAction(DbClient dbClient, UserSession userSession, UserJsonWriter userWriter,
- UserDeactivator userDeactivator) {
+ UserDeactivator userDeactivator, ManagedInstanceChecker managedInstanceChecker) {
this.dbClient = dbClient;
this.userSession = userSession;
this.userWriter = userWriter;
this.userDeactivator = userDeactivator;
+ this.managedInstanceChecker = managedInstanceChecker;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
String login;
-
userSession.checkLoggedIn().checkIsSystemAdministrator();
login = request.mandatoryParam(PARAM_LOGIN);
checkRequest(!login.equals(userSession.getLogin()), "Self-deactivation is not possible");
-
try (DbSession dbSession = dbClient.openSession(false)) {
+ preventManagedUserDeactivationIfManagedInstance(dbSession, login);
boolean shouldAnonymize = request.mandatoryParamAsBoolean(PARAM_ANONYMIZE);
UserDto userDto = shouldAnonymize
? userDeactivator.deactivateUserWithAnonymization(dbSession, login)
}
}
+ private void preventManagedUserDeactivationIfManagedInstance(DbSession dbSession, String login) {
+ UserDto userDto = dbClient.userDao().selectByLogin(dbSession, login);
+ if (userDto != null && !userDto.isLocal()) {
+ managedInstanceChecker.throwIfInstanceIsManaged();
+ }
+ }
+
private void writeResponse(Response response, String login) {
try (DbSession dbSession = dbClient.openSession(false)) {
UserDto user = dbClient.userDao().selectByLogin(dbSession, login);
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.user.UpdateUser;
import org.sonar.server.user.UserSession;
import org.sonar.server.user.UserUpdater;
private final UserSession userSession;
private final UserJsonWriter userWriter;
private final DbClient dbClient;
+ private final ManagedInstanceChecker managedInstanceChecker;
- public UpdateAction(UserUpdater userUpdater, UserSession userSession, UserJsonWriter userWriter, DbClient dbClient) {
+ public UpdateAction(UserUpdater userUpdater, UserSession userSession, UserJsonWriter userWriter, DbClient dbClient,
+ ManagedInstanceChecker managedInstanceChecker) {
this.userUpdater = userUpdater;
this.userSession = userSession;
this.userWriter = userWriter;
this.dbClient = dbClient;
+ this.managedInstanceChecker = managedInstanceChecker;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
userSession.checkLoggedIn().checkIsSystemAdministrator();
+ managedInstanceChecker.throwIfInstanceIsManaged();
UpdateRequest updateRequest = toWsRequest(request);
checkArgument(isValidIfPresent(updateRequest.getEmail()), "Email '%s' is not valid", updateRequest.getEmail());
try (DbSession dbSession = dbClient.openSession(false)) {
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.user.ExternalIdentity;
import org.sonar.server.user.UpdateUser;
import org.sonar.server.user.UserSession;
private final DbClient dbClient;
private final IdentityProviderRepository identityProviderRepository;
-
private final UserUpdater userUpdater;
private final UserSession userSession;
+ private final ManagedInstanceChecker managedInstanceChecker;
- public UpdateIdentityProviderAction(DbClient dbClient, IdentityProviderRepository identityProviderRepository, UserUpdater userUpdater, UserSession userSession) {
+ public UpdateIdentityProviderAction(DbClient dbClient, IdentityProviderRepository identityProviderRepository, UserUpdater userUpdater, UserSession userSession, ManagedInstanceChecker managedInstanceChecker) {
this.dbClient = dbClient;
this.identityProviderRepository = identityProviderRepository;
this.userUpdater = userUpdater;
this.userSession = userSession;
+ this.managedInstanceChecker = managedInstanceChecker;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
userSession.checkLoggedIn().checkIsSystemAdministrator();
+ managedInstanceChecker.throwIfInstanceIsManaged();
UpdateIdentityProviderRequest wsRequest = toWsRequest(request);
doHandle(wsRequest);
response.noContent();
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.user.UpdateUser;
import org.sonar.server.user.UserSession;
import org.sonar.server.user.UserUpdater;
private final DbClient dbClient;
private final UserSession userSession;
private final UserUpdater userUpdater;
+ private final ManagedInstanceChecker managedInstanceChecker;
- public UpdateLoginAction(DbClient dbClient, UserSession userSession, UserUpdater userUpdater) {
+ public UpdateLoginAction(DbClient dbClient, UserSession userSession, UserUpdater userUpdater,
+ ManagedInstanceChecker managedInstanceChecker) {
this.dbClient = dbClient;
this.userSession = userSession;
this.userUpdater = userUpdater;
+ this.managedInstanceChecker = managedInstanceChecker;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
userSession.checkLoggedIn().checkIsSystemAdministrator();
+ managedInstanceChecker.throwIfInstanceIsManaged();
String login = request.mandatoryParam(PARAM_LOGIN);
String newLogin = request.mandatoryParam(PARAM_NEW_LOGIN);
try (DbSession dbSession = dbClient.openSession(false)) {