diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-10-27 10:35:16 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-10-27 17:47:56 +0200 |
commit | 0437299b4e9593501fdc34e94ccd0898704b1418 (patch) | |
tree | 863b81882335d952932232ed054dc47e868bb96c /it | |
parent | a60fc53baf7d3f6e1aee6447f881b38be5ce2f5e (diff) | |
download | sonarqube-0437299b4e9593501fdc34e94ccd0898704b1418.tar.gz sonarqube-0437299b4e9593501fdc34e94ccd0898704b1418.zip |
SONAR-5430 User authentication by HTTP header
Diffstat (limited to 'it')
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}"); + } + +} |