diff options
author | Antoine Vigneau <antoine.vigneau@sonarsource.com> | 2023-12-21 17:19:14 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-12-22 20:03:03 +0000 |
commit | e7ab4f4c88e51b63185fee61edb9f9154baf802e (patch) | |
tree | 461e2887763a7915186db0207d672d260e63323b /server/sonar-webserver-common/src | |
parent | 7796b0b6b9f2b16043915ec5b125c594d40006c8 (diff) | |
download | sonarqube-e7ab4f4c88e51b63185fee61edb9f9154baf802e.tar.gz sonarqube-e7ab4f4c88e51b63185fee61edb9f9154baf802e.zip |
SONAR-21250 Add validation checks for the Gitlab configuration
Diffstat (limited to 'server/sonar-webserver-common/src')
5 files changed, 190 insertions, 68 deletions
diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/gitlab/config/GitlabConfigurationServiceIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/gitlab/config/GitlabConfigurationServiceIT.java index 39291879fa7..e18baa8734a 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/gitlab/config/GitlabConfigurationServiceIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/gitlab/config/GitlabConfigurationServiceIT.java @@ -22,6 +22,7 @@ package org.sonar.server.common.gitlab.config; import com.google.common.base.Strings; import java.util.LinkedHashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; import org.junit.Before; @@ -30,6 +31,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator; import org.sonar.auth.gitlab.GitLabIdentityProvider; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -43,12 +45,15 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import static org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator.ValidationMode.AUTH_ONLY; +import static org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator.ValidationMode.COMPLETE; import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP; import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_APPLICATION_ID; import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_ENABLED; @@ -61,6 +66,8 @@ import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_URL; import static org.sonar.server.common.NonNullUpdatedValue.withValueOrThrow; import static org.sonar.server.common.UpdatedValue.withValue; import static org.sonar.server.common.gitlab.config.GitlabConfigurationService.UNIQUE_GITLAB_CONFIGURATION_ID; +import static org.sonar.server.common.gitlab.config.ProvisioningType.AUTO_PROVISIONING; +import static org.sonar.server.common.gitlab.config.ProvisioningType.JIT; import static org.sonar.server.common.gitlab.config.UpdateGitlabConfigurationRequest.builder; @RunWith(MockitoJUnitRunner.class) @@ -72,14 +79,18 @@ public class GitlabConfigurationServiceIT { @Mock private ManagedInstanceService managedInstanceService; + @Mock + private GitlabGlobalSettingsValidator gitlabGlobalSettingsValidator; + private GitlabConfigurationService gitlabConfigurationService; @Before public void setUp() { when(managedInstanceService.getProviderName()).thenReturn("gitlab"); gitlabConfigurationService = new GitlabConfigurationService( + dbTester.getDbClient(), managedInstanceService, - dbTester.getDbClient()); + gitlabGlobalSettingsValidator); } @Test @@ -99,7 +110,7 @@ public class GitlabConfigurationServiceIT { @Test public void getConfiguration_whenConfigurationSet_returnsConfig() { - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING)); GitlabConfiguration configuration = gitlabConfigurationService.getConfiguration("gitlab-configuration"); @@ -119,7 +130,7 @@ public class GitlabConfigurationServiceIT { assertThat(configuration.url()).isEmpty(); assertThat(configuration.secret()).isEmpty(); assertThat(configuration.synchronizeGroups()).isFalse(); - assertThat(configuration.synchronizationType()).isEqualTo(SynchronizationType.JIT); + assertThat(configuration.provisioningType()).isEqualTo(JIT); assertThat(configuration.allowUsersToSignUp()).isFalse(); assertThat(configuration.provisioningToken()).isNull(); assertThat(configuration.provisioningGroups()).isEmpty(); @@ -127,7 +138,7 @@ public class GitlabConfigurationServiceIT { @Test public void updateConfiguration_whenIdIsNotGitlabConfiguration_throwsException() { - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING)); UpdateGitlabConfigurationRequest updateGitlabConfigurationRequest = builder().gitlabConfigurationId("not-gitlab-configuration").build(); assertThatExceptionOfType(NotFoundException.class) .isThrownBy(() -> gitlabConfigurationService.updateConfiguration(updateGitlabConfigurationRequest)) @@ -144,7 +155,7 @@ public class GitlabConfigurationServiceIT { @Test public void updateConfiguration_whenAllUpdateFieldDefined_updatesEverything() { - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.JIT)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(JIT)); UpdateGitlabConfigurationRequest updateRequest = builder() .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID) @@ -153,7 +164,7 @@ public class GitlabConfigurationServiceIT { .url(withValueOrThrow("url")) .secret(withValueOrThrow("secret")) .synchronizeGroups(withValueOrThrow(true)) - .synchronizationType(withValueOrThrow(SynchronizationType.AUTO_PROVISIONING)) + .provisioningType(withValueOrThrow(AUTO_PROVISIONING)) .allowUserToSignUp(withValueOrThrow(true)) .provisioningToken(withValueOrThrow("provisioningToken")) .provisioningGroups(withValueOrThrow(new LinkedHashSet<>(List.of("group1", "group2", "group3")))) @@ -177,7 +188,7 @@ public class GitlabConfigurationServiceIT { @Test public void updateConfiguration_whenAllUpdateFieldDefinedAndSetToFalse_updatesEverything() { - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING)); verify(managedInstanceService).queueSynchronisationTask(); clearInvocations(managedInstanceService); @@ -185,7 +196,7 @@ public class GitlabConfigurationServiceIT { .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID) .enabled(withValueOrThrow(false)) .synchronizeGroups(withValueOrThrow(false)) - .synchronizationType(withValueOrThrow(SynchronizationType.JIT)) + .provisioningType(withValueOrThrow(JIT)) .allowUserToSignUp(withValueOrThrow(false)) .build(); @@ -206,14 +217,14 @@ public class GitlabConfigurationServiceIT { dbTester.getDbClient().externalGroupDao().insert(dbSession, new ExternalGroupDto("34", "34", GitLabIdentityProvider.KEY)); dbSession.commit(); - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING)); verify(managedInstanceService).queueSynchronisationTask(); reset(managedInstanceService); UpdateGitlabConfigurationRequest updateRequest = builder() .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID) .provisioningToken(withValue(null)) - .synchronizationType(withValueOrThrow(SynchronizationType.JIT)) + .provisioningType(withValueOrThrow(JIT)) .build(); gitlabConfigurationService.updateConfiguration(updateRequest); @@ -224,7 +235,7 @@ public class GitlabConfigurationServiceIT { @Test public void updateConfiguration_whenSwitchingToAutoProvisioningAndTheConfigIsNotEnabled_shouldThrow() { - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.JIT)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(JIT)); UpdateGitlabConfigurationRequest disableRequest = builder() .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID) @@ -235,7 +246,7 @@ public class GitlabConfigurationServiceIT { UpdateGitlabConfigurationRequest updateRequest = builder() .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID) - .synchronizationType(withValueOrThrow(SynchronizationType.AUTO_PROVISIONING)) + .provisioningType(withValueOrThrow(AUTO_PROVISIONING)) .build(); assertThatThrownBy(() -> gitlabConfigurationService.updateConfiguration(updateRequest)) @@ -246,7 +257,7 @@ public class GitlabConfigurationServiceIT { @Test public void updateConfiguration_whenSwitchingToAutoProvisioningAndProvisioningTokenIsNotDefined_shouldThrow() { - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.JIT)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(JIT)); UpdateGitlabConfigurationRequest removeTokenRequest = builder() .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID) @@ -257,7 +268,7 @@ public class GitlabConfigurationServiceIT { UpdateGitlabConfigurationRequest updateRequest = builder() .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID) - .synchronizationType(withValueOrThrow(SynchronizationType.AUTO_PROVISIONING)) + .provisioningType(withValueOrThrow(AUTO_PROVISIONING)) .build(); assertThatThrownBy(() -> gitlabConfigurationService.updateConfiguration(updateRequest)) @@ -274,7 +285,7 @@ public class GitlabConfigurationServiceIT { assertThat(configuration.url()).isEqualTo("url"); assertThat(configuration.secret()).isEqualTo("secret"); assertThat(configuration.synchronizeGroups()).isTrue(); - assertThat(configuration.synchronizationType()).isEqualTo(SynchronizationType.AUTO_PROVISIONING); + assertThat(configuration.provisioningType()).isEqualTo(AUTO_PROVISIONING); assertThat(configuration.allowUsersToSignUp()).isTrue(); assertThat(configuration.provisioningToken()).isEqualTo("provisioningToken"); assertThat(configuration.provisioningGroups()).containsExactlyInAnyOrder("group1", "group2", "group3"); @@ -282,7 +293,7 @@ public class GitlabConfigurationServiceIT { @Test public void createConfiguration_whenConfigurationAlreadyExists_shouldThrow() { - GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING); + GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING); gitlabConfigurationService.createConfiguration(gitlabConfiguration); assertThatThrownBy(() -> gitlabConfigurationService.createConfiguration(gitlabConfiguration)) @@ -292,11 +303,11 @@ public class GitlabConfigurationServiceIT { @Test public void createConfiguration_whenAutoProvisioning_shouldCreateCorrectConfigurationAndScheduleSync() { - GitlabConfiguration configuration = buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING); + GitlabConfiguration configuration = buildGitlabConfiguration(AUTO_PROVISIONING); GitlabConfiguration createdConfiguration = gitlabConfigurationService.createConfiguration(configuration); - assertThat(createdConfiguration).isEqualTo(configuration); + assertConfigurationIsCorrect(configuration, createdConfiguration); verifyCommonSettings(configuration); @@ -313,7 +324,7 @@ public class GitlabConfigurationServiceIT { "url", "secret", true, - SynchronizationType.AUTO_PROVISIONING, + AUTO_PROVISIONING, true, null, Set.of("group1", "group2", "group3")); @@ -326,7 +337,7 @@ public class GitlabConfigurationServiceIT { @Test public void createConfiguration_whenInstanceIsExternallyManaged_shouldThrow() { - GitlabConfiguration configuration = buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING); + GitlabConfiguration configuration = buildGitlabConfiguration(AUTO_PROVISIONING); when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(true); when(managedInstanceService.getProviderName()).thenReturn("not-gitlab"); @@ -339,11 +350,11 @@ public class GitlabConfigurationServiceIT { @Test public void createConfiguration_whenJitProvisioning_shouldCreateCorrectConfiguration() { - GitlabConfiguration configuration = buildGitlabConfiguration(SynchronizationType.JIT); + GitlabConfiguration configuration = buildGitlabConfiguration(JIT); GitlabConfiguration createdConfiguration = gitlabConfigurationService.createConfiguration(configuration); - assertThat(createdConfiguration).isEqualTo(configuration); + assertConfigurationIsCorrect(configuration, createdConfiguration); verifyCommonSettings(configuration); verifyNoInteractions(managedInstanceService); @@ -359,14 +370,14 @@ public class GitlabConfigurationServiceIT { "url", "secret", true, - SynchronizationType.JIT, + JIT, true, null, Set.of("group1", "group2", "group3")); GitlabConfiguration createdConfiguration = gitlabConfigurationService.createConfiguration(configuration); - assertThat(createdConfiguration).isEqualTo(configuration); + assertConfigurationIsCorrect(configuration, createdConfiguration); verifyCommonSettings(configuration); verifyNoInteractions(managedInstanceService); @@ -383,7 +394,7 @@ public class GitlabConfigurationServiceIT { verifySettingWasSet(GITLAB_AUTH_PROVISIONING_TOKEN, Strings.nullToEmpty(configuration.provisioningToken())); verifySettingWasSet(GITLAB_AUTH_PROVISIONING_GROUPS, String.join(",", configuration.provisioningGroups())); verifySettingWasSet(GITLAB_AUTH_PROVISIONING_ENABLED, - String.valueOf(configuration.synchronizationType().equals(SynchronizationType.AUTO_PROVISIONING))); + String.valueOf(configuration.provisioningType().equals(AUTO_PROVISIONING))); } private void verifySettingWasSet(String setting, @Nullable String value) { @@ -410,7 +421,7 @@ public class GitlabConfigurationServiceIT { dbTester.getDbClient().externalGroupDao().insert(dbSession, new ExternalGroupDto("12", "12", GitLabIdentityProvider.KEY)); dbTester.getDbClient().externalGroupDao().insert(dbSession, new ExternalGroupDto("34", "34", GitLabIdentityProvider.KEY)); dbSession.commit(); - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING)); gitlabConfigurationService.deleteConfiguration("gitlab-configuration"); assertPropertyIsDeleted(GITLAB_AUTH_ENABLED); @@ -432,7 +443,7 @@ public class GitlabConfigurationServiceIT { @Test public void triggerRun_whenConfigIsCorrect_shouldTriggerSync() { - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING)); reset(managedInstanceService); gitlabConfigurationService.triggerRun(); @@ -442,7 +453,7 @@ public class GitlabConfigurationServiceIT { @Test public void triggerRun_whenConfigIsForJit_shouldThrow() { - gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(SynchronizationType.JIT)); + gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(JIT)); assertThatIllegalStateException() .isThrownBy(() -> gitlabConfigurationService.triggerRun()) @@ -451,7 +462,7 @@ public class GitlabConfigurationServiceIT { @Test public void triggerRun_whenConfigIsDisabled_shouldThrow() { - GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING); + GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING); gitlabConfigurationService.createConfiguration(gitlabConfiguration); gitlabConfigurationService.updateConfiguration(builder().gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID).enabled(withValueOrThrow(false)).build()); @@ -462,7 +473,7 @@ public class GitlabConfigurationServiceIT { @Test public void triggerRun_whenProvisioningTokenIsNotSet_shouldThrow() { - GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(SynchronizationType.AUTO_PROVISIONING); + GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING); gitlabConfigurationService.createConfiguration(gitlabConfiguration); gitlabConfigurationService.updateConfiguration(builder().gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID).provisioningToken(withValue(null)).build()); @@ -471,17 +482,74 @@ public class GitlabConfigurationServiceIT { .withMessage("Provisioning token must be set to enable GitLab provisioning."); } - private static GitlabConfiguration buildGitlabConfiguration(SynchronizationType synchronizationType) { - return new GitlabConfiguration( - UNIQUE_GITLAB_CONFIGURATION_ID, - true, - "applicationId", - "url", - "secret", - true, - synchronizationType, - true, - "provisioningToken", - Set.of("group1", "group2", "group3")); + @Test + public void validate_whenConfigurationIsDisabled_shouldNotValidate() { + GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING); + when(gitlabConfiguration.enabled()).thenReturn(false); + + gitlabConfigurationService.validate(gitlabConfiguration); + + verifyNoInteractions(gitlabGlobalSettingsValidator); + } + + @Test + public void validate_whenConfigurationIsValidAndJIT_returnEmptyOptional() { + GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(JIT); + when(gitlabConfiguration.enabled()).thenReturn(true); + + gitlabConfigurationService.validate(gitlabConfiguration); + + verify(gitlabGlobalSettingsValidator).validate(AUTH_ONLY, gitlabConfiguration.url() + "/api/v4", gitlabConfiguration.provisioningToken()); + } + + @Test + public void validate_whenConfigurationIsValidAndAutoProvisioning_returnEmptyOptional() { + GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING); + when(gitlabConfiguration.enabled()).thenReturn(true); + + gitlabConfigurationService.validate(gitlabConfiguration); + + verify(gitlabGlobalSettingsValidator).validate(COMPLETE, gitlabConfiguration.url() + "/api/v4", gitlabConfiguration.provisioningToken()); + } + + @Test + public void validate_whenConfigurationIsInValid_returnsExceptionMessage() { + GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING); + when(gitlabConfiguration.enabled()).thenReturn(true); + + Exception exception = new IllegalStateException("Invalid configuration"); + when(gitlabConfigurationService.validate(gitlabConfiguration)).thenThrow(exception); + + Optional<String> message = gitlabConfigurationService.validate(gitlabConfiguration); + + assertThat(message).contains("Invalid configuration"); + } + + private static GitlabConfiguration buildGitlabConfiguration(ProvisioningType provisioningType) { + GitlabConfiguration gitlabConfiguration = mock(); + when(gitlabConfiguration.id()).thenReturn("gitlab-configuration"); + when(gitlabConfiguration.enabled()).thenReturn(true); + when(gitlabConfiguration.applicationId()).thenReturn("applicationId"); + when(gitlabConfiguration.url()).thenReturn("url"); + when(gitlabConfiguration.secret()).thenReturn("secret"); + when(gitlabConfiguration.synchronizeGroups()).thenReturn(true); + when(gitlabConfiguration.provisioningType()).thenReturn(provisioningType); + when(gitlabConfiguration.allowUsersToSignUp()).thenReturn(true); + when(gitlabConfiguration.provisioningToken()).thenReturn("provisioningToken"); + when(gitlabConfiguration.provisioningGroups()).thenReturn(new LinkedHashSet<>(Set.of("group1", "group2", "group3"))); + return gitlabConfiguration; + } + + private static void assertConfigurationIsCorrect(GitlabConfiguration expectedConfiguration, GitlabConfiguration actualConfiguration) { + assertThat(actualConfiguration.id()).isEqualTo(expectedConfiguration.id()); + assertThat(actualConfiguration.enabled()).isEqualTo(expectedConfiguration.enabled()); + assertThat(actualConfiguration.applicationId()).isEqualTo(expectedConfiguration.applicationId()); + assertThat(actualConfiguration.url()).isEqualTo(expectedConfiguration.url()); + assertThat(actualConfiguration.secret()).isEqualTo(expectedConfiguration.secret()); + assertThat(actualConfiguration.synchronizeGroups()).isEqualTo(expectedConfiguration.synchronizeGroups()); + assertThat(actualConfiguration.provisioningType()).isEqualTo(expectedConfiguration.provisioningType()); + assertThat(actualConfiguration.allowUsersToSignUp()).isEqualTo(expectedConfiguration.allowUsersToSignUp()); + assertThat(actualConfiguration.provisioningToken()).isEqualTo(expectedConfiguration.provisioningToken()); + assertThat(actualConfiguration.provisioningGroups()).containsExactlyInAnyOrderElementsOf(expectedConfiguration.provisioningGroups()); } } diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/GitlabConfiguration.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/GitlabConfiguration.java index a0f6ab7badd..3e0810e3625 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/GitlabConfiguration.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/GitlabConfiguration.java @@ -35,7 +35,7 @@ public record GitlabConfiguration( boolean synchronizeGroups, - SynchronizationType synchronizationType, + ProvisioningType provisioningType, boolean allowUsersToSignUp, diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/GitlabConfigurationService.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/GitlabConfigurationService.java index 3de2fa14948..41e662f98b3 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/GitlabConfigurationService.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/GitlabConfigurationService.java @@ -26,7 +26,8 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.sonar.api.utils.Preconditions; +import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator; +import org.sonar.api.server.ServerSide; import org.sonar.auth.gitlab.GitLabIdentityProvider; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -38,6 +39,8 @@ import org.sonar.server.management.ManagedInstanceService; import static java.lang.String.format; import static org.apache.commons.lang.StringUtils.isNotBlank; +import static org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator.ValidationMode.AUTH_ONLY; +import static org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator.ValidationMode.COMPLETE; import static org.sonar.api.utils.Preconditions.checkState; import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP; import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_APPLICATION_ID; @@ -48,9 +51,11 @@ import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_PROVISIONING_TOKE import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_SECRET; import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_SYNC_USER_GROUPS; import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_URL; -import static org.sonar.server.common.gitlab.config.SynchronizationType.AUTO_PROVISIONING; +import static org.sonar.server.common.gitlab.config.ProvisioningType.AUTO_PROVISIONING; +import static org.sonar.server.common.gitlab.config.ProvisioningType.JIT; import static org.sonar.server.exceptions.NotFoundException.checkFound; +@ServerSide public class GitlabConfigurationService { private static final List<String> GITLAB_CONFIGURATION_PROPERTIES = List.of( @@ -65,17 +70,20 @@ public class GitlabConfigurationService { GITLAB_AUTH_PROVISIONING_GROUPS); public static final String UNIQUE_GITLAB_CONFIGURATION_ID = "gitlab-configuration"; - private final ManagedInstanceService managedInstanceService; private final DbClient dbClient; + private final ManagedInstanceService managedInstanceService; + private final GitlabGlobalSettingsValidator gitlabGlobalSettingsValidator; - public GitlabConfigurationService(ManagedInstanceService managedInstanceService, DbClient dbClient) { - this.managedInstanceService = managedInstanceService; + public GitlabConfigurationService(DbClient dbClient, + ManagedInstanceService managedInstanceService, GitlabGlobalSettingsValidator gitlabGlobalSettingsValidator) { this.dbClient = dbClient; + this.managedInstanceService = managedInstanceService; + this.gitlabGlobalSettingsValidator = gitlabGlobalSettingsValidator; } public GitlabConfiguration updateConfiguration(UpdateGitlabConfigurationRequest updateRequest) { UpdatedValue<Boolean> provisioningEnabled = - updateRequest.synchronizationType().map(GitlabConfigurationService::shouldEnableAutoProvisioning); + updateRequest.provisioningType().map(GitlabConfigurationService::shouldEnableAutoProvisioning); try (DbSession dbSession = dbClient.openSession(true)) { throwIfConfigurationDoesntExist(dbSession); GitlabConfiguration currentConfiguration = getConfiguration(updateRequest.gitlabConfigurationId(), dbSession); @@ -89,8 +97,8 @@ public class GitlabConfigurationService { setIfDefined(dbSession, GITLAB_AUTH_PROVISIONING_TOKEN, updateRequest.provisioningToken()); setIfDefined(dbSession, GITLAB_AUTH_PROVISIONING_GROUPS, updateRequest.provisioningGroups().map(groups -> String.join(",", groups))); boolean shouldTriggerProvisioning = - provisioningEnabled.orElse(false) && !currentConfiguration.synchronizationType().equals(AUTO_PROVISIONING); - deleteExternalGroupsWhenDisablingAutoProvisioning(dbSession, currentConfiguration, updateRequest.synchronizationType()); + provisioningEnabled.orElse(false) && !currentConfiguration.provisioningType().equals(AUTO_PROVISIONING); + deleteExternalGroupsWhenDisablingAutoProvisioning(dbSession, currentConfiguration, updateRequest.provisioningType()); GitlabConfiguration updatedConfiguration = getConfiguration(UNIQUE_GITLAB_CONFIGURATION_ID, dbSession); if (shouldTriggerProvisioning) { triggerRun(updatedConfiguration); @@ -109,9 +117,10 @@ public class GitlabConfigurationService { private void deleteExternalGroupsWhenDisablingAutoProvisioning( DbSession dbSession, GitlabConfiguration currentConfiguration, - UpdatedValue<SynchronizationType> synchronizationTypeFromUpdate) { - boolean disableAutoProvisioning = synchronizationTypeFromUpdate.map(synchronizationType -> synchronizationType.equals(SynchronizationType.JIT)).orElse(false) - && currentConfiguration.synchronizationType().equals(AUTO_PROVISIONING); + UpdatedValue<ProvisioningType> provisioningTypeFromUpdate) { + boolean disableAutoProvisioning = + provisioningTypeFromUpdate.map(provisioningType -> provisioningType.equals(JIT)).orElse(false) + && currentConfiguration.provisioningType().equals(AUTO_PROVISIONING); if (disableAutoProvisioning) { dbClient.externalGroupDao().deleteByExternalIdentityProvider(dbSession, GitLabIdentityProvider.KEY); } @@ -169,14 +178,14 @@ public class GitlabConfigurationService { checkFound(dbClient.propertiesDao().selectGlobalProperty(dbSession, GITLAB_AUTH_ENABLED), "GitLab configuration doesn't exist."); } - private static SynchronizationType toSynchronizationType(boolean provisioningEnabled) { - return provisioningEnabled ? AUTO_PROVISIONING : SynchronizationType.JIT; + private static ProvisioningType toProvisioningType(boolean provisioningEnabled) { + return provisioningEnabled ? AUTO_PROVISIONING : JIT; } public GitlabConfiguration createConfiguration(GitlabConfiguration configuration) { throwIfConfigurationAlreadyExists(); - boolean enableAutoProvisioning = shouldEnableAutoProvisioning(configuration.synchronizationType()); + boolean enableAutoProvisioning = shouldEnableAutoProvisioning(configuration.provisioningType()); try (DbSession dbSession = dbClient.openSession(false)) { setProperty(dbSession, GITLAB_AUTH_ENABLED, String.valueOf(configuration.enabled())); setProperty(dbSession, GITLAB_AUTH_APPLICATION_ID, configuration.applicationId()); @@ -203,8 +212,8 @@ public class GitlabConfigurationService { }); } - private static boolean shouldEnableAutoProvisioning(SynchronizationType synchronizationType) { - return AUTO_PROVISIONING.equals(synchronizationType); + private static boolean shouldEnableAutoProvisioning(ProvisioningType provisioningType) { + return AUTO_PROVISIONING.equals(provisioningType); } private void setProperty(DbSession dbSession, String propertyName, @Nullable String value) { @@ -221,7 +230,7 @@ public class GitlabConfigurationService { getStringPropertyOrEmpty(dbSession, GITLAB_AUTH_URL), getStringPropertyOrEmpty(dbSession, GITLAB_AUTH_SECRET), getBooleanOrFalse(dbSession, GITLAB_AUTH_SYNC_USER_GROUPS), - toSynchronizationType(getBooleanOrFalse(dbSession, GITLAB_AUTH_PROVISIONING_ENABLED)), + toProvisioningType(getBooleanOrFalse(dbSession, GITLAB_AUTH_PROVISIONING_ENABLED)), getBooleanOrFalse(dbSession, GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP), getStringPropertyOrNull(dbSession, GITLAB_AUTH_PROVISIONING_TOKEN), getProvisioningGroups(dbSession) @@ -244,13 +253,12 @@ public class GitlabConfigurationService { private void triggerRun(GitlabConfiguration gitlabConfiguration) { throwIfConfigIncompleteOrInstanceAlreadyManaged(gitlabConfiguration); managedInstanceService.queueSynchronisationTask(); - } private void throwIfConfigIncompleteOrInstanceAlreadyManaged(GitlabConfiguration configuration) { checkInstanceNotManagedByAnotherProvider(); - Preconditions.checkState(AUTO_PROVISIONING.equals(configuration.synchronizationType()), "Auto provisioning must be activated"); - Preconditions.checkState(configuration.enabled(), getErrorMessage("GitLab authentication must be turned on")); + checkState(AUTO_PROVISIONING.equals(configuration.provisioningType()), "Auto provisioning must be activated"); + checkState(configuration.enabled(), getErrorMessage("GitLab authentication must be turned on")); checkState(isNotBlank(configuration.provisioningToken()), getErrorMessage("Provisioning token must be set")); } @@ -267,4 +275,25 @@ public class GitlabConfigurationService { private static String getErrorMessage(String prefix) { return format("%s to enable GitLab provisioning.", prefix); } + + public Optional<String> validate(GitlabConfiguration gitlabConfiguration) { + if (!gitlabConfiguration.enabled()) { + return Optional.empty(); + } + String url = (gitlabConfiguration.url() + "/api/v4").replace("//", "/"); + try { + gitlabGlobalSettingsValidator.validate( + toValidationMode(gitlabConfiguration.provisioningType()), + url, + gitlabConfiguration.provisioningToken() + ); + } catch (Exception e) { + return Optional.of(e.getMessage()); + } + return Optional.empty(); + } + + private static GitlabGlobalSettingsValidator.ValidationMode toValidationMode(ProvisioningType provisioningType) { + return AUTO_PROVISIONING.equals(provisioningType) ? COMPLETE : AUTH_ONLY; + } } diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/ProvisioningType.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/ProvisioningType.java new file mode 100644 index 00000000000..5548704c7e7 --- /dev/null +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/ProvisioningType.java @@ -0,0 +1,25 @@ +/* + * 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.common.gitlab.config; + +public enum ProvisioningType { + JIT, + AUTO_PROVISIONING +} diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/UpdateGitlabConfigurationRequest.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/UpdateGitlabConfigurationRequest.java index 9e120a5e9a3..6db27f2ba25 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/UpdateGitlabConfigurationRequest.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/gitlab/config/UpdateGitlabConfigurationRequest.java @@ -30,7 +30,7 @@ public record UpdateGitlabConfigurationRequest( NonNullUpdatedValue<String> url, NonNullUpdatedValue<String> secret, NonNullUpdatedValue<Boolean> synchronizeGroups, - NonNullUpdatedValue<SynchronizationType> synchronizationType, + NonNullUpdatedValue<ProvisioningType> provisioningType, NonNullUpdatedValue<Boolean> allowUsersToSignUp, UpdatedValue<String> provisioningToken, NonNullUpdatedValue<Set<String>> provisioningGroups @@ -47,7 +47,7 @@ public record UpdateGitlabConfigurationRequest( private NonNullUpdatedValue<String> url = NonNullUpdatedValue.undefined(); private NonNullUpdatedValue<String> secret = NonNullUpdatedValue.undefined(); private NonNullUpdatedValue<Boolean> synchronizeGroups = NonNullUpdatedValue.undefined(); - private NonNullUpdatedValue<SynchronizationType> synchronizationType = NonNullUpdatedValue.undefined(); + private NonNullUpdatedValue<ProvisioningType> provisioningType = NonNullUpdatedValue.undefined(); private NonNullUpdatedValue<Boolean> allowUserToSignUp = NonNullUpdatedValue.undefined(); private UpdatedValue<String> provisioningToken = UpdatedValue.undefined(); private NonNullUpdatedValue<Set<String>> provisioningGroups = NonNullUpdatedValue.undefined(); @@ -85,8 +85,8 @@ public record UpdateGitlabConfigurationRequest( return this; } - public Builder synchronizationType(NonNullUpdatedValue<SynchronizationType> synchronizationType) { - this.synchronizationType = synchronizationType; + public Builder provisioningType(NonNullUpdatedValue<ProvisioningType> provisioningType) { + this.provisioningType = provisioningType; return this; } @@ -106,7 +106,7 @@ public record UpdateGitlabConfigurationRequest( } public UpdateGitlabConfigurationRequest build() { - return new UpdateGitlabConfigurationRequest(gitlabConfigurationId, enabled, applicationId, url, secret, synchronizeGroups, synchronizationType, allowUserToSignUp, + return new UpdateGitlabConfigurationRequest(gitlabConfigurationId, enabled, applicationId, url, secret, synchronizeGroups, provisioningType, allowUserToSignUp, provisioningToken, provisioningGroups); } } |