]> source.dussan.org Git - sonarqube.git/blob
cb7e8cd888953e4c141a4ee4bad64f6959220845
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.server.common.gitlab.config;
21
22 import com.google.common.base.Strings;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Optional;
26 import java.util.Set;
27 import javax.annotation.Nullable;
28 import org.junit.Before;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.mockito.Mock;
33 import org.mockito.junit.MockitoJUnitRunner;
34 import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator;
35 import org.sonar.auth.gitlab.GitLabIdentityProvider;
36 import org.sonar.db.DbSession;
37 import org.sonar.db.DbTester;
38 import org.sonar.db.user.ExternalGroupDto;
39 import org.sonar.server.exceptions.BadRequestException;
40 import org.sonar.server.exceptions.NotFoundException;
41 import org.sonar.server.management.ManagedInstanceService;
42 import org.sonar.server.setting.ThreadLocalSettings;
43
44 import static org.assertj.core.api.Assertions.assertThat;
45 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
46 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
47 import static org.assertj.core.api.Assertions.assertThatThrownBy;
48 import static org.mockito.Mockito.clearInvocations;
49 import static org.mockito.Mockito.mock;
50 import static org.mockito.Mockito.reset;
51 import static org.mockito.Mockito.times;
52 import static org.mockito.Mockito.verify;
53 import static org.mockito.Mockito.verifyNoInteractions;
54 import static org.mockito.Mockito.verifyNoMoreInteractions;
55 import static org.mockito.Mockito.when;
56 import static org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator.ValidationMode.AUTH_ONLY;
57 import static org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator.ValidationMode.COMPLETE;
58 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_ALLOWED_GROUPS;
59 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP;
60 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_APPLICATION_ID;
61 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_ENABLED;
62 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_PROVISIONING_ENABLED;
63 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_PROVISIONING_TOKEN;
64 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_SECRET;
65 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_SYNC_USER_GROUPS;
66 import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_URL;
67 import static org.sonar.server.common.NonNullUpdatedValue.withValueOrThrow;
68 import static org.sonar.server.common.UpdatedValue.withValue;
69 import static org.sonar.server.common.gitlab.config.GitlabConfigurationService.UNIQUE_GITLAB_CONFIGURATION_ID;
70 import static org.sonar.server.common.gitlab.config.ProvisioningType.AUTO_PROVISIONING;
71 import static org.sonar.server.common.gitlab.config.ProvisioningType.JIT;
72 import static org.sonar.server.common.gitlab.config.UpdateGitlabConfigurationRequest.builder;
73
74 @RunWith(MockitoJUnitRunner.class)
75 public class GitlabConfigurationServiceIT {
76
77   @Rule
78   public DbTester dbTester = DbTester.create();
79
80   @Mock
81   private ManagedInstanceService managedInstanceService;
82
83   @Mock
84   private GitlabGlobalSettingsValidator gitlabGlobalSettingsValidator;
85
86   @Mock
87   private ThreadLocalSettings threadLocalSettings;
88
89   private GitlabConfigurationService gitlabConfigurationService;
90
91   @Before
92   public void setUp() {
93     when(managedInstanceService.getProviderName()).thenReturn("gitlab");
94     gitlabConfigurationService = new GitlabConfigurationService(
95       dbTester.getDbClient(),
96       managedInstanceService,
97       gitlabGlobalSettingsValidator,
98       threadLocalSettings);
99   }
100
101   @Test
102   public void getConfiguration_whenIdIsNotGitlabConfiguration_throwsException() {
103     assertThatExceptionOfType(NotFoundException.class)
104       .isThrownBy(() -> gitlabConfigurationService.getConfiguration("not-gitlab-configuration"))
105       .withMessage("Gitlab configuration with id not-gitlab-configuration not found");
106   }
107
108   @Test
109   public void getConfiguration_whenNoConfiguration_throwsNotFoundException() {
110     assertThatThrownBy(() -> gitlabConfigurationService.getConfiguration("gitlab-configuration"))
111       .isInstanceOf(NotFoundException.class)
112       .hasMessage("GitLab configuration doesn't exist.");
113
114   }
115
116   @Test
117   public void getConfiguration_whenConfigurationSet_returnsConfig() {
118     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING));
119
120     GitlabConfiguration configuration = gitlabConfigurationService.getConfiguration("gitlab-configuration");
121
122     assertConfigurationFields(configuration);
123   }
124
125   @Test
126   public void getConfiguration_whenConfigurationSetAndEmpty_returnsConfig() {
127     dbTester.properties().insertProperty(GITLAB_AUTH_ENABLED, "true", null);
128     dbTester.properties().insertProperty(GITLAB_AUTH_ALLOWED_GROUPS, "", null);
129
130     GitlabConfiguration configuration = gitlabConfigurationService.getConfiguration("gitlab-configuration");
131
132     assertThat(configuration.id()).isEqualTo("gitlab-configuration");
133     assertThat(configuration.enabled()).isTrue();
134     assertThat(configuration.applicationId()).isEmpty();
135     assertThat(configuration.url()).isEmpty();
136     assertThat(configuration.secret()).isEmpty();
137     assertThat(configuration.synchronizeGroups()).isFalse();
138     assertThat(configuration.allowedGroups()).isEmpty();
139     assertThat(configuration.provisioningType()).isEqualTo(JIT);
140     assertThat(configuration.allowUsersToSignUp()).isFalse();
141     assertThat(configuration.provisioningToken()).isNull();
142   }
143
144   @Test
145   public void updateConfiguration_whenIdIsNotGitlabConfiguration_throwsException() {
146     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING));
147     UpdateGitlabConfigurationRequest updateGitlabConfigurationRequest = builder().gitlabConfigurationId("not-gitlab-configuration").build();
148     assertThatExceptionOfType(NotFoundException.class)
149       .isThrownBy(() -> gitlabConfigurationService.updateConfiguration(updateGitlabConfigurationRequest))
150       .withMessage("Gitlab configuration with id not-gitlab-configuration not found");
151   }
152
153   @Test
154   public void updateConfiguration_whenConfigurationDoesntExist_throwsException() {
155     UpdateGitlabConfigurationRequest updateGitlabConfigurationRequest = builder().gitlabConfigurationId("gitlab-configuration").build();
156     assertThatExceptionOfType(NotFoundException.class)
157       .isThrownBy(() -> gitlabConfigurationService.updateConfiguration(updateGitlabConfigurationRequest))
158       .withMessage("GitLab configuration doesn't exist.");
159   }
160
161   @Test
162   public void updateConfiguration_whenAllUpdateFieldDefined_updatesEverything() {
163     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(JIT));
164
165     UpdateGitlabConfigurationRequest updateRequest = builder()
166       .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID)
167       .enabled(withValueOrThrow(true))
168       .applicationId(withValueOrThrow("applicationId"))
169       .url(withValueOrThrow("url"))
170       .secret(withValueOrThrow("secret"))
171       .synchronizeGroups(withValueOrThrow(true))
172       .allowedGroups(withValueOrThrow(new LinkedHashSet<>(List.of("group1", "group2", "group3"))))
173       .provisioningType(withValueOrThrow(AUTO_PROVISIONING))
174       .allowUserToSignUp(withValueOrThrow(true))
175       .provisioningToken(withValueOrThrow("provisioningToken"))
176       .build();
177
178     GitlabConfiguration gitlabConfiguration = gitlabConfigurationService.updateConfiguration(updateRequest);
179
180     verifySettingWasSet(GITLAB_AUTH_ENABLED, "true");
181     verifySettingWasSet(GITLAB_AUTH_APPLICATION_ID, "applicationId");
182     verifySettingWasSet(GITLAB_AUTH_URL, "url");
183     verifySettingWasSet(GITLAB_AUTH_SECRET, "secret");
184     verifySettingWasSet(GITLAB_AUTH_SYNC_USER_GROUPS, "true");
185     verifySettingWasSet(GITLAB_AUTH_ALLOWED_GROUPS, "group1,group2,group3");
186     verifySettingWasSet(GITLAB_AUTH_PROVISIONING_ENABLED, "true");
187     verifySettingWasSet(GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP, "true");
188     verifySettingWasSet(GITLAB_AUTH_PROVISIONING_TOKEN, "provisioningToken");
189     verify(managedInstanceService).queueSynchronisationTask();
190
191     assertConfigurationFields(gitlabConfiguration);
192   }
193
194   @Test
195   public void updateConfiguration_whenAllUpdateFieldDefinedAndSetToFalse_updatesEverything() {
196     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING));
197     verify(managedInstanceService).queueSynchronisationTask();
198     clearInvocations(managedInstanceService);
199
200     UpdateGitlabConfigurationRequest updateRequest = builder()
201       .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID)
202       .enabled(withValueOrThrow(false))
203       .synchronizeGroups(withValueOrThrow(false))
204       .provisioningType(withValueOrThrow(JIT))
205       .allowUserToSignUp(withValueOrThrow(false))
206       .build();
207
208     gitlabConfigurationService.updateConfiguration(updateRequest);
209
210     verifySettingWasSet(GITLAB_AUTH_ENABLED, "false");
211     verifySettingWasSet(GITLAB_AUTH_SYNC_USER_GROUPS, "false");
212     verifySettingWasSet(GITLAB_AUTH_PROVISIONING_ENABLED, "false");
213     verifySettingWasSet(GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP, "false");
214     verifyNoMoreInteractions(managedInstanceService);
215
216   }
217
218   @Test
219   public void updateConfiguration_whenSwitchingFromAutoToJit_shouldNotScheduleSyncAndCallManagedInstanceChecker() {
220     DbSession dbSession = dbTester.getSession();
221     dbTester.getDbClient().externalGroupDao().insert(dbSession, new ExternalGroupDto("12", "12", GitLabIdentityProvider.KEY));
222     dbTester.getDbClient().externalGroupDao().insert(dbSession, new ExternalGroupDto("34", "34", GitLabIdentityProvider.KEY));
223     dbSession.commit();
224
225     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING));
226     verify(managedInstanceService).queueSynchronisationTask();
227     reset(managedInstanceService);
228
229     UpdateGitlabConfigurationRequest updateRequest = builder()
230       .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID)
231       .provisioningToken(withValue(null))
232       .provisioningType(withValueOrThrow(JIT))
233       .build();
234
235     gitlabConfigurationService.updateConfiguration(updateRequest);
236
237     verifyNoMoreInteractions(managedInstanceService);
238     assertThat(dbTester.getDbClient().externalGroupDao().selectByIdentityProvider(dbTester.getSession(), GitLabIdentityProvider.KEY)).isEmpty();
239   }
240
241   @Test
242   public void updateConfiguration_whenSwitchingToAutoProvisioningAndTheConfigIsNotEnabled_shouldThrow() {
243     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(JIT));
244
245     UpdateGitlabConfigurationRequest disableRequest = builder()
246       .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID)
247       .enabled(withValueOrThrow(false))
248       .build();
249
250     gitlabConfigurationService.updateConfiguration(disableRequest);
251
252     UpdateGitlabConfigurationRequest updateRequest = builder()
253       .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID)
254       .provisioningType(withValueOrThrow(AUTO_PROVISIONING))
255       .build();
256
257     assertThatThrownBy(() -> gitlabConfigurationService.updateConfiguration(updateRequest))
258       .isInstanceOf(IllegalStateException.class)
259       .hasMessage("GitLab authentication must be turned on to enable GitLab provisioning.");
260     verify(managedInstanceService, times(0)).queueSynchronisationTask();
261   }
262
263   @Test
264   public void updateConfiguration_whenSwitchingToAutoProvisioningAndProvisioningTokenIsNotDefined_shouldThrow() {
265     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(JIT));
266
267     UpdateGitlabConfigurationRequest removeTokenRequest = builder()
268       .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID)
269       .provisioningToken(withValue(null))
270       .build();
271
272     gitlabConfigurationService.updateConfiguration(removeTokenRequest);
273
274     UpdateGitlabConfigurationRequest updateRequest = builder()
275       .gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID)
276       .provisioningType(withValueOrThrow(AUTO_PROVISIONING))
277       .build();
278
279     assertThatThrownBy(() -> gitlabConfigurationService.updateConfiguration(updateRequest))
280       .isInstanceOf(IllegalStateException.class)
281       .hasMessage("Provisioning token must be set to enable GitLab provisioning.");
282     verify(managedInstanceService, times(0)).queueSynchronisationTask();
283   }
284
285   private static void assertConfigurationFields(GitlabConfiguration configuration) {
286     assertThat(configuration).isNotNull();
287     assertThat(configuration.id()).isEqualTo("gitlab-configuration");
288     assertThat(configuration.enabled()).isTrue();
289     assertThat(configuration.applicationId()).isEqualTo("applicationId");
290     assertThat(configuration.url()).isEqualTo("url");
291     assertThat(configuration.secret()).isEqualTo("secret");
292     assertThat(configuration.synchronizeGroups()).isTrue();
293     assertThat(configuration.allowedGroups()).containsExactlyInAnyOrder("group1", "group2", "group3");
294     assertThat(configuration.provisioningType()).isEqualTo(AUTO_PROVISIONING);
295     assertThat(configuration.allowUsersToSignUp()).isTrue();
296     assertThat(configuration.provisioningToken()).isEqualTo("provisioningToken");
297   }
298
299   @Test
300   public void createConfiguration_whenConfigurationAlreadyExists_shouldThrow() {
301     GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING);
302     gitlabConfigurationService.createConfiguration(gitlabConfiguration);
303
304     assertThatThrownBy(() -> gitlabConfigurationService.createConfiguration(gitlabConfiguration))
305       .isInstanceOf(BadRequestException.class)
306       .hasMessage("GitLab configuration already exists. Only one Gitlab configuration is supported.");
307   }
308
309   @Test
310   public void createConfiguration_whenAutoProvisioning_shouldCreateCorrectConfigurationAndScheduleSync() {
311     GitlabConfiguration configuration = buildGitlabConfiguration(AUTO_PROVISIONING);
312
313     GitlabConfiguration createdConfiguration = gitlabConfigurationService.createConfiguration(configuration);
314
315     assertConfigurationIsCorrect(configuration, createdConfiguration);
316
317     verifyCommonSettings(configuration);
318
319     verify(managedInstanceService).queueSynchronisationTask();
320
321   }
322
323   @Test
324   public void createConfiguration_whenAutoProvisioningConfigIsIncorrect_shouldThrow() {
325     GitlabConfiguration configuration = new GitlabConfiguration(
326       UNIQUE_GITLAB_CONFIGURATION_ID,
327       true,
328       "applicationId",
329       "url",
330       "secret",
331       true,
332       Set.of("group1", "group2", "group3"),
333       true,
334       AUTO_PROVISIONING,
335       null
336     );
337
338     assertThatThrownBy(() -> gitlabConfigurationService.createConfiguration(configuration))
339       .isInstanceOf(IllegalStateException.class)
340       .hasMessage("Provisioning token must be set to enable GitLab provisioning.");
341
342   }
343
344   @Test
345   public void createConfiguration_whenInstanceIsExternallyManaged_shouldThrow() {
346     GitlabConfiguration configuration = buildGitlabConfiguration(AUTO_PROVISIONING);
347
348     when(managedInstanceService.isInstanceExternallyManaged()).thenReturn(true);
349     when(managedInstanceService.getProviderName()).thenReturn("not-gitlab");
350
351     assertThatIllegalStateException()
352       .isThrownBy(() -> gitlabConfigurationService.createConfiguration(configuration))
353       .withMessage("It is not possible to synchronize SonarQube using GitLab, as it is already managed by not-gitlab.");
354
355   }
356
357   @Test
358   public void createConfiguration_whenJitProvisioning_shouldCreateCorrectConfiguration() {
359     GitlabConfiguration configuration = buildGitlabConfiguration(JIT);
360
361     GitlabConfiguration createdConfiguration = gitlabConfigurationService.createConfiguration(configuration);
362
363     assertConfigurationIsCorrect(configuration, createdConfiguration);
364
365     verifyCommonSettings(configuration);
366     verifyNoInteractions(managedInstanceService);
367
368   }
369
370   @Test
371   public void createConfiguration_whenJitProvisioningAndProvisioningTokenNotSet_shouldCreateCorrectConfiguration() {
372     GitlabConfiguration configuration = new GitlabConfiguration(
373       UNIQUE_GITLAB_CONFIGURATION_ID,
374       true,
375       "applicationId",
376       "url",
377       "secret",
378       true,
379       Set.of("group1", "group2", "group3"),
380       true,
381       JIT,
382       null
383     );
384
385     GitlabConfiguration createdConfiguration = gitlabConfigurationService.createConfiguration(configuration);
386
387     assertConfigurationIsCorrect(configuration, createdConfiguration);
388
389     verifyCommonSettings(configuration);
390     verifyNoInteractions(managedInstanceService);
391
392   }
393
394   private void verifyCommonSettings(GitlabConfiguration configuration) {
395     verifySettingWasSet(GITLAB_AUTH_ENABLED, String.valueOf(configuration.enabled()));
396     verifySettingWasSet(GITLAB_AUTH_APPLICATION_ID, configuration.applicationId());
397     verifySettingWasSet(GITLAB_AUTH_URL, configuration.url());
398     verifySettingWasSet(GITLAB_AUTH_SECRET, configuration.secret());
399     verifySettingWasSet(GITLAB_AUTH_SYNC_USER_GROUPS, String.valueOf(configuration.synchronizeGroups()));
400     verifySettingWasSet(GITLAB_AUTH_ALLOWED_GROUPS, String.join(",", configuration.allowedGroups()));
401     verifySettingWasSet(GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP, String.valueOf(configuration.allowUsersToSignUp()));
402     verifySettingWasSet(GITLAB_AUTH_PROVISIONING_TOKEN, Strings.nullToEmpty(configuration.provisioningToken()));
403     verifySettingWasSet(GITLAB_AUTH_PROVISIONING_ENABLED, String.valueOf(configuration.provisioningType().equals(AUTO_PROVISIONING)));
404   }
405
406   private void verifySettingWasSet(String setting, @Nullable String value) {
407     assertThat(dbTester.getDbClient().propertiesDao().selectGlobalProperty(setting).getValue()).isEqualTo(value);
408   }
409
410   @Test
411   public void deleteConfiguration_whenIdIsNotGitlabConfiguration_throwsException() {
412     assertThatThrownBy(() -> gitlabConfigurationService.deleteConfiguration("not-gitlab-configuration"))
413       .isInstanceOf(NotFoundException.class)
414       .hasMessage("Gitlab configuration with id not-gitlab-configuration not found");
415   }
416
417   @Test
418   public void deleteConfiguration_whenConfigurationDoesntExist_throwsException() {
419     assertThatThrownBy(() -> gitlabConfigurationService.deleteConfiguration("gitlab-configuration"))
420       .isInstanceOf(NotFoundException.class)
421       .hasMessage("GitLab configuration doesn't exist.");
422   }
423
424   @Test
425   public void deleteConfiguration_whenConfigurationExists_shouldDeleteConfiguration() {
426     DbSession dbSession = dbTester.getSession();
427     dbTester.getDbClient().externalGroupDao().insert(dbSession, new ExternalGroupDto("12", "12", GitLabIdentityProvider.KEY));
428     dbTester.getDbClient().externalGroupDao().insert(dbSession, new ExternalGroupDto("34", "34", GitLabIdentityProvider.KEY));
429     dbSession.commit();
430     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING));
431     gitlabConfigurationService.deleteConfiguration("gitlab-configuration");
432
433     assertPropertyIsDeleted(GITLAB_AUTH_ENABLED);
434     assertPropertyIsDeleted(GITLAB_AUTH_APPLICATION_ID);
435     assertPropertyIsDeleted(GITLAB_AUTH_URL);
436     assertPropertyIsDeleted(GITLAB_AUTH_SECRET);
437     assertPropertyIsDeleted(GITLAB_AUTH_SYNC_USER_GROUPS);
438     assertPropertyIsDeleted(GITLAB_AUTH_ALLOWED_GROUPS);
439     assertPropertyIsDeleted(GITLAB_AUTH_PROVISIONING_ENABLED);
440     assertPropertyIsDeleted(GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP);
441     assertPropertyIsDeleted(GITLAB_AUTH_PROVISIONING_TOKEN);
442
443     assertThat(dbTester.getDbClient().externalGroupDao().selectByIdentityProvider(dbTester.getSession(), GitLabIdentityProvider.KEY)).isEmpty();
444   }
445
446   private void assertPropertyIsDeleted(String property) {
447     assertThat(dbTester.getDbClient().propertiesDao().selectGlobalProperty(property)).isNull();
448   }
449
450   @Test
451   public void triggerRun_whenConfigIsCorrect_shouldTriggerSync() {
452     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(AUTO_PROVISIONING));
453     reset(managedInstanceService);
454
455     gitlabConfigurationService.triggerRun();
456
457     verify(managedInstanceService).queueSynchronisationTask();
458   }
459
460   @Test
461   public void triggerRun_whenConfigIsForJit_shouldThrow() {
462     gitlabConfigurationService.createConfiguration(buildGitlabConfiguration(JIT));
463
464     assertThatIllegalStateException()
465       .isThrownBy(() -> gitlabConfigurationService.triggerRun())
466       .withMessage("Auto provisioning must be activated");
467   }
468
469   @Test
470   public void triggerRun_whenConfigIsDisabled_shouldThrow() {
471     GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING);
472     gitlabConfigurationService.createConfiguration(gitlabConfiguration);
473     gitlabConfigurationService.updateConfiguration(builder().gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID).enabled(withValueOrThrow(false)).build());
474
475     assertThatIllegalStateException()
476       .isThrownBy(() -> gitlabConfigurationService.triggerRun())
477       .withMessage("GitLab authentication must be turned on to enable GitLab provisioning.");
478   }
479
480   @Test
481   public void triggerRun_whenProvisioningTokenIsNotSet_shouldThrow() {
482     GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING);
483     gitlabConfigurationService.createConfiguration(gitlabConfiguration);
484     gitlabConfigurationService.updateConfiguration(builder().gitlabConfigurationId(UNIQUE_GITLAB_CONFIGURATION_ID).provisioningToken(withValue(null)).build());
485
486     assertThatIllegalStateException()
487       .isThrownBy(() -> gitlabConfigurationService.triggerRun())
488       .withMessage("Provisioning token must be set to enable GitLab provisioning.");
489   }
490
491   @Test
492   public void validate_whenConfigurationIsDisabled_shouldNotValidate() {
493     GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING);
494     when(gitlabConfiguration.enabled()).thenReturn(false);
495
496     gitlabConfigurationService.validate(gitlabConfiguration);
497
498     verifyNoInteractions(gitlabGlobalSettingsValidator);
499   }
500
501   @Test
502   public void validate_whenConfigurationIsValidAndJIT_returnEmptyOptional() {
503     GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(JIT);
504     when(gitlabConfiguration.enabled()).thenReturn(true);
505
506     gitlabConfigurationService.validate(gitlabConfiguration);
507
508     verify(gitlabGlobalSettingsValidator).validate(AUTH_ONLY, gitlabConfiguration.url() + "/api/v4", gitlabConfiguration.provisioningToken());
509   }
510
511   @Test
512   public void validate_whenConfigurationIsValidAndAutoProvisioning_returnEmptyOptional() {
513     GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING);
514     when(gitlabConfiguration.enabled()).thenReturn(true);
515
516     gitlabConfigurationService.validate(gitlabConfiguration);
517
518     verify(gitlabGlobalSettingsValidator).validate(COMPLETE, gitlabConfiguration.url() + "/api/v4", gitlabConfiguration.provisioningToken());
519   }
520
521   @Test
522   public void validate_whenConfigurationIsInValid_returnsExceptionMessage() {
523     GitlabConfiguration gitlabConfiguration = buildGitlabConfiguration(AUTO_PROVISIONING);
524     when(gitlabConfiguration.enabled()).thenReturn(true);
525
526     Exception exception = new IllegalStateException("Invalid configuration");
527     when(gitlabConfigurationService.validate(gitlabConfiguration)).thenThrow(exception);
528
529     Optional<String> message =  gitlabConfigurationService.validate(gitlabConfiguration);
530
531     assertThat(message).contains("Invalid configuration");
532   }
533
534   private static GitlabConfiguration buildGitlabConfiguration(ProvisioningType provisioningType) {
535     GitlabConfiguration gitlabConfiguration = mock();
536     when(gitlabConfiguration.id()).thenReturn("gitlab-configuration");
537     when(gitlabConfiguration.enabled()).thenReturn(true);
538     when(gitlabConfiguration.applicationId()).thenReturn("applicationId");
539     when(gitlabConfiguration.url()).thenReturn("url");
540     when(gitlabConfiguration.secret()).thenReturn("secret");
541     when(gitlabConfiguration.synchronizeGroups()).thenReturn(true);
542     when(gitlabConfiguration.allowedGroups()).thenReturn(new LinkedHashSet<>(Set.of("group1", "group2", "group3")));
543     when(gitlabConfiguration.provisioningType()).thenReturn(provisioningType);
544     when(gitlabConfiguration.allowUsersToSignUp()).thenReturn(true);
545     when(gitlabConfiguration.provisioningToken()).thenReturn("provisioningToken");
546     return gitlabConfiguration;
547   }
548
549   private static void assertConfigurationIsCorrect(GitlabConfiguration expectedConfiguration, GitlabConfiguration actualConfiguration) {
550     assertThat(actualConfiguration.id()).isEqualTo(expectedConfiguration.id());
551     assertThat(actualConfiguration.enabled()).isEqualTo(expectedConfiguration.enabled());
552     assertThat(actualConfiguration.applicationId()).isEqualTo(expectedConfiguration.applicationId());
553     assertThat(actualConfiguration.url()).isEqualTo(expectedConfiguration.url());
554     assertThat(actualConfiguration.secret()).isEqualTo(expectedConfiguration.secret());
555     assertThat(actualConfiguration.synchronizeGroups()).isEqualTo(expectedConfiguration.synchronizeGroups());
556     assertThat(actualConfiguration.allowedGroups()).containsExactlyInAnyOrderElementsOf(expectedConfiguration.allowedGroups());
557     assertThat(actualConfiguration.provisioningType()).isEqualTo(expectedConfiguration.provisioningType());
558     assertThat(actualConfiguration.allowUsersToSignUp()).isEqualTo(expectedConfiguration.allowUsersToSignUp());
559     assertThat(actualConfiguration.provisioningToken()).isEqualTo(expectedConfiguration.provisioningToken());
560   }
561 }