From: Aurelien Poscia Date: Thu, 20 Apr 2023 09:59:05 +0000 (+0200) Subject: SONAR-19084 add setting for GitHub provisioning X-Git-Tag: 10.1.0.73491~306 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4ebc514173a72ca8c435421794ac092fe4157094;p=sonarqube.git SONAR-19084 add setting for GitHub provisioning --- diff --git a/server/sonar-auth-github/build.gradle b/server/sonar-auth-github/build.gradle index f78f4ba0b22..62325070c81 100644 --- a/server/sonar-auth-github/build.gradle +++ b/server/sonar-auth-github/build.gradle @@ -11,6 +11,7 @@ dependencies { api 'com.github.scribejava:scribejava-core' api 'com.google.code.gson:gson' api project(':server:sonar-auth-common') + api project(':server:sonar-server-common') compileOnlyApi 'com.google.code.findbugs:jsr305' compileOnlyApi 'com.squareup.okhttp3:okhttp' @@ -22,5 +23,6 @@ dependencies { testImplementation 'junit:junit' testImplementation 'org.assertj:assertj-core' testImplementation 'org.mockito:mockito-core' + testImplementation testFixtures(project(':server:sonar-db-dao')) testImplementation project(path: ':server:sonar-webserver-api') } diff --git a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubManagedInstanceService.java b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubManagedInstanceService.java new file mode 100644 index 00000000000..4422d1d3e61 --- /dev/null +++ b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubManagedInstanceService.java @@ -0,0 +1,63 @@ +/* + * 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.auth.github; + +import java.util.Map; +import java.util.Set; +import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.server.ServerSide; +import org.sonar.db.DbSession; +import org.sonar.server.management.ManagedInstanceService; + +@ServerSide +@ComputeEngineSide +public class GitHubManagedInstanceService implements ManagedInstanceService { + + private final GitHubSettings gitHubSettings; + + public GitHubManagedInstanceService(GitHubSettings gitHubSettings) { + this.gitHubSettings = gitHubSettings; + } + + @Override + public boolean isInstanceExternallyManaged() { + return gitHubSettings.isProvisioningEnabled(); + } + + @Override + public Map getUserUuidToManaged(DbSession dbSession, Set userUuids) { + throw new IllegalStateException("Not implemented."); + } + + @Override + public Map getGroupUuidToManaged(DbSession dbSession, Set groupUuids) { + throw new IllegalStateException("Not implemented."); + } + + @Override + public String getManagedUsersSqlFilter(boolean filterByManaged) { + throw new IllegalStateException("Not implemented."); + } + + @Override + public String getManagedGroupsSqlFilter(boolean filterByManaged) { + throw new IllegalStateException("Not implemented."); + } +} diff --git a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java index a7640e07504..7469f79749f 100644 --- a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java +++ b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java @@ -19,12 +19,14 @@ */ package org.sonar.auth.github; +import com.google.common.annotations.VisibleForTesting; import java.util.Arrays; import java.util.List; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.config.Configuration; import org.sonar.api.config.PropertyDefinition; +import org.sonar.server.property.InternalProperties; import static java.lang.String.valueOf; import static org.sonar.api.PropertyType.BOOLEAN; @@ -41,14 +43,20 @@ public class GitHubSettings { public static final String API_URL = "sonar.auth.github.apiUrl"; public static final String WEB_URL = "sonar.auth.github.webUrl"; public static final String ORGANIZATIONS = "sonar.auth.github.organizations"; + @VisibleForTesting + static final String PROVISIONING = "sonar.provisioning.github.enabled"; private static final String CATEGORY = "authentication"; private static final String SUBCATEGORY = "github"; private final Configuration configuration; - public GitHubSettings(Configuration configuration) { + private final InternalProperties internalProperties; + + + public GitHubSettings(Configuration configuration, InternalProperties internalProperties) { this.configuration = configuration; + this.internalProperties = internalProperties; } String clientId() { @@ -93,6 +101,14 @@ public class GitHubSettings { return url; } + public void setProvisioning(boolean enableProvisioning) { + internalProperties.write(PROVISIONING, String.valueOf(enableProvisioning)); + } + + public boolean isProvisioningEnabled() { + return isEnabled() && internalProperties.read(PROVISIONING).map(Boolean::parseBoolean).orElse(false); + } + public static List definitions() { return Arrays.asList( PropertyDefinition.builder(ENABLED) diff --git a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java index a46516abd96..491413a39ec 100644 --- a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java +++ b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java @@ -22,6 +22,7 @@ package org.sonar.auth.github; import org.junit.Test; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.server.authentication.OAuth2IdentityProvider; +import org.sonar.server.property.InternalProperties; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -33,7 +34,8 @@ public class GitHubIdentityProviderTest { private MapSettings settings = new MapSettings(); - private GitHubSettings gitHubSettings = new GitHubSettings(settings.asConfig()); + private InternalProperties internalProperties = mock(InternalProperties.class); + private GitHubSettings gitHubSettings = new GitHubSettings(settings.asConfig(), internalProperties); private UserIdentityFactoryImpl userIdentityFactory = mock(UserIdentityFactoryImpl.class); private ScribeGitHubApi scribeApi = new ScribeGitHubApi(gitHubSettings); private GitHubRestClient gitHubRestClient = new GitHubRestClient(gitHubSettings); diff --git a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubManagedInstanceServiceTest.java b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubManagedInstanceServiceTest.java new file mode 100644 index 00000000000..e88ceffe3aa --- /dev/null +++ b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubManagedInstanceServiceTest.java @@ -0,0 +1,51 @@ +/* + * 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.auth.github; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GitHubManagedInstanceServiceTest { + + @Mock + private GitHubSettings gitHubSettings; + + @InjectMocks + private GitHubManagedInstanceService gitHubManagedInstanceService; + + @Test + public void isInstanceExternallyManaged_whenFalse_returnsFalse() { + when(gitHubSettings.isProvisioningEnabled()).thenReturn(false); + assertThat(gitHubManagedInstanceService.isInstanceExternallyManaged()).isFalse(); + } + + @Test + public void isInstanceExternallyManaged_whenTrue_returnsTrue() { + when(gitHubSettings.isProvisioningEnabled()).thenReturn(true); + assertThat(gitHubManagedInstanceService.isInstanceExternallyManaged()).isTrue(); + } +} diff --git a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubSettingsTest.java b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubSettingsTest.java index 6e412fad1db..12dc3c63b1f 100644 --- a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubSettingsTest.java +++ b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubSettingsTest.java @@ -19,25 +19,29 @@ */ package org.sonar.auth.github; +import java.util.Optional; import org.junit.Test; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.utils.System2; +import org.sonar.server.property.InternalProperties; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class GitHubSettingsTest { private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, GitHubSettings.definitions())); + private InternalProperties internalProperties = mock(InternalProperties.class); - private GitHubSettings underTest = new GitHubSettings(settings.asConfig()); + private GitHubSettings underTest = new GitHubSettings(settings.asConfig(), internalProperties); @Test public void is_enabled() { - settings.setProperty("sonar.auth.github.clientId.secured", "id"); - settings.setProperty("sonar.auth.github.clientSecret.secured", "secret"); + enableGithubAuthentication(); - settings.setProperty("sonar.auth.github.enabled", true); assertThat(underTest.isEnabled()).isTrue(); settings.setProperty("sonar.auth.github.enabled", false); @@ -62,6 +66,45 @@ public class GitHubSettingsTest { assertThat(underTest.isEnabled()).isFalse(); } + @Test + public void isProvisioningEnabled_returnsFalseByDefault() { + enableGithubAuthentication(); + when(internalProperties.read(GitHubSettings.PROVISIONING)).thenReturn(Optional.empty()); + assertThat(underTest.isProvisioningEnabled()).isFalse(); + } + + @Test + public void isProvisioningEnabled_ifProvisioningEnabledButGithubAuthNotSet_returnsFalse() { + enableGithubAuthentication(); + when(internalProperties.read(GitHubSettings.PROVISIONING)).thenReturn(Optional.of(Boolean.FALSE.toString())); + assertThat(underTest.isProvisioningEnabled()).isFalse(); + } + + @Test + public void isProvisioningEnabled_ifProvisioningEnabledButGithubAuthDisabled_returnsFalse() { + when(internalProperties.read(GitHubSettings.PROVISIONING)).thenReturn(Optional.of(Boolean.TRUE.toString())); + assertThat(underTest.isProvisioningEnabled()).isFalse(); + } + + @Test + public void isProvisioningEnabled_ifProvisioningEnabledAndGithubAuthEnabled_returnsTrue() { + enableGithubAuthentication(); + when(internalProperties.read(GitHubSettings.PROVISIONING)).thenReturn(Optional.of(Boolean.TRUE.toString())); + assertThat(underTest.isProvisioningEnabled()).isTrue(); + } + + @Test + public void setProvisioning_whenPassedTrue_delegatesToInternalPropertiesWrite() { + underTest.setProvisioning(true); + verify(internalProperties).write(GitHubSettings.PROVISIONING, Boolean.TRUE.toString()); + } + + @Test + public void setProvisioning_whenPassedFalse_delegatesToInternalPropertiesWrite() { + underTest.setProvisioning(false); + verify(internalProperties).write(GitHubSettings.PROVISIONING, Boolean.FALSE.toString()); + } + @Test public void return_client_id() { settings.setProperty("sonar.auth.github.clientId.secured", "id"); @@ -146,4 +189,10 @@ public class GitHubSettingsTest { public void definitions() { assertThat(GitHubSettings.definitions()).hasSize(8); } + + private void enableGithubAuthentication() { + settings.setProperty("sonar.auth.github.clientId.secured", "id"); + settings.setProperty("sonar.auth.github.clientSecret.secured", "secret"); + settings.setProperty("sonar.auth.github.enabled", true); + } } diff --git a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java index 3d8a1f0d8d3..9af6681ab46 100644 --- a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java +++ b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java @@ -40,6 +40,9 @@ import org.sonar.api.server.authentication.UserIdentity; import org.sonar.api.server.http.HttpRequest; import org.sonar.api.server.http.HttpResponse; import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.server.property.InternalProperties; +import org.sonar.server.property.InternalPropertiesImpl; import org.sonar.server.http.JavaxHttpRequest; import static java.lang.String.format; @@ -55,9 +58,13 @@ public class IntegrationTest { @Rule public MockWebServer github = new MockWebServer(); + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + // load settings with default values private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, GitHubSettings.definitions())); - private GitHubSettings gitHubSettings = new GitHubSettings(settings.asConfig()); + private InternalProperties internalProperties = new InternalPropertiesImpl(db.getDbClient()); + private GitHubSettings gitHubSettings = new GitHubSettings(settings.asConfig(), internalProperties); private UserIdentityFactoryImpl userIdentityFactory = new UserIdentityFactoryImpl(); private ScribeGitHubApi scribeApi = new ScribeGitHubApi(gitHubSettings); private GitHubRestClient gitHubRestClient = new GitHubRestClient(gitHubSettings);