]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19084 add setting for GitHub provisioning
authorAurelien Poscia <aurelien.poscia@sonarsource.com>
Thu, 20 Apr 2023 09:59:05 +0000 (11:59 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 11 May 2023 20:03:13 +0000 (20:03 +0000)
server/sonar-auth-github/build.gradle
server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubManagedInstanceService.java [new file with mode: 0644]
server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubManagedInstanceServiceTest.java [new file with mode: 0644]
server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubSettingsTest.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java

index f78f4ba0b22af29bda2511cf46c145389fe30221..62325070c81eac3e12d948b9ddce2c25a1cdf853 100644 (file)
@@ -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 (file)
index 0000000..4422d1d
--- /dev/null
@@ -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<String, Boolean> getUserUuidToManaged(DbSession dbSession, Set<String> userUuids) {
+    throw new IllegalStateException("Not implemented.");
+  }
+
+  @Override
+  public Map<String, Boolean> getGroupUuidToManaged(DbSession dbSession, Set<String> 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.");
+  }
+}
index a7640e0750475069efb84ec30212580da627368a..7469f79749fe2ec7d448ccddff02a8b02c8ba57d 100644 (file)
  */
 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<PropertyDefinition> definitions() {
     return Arrays.asList(
       PropertyDefinition.builder(ENABLED)
index a46516abd960b7541d2252aaa36500a71ab4f325..491413a39ec566283e218e5bf2feba8f342b1ff5 100644 (file)
@@ -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 (file)
index 0000000..e88ceff
--- /dev/null
@@ -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();
+  }
+}
index 6e412fad1db6575b1091b7ff251c64007249aea8..12dc3c63b1f7f57f5bbfd6629e6292090ec62542 100644 (file)
  */
 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);
+  }
 }
index 3d8a1f0d8d3700e45fc2e4c01b232d3e3d497304..9af6681ab46da28dbc55a0288036e163ca7f626c 100644 (file)
@@ -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);