aboutsummaryrefslogtreecommitdiffstats
path: root/it
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2016-10-27 10:35:16 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-10-27 17:47:56 +0200
commit0437299b4e9593501fdc34e94ccd0898704b1418 (patch)
tree863b81882335d952932232ed054dc47e868bb96c /it
parenta60fc53baf7d3f6e1aee6447f881b38be5ce2f5e (diff)
downloadsonarqube-0437299b4e9593501fdc34e94ccd0898704b1418.tar.gz
sonarqube-0437299b4e9593501fdc34e94ccd0898704b1418.zip
SONAR-5430 User authentication by HTTP header
Diffstat (limited to 'it')
-rw-r--r--it/it-tests/src/test/java/it/Category5Suite.java6
-rw-r--r--it/it-tests/src/test/java/it/user/BaseIdentityProviderTest.java7
-rw-r--r--it/it-tests/src/test/java/it/user/SsoAuthenticationTest.java159
3 files changed, 166 insertions, 6 deletions
diff --git a/it/it-tests/src/test/java/it/Category5Suite.java b/it/it-tests/src/test/java/it/Category5Suite.java
index 4a775d07653..94b693679dd 100644
--- a/it/it-tests/src/test/java/it/Category5Suite.java
+++ b/it/it-tests/src/test/java/it/Category5Suite.java
@@ -26,6 +26,7 @@ import it.settings.LicensesPageTest;
import it.settings.SettingsTestRestartingOrchestrator;
import it.updateCenter.UpdateCenterTest;
import it.user.RealmAuthenticationTest;
+import it.user.SsoAuthenticationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -43,8 +44,9 @@ import org.junit.runners.Suite;
LicensesPageTest.class,
// update center
UpdateCenterTest.class,
- RealmAuthenticationTest.class
- })
+ RealmAuthenticationTest.class,
+ SsoAuthenticationTest.class
+})
public class Category5Suite {
}
diff --git a/it/it-tests/src/test/java/it/user/BaseIdentityProviderTest.java b/it/it-tests/src/test/java/it/user/BaseIdentityProviderTest.java
index 07471d31fdc..2801b4e3d48 100644
--- a/it/it-tests/src/test/java/it/user/BaseIdentityProviderTest.java
+++ b/it/it-tests/src/test/java/it/user/BaseIdentityProviderTest.java
@@ -32,7 +32,6 @@ import org.junit.ClassRule;
import org.junit.Test;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.ws.client.WsResponse;
import util.selenium.SeleneseTest;
import util.user.UserRule;
import util.user.Users;
@@ -277,9 +276,9 @@ public class BaseIdentityProviderTest {
}
private static void authenticateWithFakeAuthProvider() {
- WsResponse response = adminWsClient.wsConnector().call(
- new GetRequest(("/sessions/init/" + FAKE_PROVIDER_KEY)));
- assertThat(response.code()).isEqualTo(200);
+ adminWsClient.wsConnector().call(
+ new GetRequest(("/sessions/init/" + FAKE_PROVIDER_KEY)))
+ .failIfNotSuccessful();
}
}
diff --git a/it/it-tests/src/test/java/it/user/SsoAuthenticationTest.java b/it/it-tests/src/test/java/it/user/SsoAuthenticationTest.java
new file mode 100644
index 00000000000..78816596e2d
--- /dev/null
+++ b/it/it-tests/src/test/java/it/user/SsoAuthenticationTest.java
@@ -0,0 +1,159 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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 it.user;
+
+import com.google.common.base.Throwables;
+import com.sonar.orchestrator.Orchestrator;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.apache.commons.io.Charsets;
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import util.user.UserRule;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test SSO authentication (using HTTP headers).
+ * <p>
+ * It starts its own server as it's using a different authentication system
+ */
+public class SsoAuthenticationTest {
+
+ private static final String LOGIN_HEADER = "H-Login";
+ private static final String NAME_HEADER = "H-Name";
+ private static final String EMAIL_HEADER = "H-Email";
+ private static final String GROUPS_HEADER = "H-Groups";
+
+ static final String USER_LOGIN = "tester";
+ static final String USER_NAME = "Tester";
+ static final String USER_EMAIL = "tester@email.com";
+
+ static final String GROUP_1 = "group-1";
+ static final String GROUP_2 = "group-2";
+ static final String GROUP_3 = "group-3";
+
+ @ClassRule
+ public static final Orchestrator orchestrator = Orchestrator.builderEnv()
+ .setServerProperty("sonar.sso.enable", "true")
+ .setServerProperty("sonar.sso.loginHeader", LOGIN_HEADER)
+ .setServerProperty("sonar.sso.nameHeader", NAME_HEADER)
+ .setServerProperty("sonar.sso.emailHeader", EMAIL_HEADER)
+ .setServerProperty("sonar.sso.groupsHeader", GROUPS_HEADER)
+ .build();
+
+ @ClassRule
+ public static UserRule USER_RULE = UserRule.from(orchestrator);
+
+ @Before
+ public void resetData() throws Exception {
+ USER_RULE.resetUsers();
+ }
+
+ @Test
+ public void authenticate() {
+ call(USER_LOGIN, USER_NAME, USER_EMAIL, null);
+
+ USER_RULE.verifyUserExists(USER_LOGIN, USER_NAME, USER_EMAIL);
+ }
+
+ @Test
+ public void authenticate_with_only_login() throws Exception {
+ call(USER_LOGIN, null, null, null);
+
+ USER_RULE.verifyUserExists(USER_LOGIN, USER_LOGIN, null);
+ }
+
+ @Test
+ public void authenticate_with_groups() {
+ call(USER_LOGIN, null, null, GROUP_1);
+
+ USER_RULE.verifyUserGroupMembership(USER_LOGIN, GROUP_1);
+ }
+
+ @Test
+ public void synchronize_groups_when_authenticating_existing_user() throws Exception {
+ USER_RULE.createGroup(GROUP_1);
+ USER_RULE.createGroup(GROUP_2);
+ USER_RULE.createGroup(GROUP_3);
+ USER_RULE.createUser(USER_LOGIN, "password");
+ USER_RULE.associateGroupsToUser(USER_LOGIN, GROUP_1, GROUP_2);
+
+ call(USER_LOGIN, null, null, GROUP_2 + "," + GROUP_3);
+
+ USER_RULE.verifyUserGroupMembership(USER_LOGIN, GROUP_2, GROUP_3);
+ }
+
+ @Test
+ public void authentication_with_local_user_is_possible_when_no_header() throws Exception {
+ USER_RULE.createUser(USER_LOGIN, "password");
+
+ checkLocalAuthentication(USER_LOGIN, "password");
+ }
+
+ @Test
+ public void fail_when_login_is_invalid() throws Exception {
+ Response response = doCall("invalid login $", null, null, null);
+
+ assertThat(response.code()).isEqualTo(500);
+ List<String> logsLines = FileUtils.readLines(orchestrator.getServer().getLogs(), Charsets.UTF_8);
+ assertThat(logsLines).contains("org.sonar.server.exceptions.BadRequestException: user.bad_login");
+ }
+
+ private static Response call(String login, @Nullable String name, @Nullable String email, @Nullable String groups) {
+ return doCall(login, name, email, groups);
+ }
+
+ private static Response doCall(String login, @Nullable String name, @Nullable String email, @Nullable String groups) {
+ Request.Builder requestBuilder = new Request.Builder().get().url(orchestrator.getServer().getUrl())
+ .addHeader(LOGIN_HEADER, login);
+ if (name != null) {
+ requestBuilder.addHeader(NAME_HEADER, name);
+ }
+ if (email != null) {
+ requestBuilder.addHeader(EMAIL_HEADER, email);
+ }
+ if (groups != null) {
+ requestBuilder.addHeader(GROUPS_HEADER, groups);
+ }
+ try {
+ return new OkHttpClient.Builder()
+ .connectTimeout(30, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .build()
+ .newCall(requestBuilder.build()).execute();
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ private boolean checkLocalAuthentication(String login, String password) {
+ String result = orchestrator.getServer().wsClient(login, password).get("/api/authentication/validate");
+ return result.contains("{\"valid\":true}");
+ }
+
+}