@@ -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') | |||
} |
@@ -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."); | |||
} | |||
} |
@@ -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<PropertyDefinition> definitions() { | |||
return Arrays.asList( | |||
PropertyDefinition.builder(ENABLED) |
@@ -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); |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); |