aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-01-26 08:50:24 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-01-26 17:54:19 +0100
commitc61cf09e06a03410f1d9fe07cd6184e171e30448 (patch)
tree68e1f9d37e802aa72d3775166cd6a902dd4bbfde /server
parentaea01719326b281aa476eaddd8bd26cebc83ce87 (diff)
downloadsonarqube-c61cf09e06a03410f1d9fe07cd6184e171e30448.tar.gz
sonarqube-c61cf09e06a03410f1d9fe07cd6184e171e30448.zip
SONAR-8684 Always create cookie with web context
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/authentication/CookieUtils.java63
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/authentication/Cookies.java106
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/authentication/JwtCsrfVerifier.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/authentication/JwtHttpHandler.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/authentication/OAuthCsrfVerifier.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java21
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/authentication/CookieUtilsTest.java82
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/authentication/CookiesTest.java122
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/authentication/ws/LogoutActionTest.java4
9 files changed, 251 insertions, 168 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/CookieUtils.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/CookieUtils.java
deleted file mode 100644
index 02baa1c1b6c..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/authentication/CookieUtils.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 org.sonar.server.authentication;
-
-import java.util.Arrays;
-import java.util.Optional;
-import javax.annotation.Nullable;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-
-public class CookieUtils {
-
- private static final String HTTPS_HEADER = "X-Forwarded-Proto";
- private static final String HTTPS_VALUE = "https";
-
- private CookieUtils() {
- // Only static methods
- }
-
- public static Optional<Cookie> findCookie(String cookieName, HttpServletRequest request) {
- Cookie[] cookies = request.getCookies();
- if (cookies == null) {
- return Optional.empty();
- }
- return Arrays.stream(cookies)
- .filter(cookie -> cookieName.equals(cookie.getName()))
- .findFirst();
- }
-
- public static Cookie createCookie(String name, @Nullable String value, boolean httpOnly, int expiry, HttpServletRequest request) {
- Cookie cookie = new Cookie(name, value);
- // Path is set "/" in order to allow rails to be able to remove cookies
- // TODO When logout when be implemented in Java (SONAR-7774), following line should be replaced by
- // cookie.setPath(request.getContextPath()"/");
- cookie.setPath("/");
- cookie.setSecure(isHttps(request));
- cookie.setHttpOnly(httpOnly);
- cookie.setMaxAge(expiry);
- return cookie;
- }
-
- private static boolean isHttps(HttpServletRequest request) {
- return HTTPS_VALUE.equalsIgnoreCase(request.getHeader(HTTPS_HEADER));
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/Cookies.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/Cookies.java
new file mode 100644
index 00000000000..c1cd587abb0
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/Cookies.java
@@ -0,0 +1,106 @@
+/*
+ * 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 org.sonar.server.authentication;
+
+import java.util.Arrays;
+import java.util.Optional;
+import javax.annotation.Nullable;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.Objects.requireNonNull;
+
+public class Cookies {
+
+ private static final String HTTPS_HEADER = "X-Forwarded-Proto";
+ private static final String HTTPS_VALUE = "https";
+
+ private Cookies() {
+ // Only static methods
+ }
+
+ public static Optional<Cookie> findCookie(String cookieName, HttpServletRequest request) {
+ Cookie[] cookies = request.getCookies();
+ if (cookies == null) {
+ return Optional.empty();
+ }
+ return Arrays.stream(cookies)
+ .filter(cookie -> cookieName.equals(cookie.getName()))
+ .findFirst();
+ }
+
+ public static CookieBuilder newCookieBuilder(HttpServletRequest request) {
+ return new CookieBuilder(request);
+ }
+
+ public static class CookieBuilder {
+
+ private final HttpServletRequest request;
+
+ private String name;
+ private String value;
+ private boolean httpOnly;
+ private int expiry;
+
+ public CookieBuilder(HttpServletRequest request) {
+ this.request = request;
+ }
+
+ public CookieBuilder setName(String name) {
+ this.name = requireNonNull(name);
+ return this;
+ }
+
+ public CookieBuilder setValue(@Nullable String value) {
+ this.value = value;
+ return this;
+ }
+
+ public CookieBuilder setHttpOnly(boolean httpOnly) {
+ this.httpOnly = httpOnly;
+ return this;
+ }
+
+ public CookieBuilder setExpiry(int expiry) {
+ this.expiry = expiry;
+ return this;
+ }
+
+ public Cookie build() {
+ Cookie cookie = new Cookie(requireNonNull(name), value);
+ cookie.setPath(getContextPath(request));
+ cookie.setSecure(isHttps(request));
+ cookie.setHttpOnly(httpOnly);
+ cookie.setMaxAge(expiry);
+ return cookie;
+ }
+
+ private static boolean isHttps(HttpServletRequest request) {
+ return HTTPS_VALUE.equalsIgnoreCase(request.getHeader(HTTPS_HEADER));
+ }
+
+ private static String getContextPath(HttpServletRequest request) {
+ String path = request.getContextPath();
+ return isNullOrEmpty(path) ? "/" : path;
+ }
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/JwtCsrfVerifier.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/JwtCsrfVerifier.java
index 4a156d9799e..28ada037e16 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/authentication/JwtCsrfVerifier.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/JwtCsrfVerifier.java
@@ -31,7 +31,7 @@ import org.apache.commons.lang.StringUtils;
import org.sonar.server.authentication.event.AuthenticationException;
import static org.apache.commons.lang.StringUtils.isBlank;
-import static org.sonar.server.authentication.CookieUtils.createCookie;
+import static org.sonar.server.authentication.Cookies.newCookieBuilder;
import static org.sonar.server.authentication.event.AuthenticationEvent.Method;
import static org.sonar.server.authentication.event.AuthenticationEvent.Source;
@@ -48,7 +48,7 @@ public class JwtCsrfVerifier {
// Create a state token to prevent request forgery.
// Store it in the cookie for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
- response.addCookie(createCookie(CSRF_STATE_COOKIE, state, false, timeoutInSeconds, request));
+ response.addCookie(newCookieBuilder(request).setName(CSRF_STATE_COOKIE).setValue(state).setHttpOnly(false).setExpiry(timeoutInSeconds).build());
return state;
}
@@ -79,11 +79,11 @@ public class JwtCsrfVerifier {
}
public void refreshState(HttpServletRequest request, HttpServletResponse response, String csrfState, int timeoutInSeconds) {
- response.addCookie(createCookie(CSRF_STATE_COOKIE, csrfState, false, timeoutInSeconds, request));
+ response.addCookie(newCookieBuilder(request).setName(CSRF_STATE_COOKIE).setValue(csrfState).setHttpOnly(false).setExpiry(timeoutInSeconds).build());
}
public void removeState(HttpServletRequest request, HttpServletResponse response) {
- response.addCookie(createCookie(CSRF_STATE_COOKIE, null, false, 0, request));
+ response.addCookie(newCookieBuilder(request).setName(CSRF_STATE_COOKIE).setValue(null).setHttpOnly(false).setExpiry(0).build());
}
private static boolean shouldRequestBeChecked(HttpServletRequest request) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/JwtHttpHandler.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/JwtHttpHandler.java
index 5b9eb6fabe3..cd01aa1d021 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/authentication/JwtHttpHandler.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/JwtHttpHandler.java
@@ -41,7 +41,8 @@ import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.time.DateUtils.addSeconds;
-import static org.sonar.server.authentication.CookieUtils.findCookie;
+import static org.sonar.server.authentication.Cookies.findCookie;
+import static org.sonar.server.authentication.Cookies.newCookieBuilder;
@ServerSide
public class JwtHttpHandler {
@@ -167,7 +168,7 @@ public class JwtHttpHandler {
}
private static Cookie createCookie(HttpServletRequest request, String name, @Nullable String value, int expirationInSeconds) {
- return CookieUtils.createCookie(name, value, true, expirationInSeconds, request);
+ return newCookieBuilder(request).setName(name).setValue(value).setHttpOnly(true).setExpiry(expirationInSeconds).build();
}
private Optional<UserDto> selectUserFromDb(String userLogin) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/OAuthCsrfVerifier.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/OAuthCsrfVerifier.java
index 2c29f2c1a09..e75171eeb51 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/authentication/OAuthCsrfVerifier.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/OAuthCsrfVerifier.java
@@ -30,8 +30,8 @@ import org.sonar.server.authentication.event.AuthenticationException;
import static java.lang.String.format;
import static org.apache.commons.codec.digest.DigestUtils.sha256Hex;
import static org.apache.commons.lang.StringUtils.isBlank;
-import static org.sonar.server.authentication.CookieUtils.createCookie;
-import static org.sonar.server.authentication.CookieUtils.findCookie;
+import static org.sonar.server.authentication.Cookies.findCookie;
+import static org.sonar.server.authentication.Cookies.newCookieBuilder;
import static org.sonar.server.authentication.event.AuthenticationEvent.Source;
public class OAuthCsrfVerifier {
@@ -42,7 +42,7 @@ public class OAuthCsrfVerifier {
// Create a state token to prevent request forgery.
// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
- response.addCookie(createCookie(CSRF_STATE_COOKIE, sha256Hex(state), true, -1, request));
+ response.addCookie(newCookieBuilder(request).setName(CSRF_STATE_COOKIE).setValue(sha256Hex(state)).setHttpOnly(true).setExpiry(-1).build());
return state;
}
@@ -54,7 +54,7 @@ public class OAuthCsrfVerifier {
String hashInCookie = cookie.getValue();
// remove cookie
- response.addCookie(createCookie(CSRF_STATE_COOKIE, null, true, 0, request));
+ response.addCookie(newCookieBuilder(request).setName(CSRF_STATE_COOKIE).setValue(null).setHttpOnly(true).setExpiry(0).build());
String stateInRequest = request.getParameter("state");
if (isBlank(stateInRequest) || !sha256Hex(stateInRequest).equals(hashInCookie)) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java
index aa48ec86df3..f191d39f6bb 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/ws/LogoutAction.java
@@ -37,7 +37,6 @@ import org.sonar.server.authentication.event.AuthenticationException;
import org.sonar.server.ws.ServletFilterHandler;
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
-import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
import static org.sonar.server.authentication.ws.AuthenticationWs.AUTHENTICATION_CONTROLLER;
import static org.sonarqube.ws.client.WsRequest.Method.POST;
@@ -81,21 +80,23 @@ public class LogoutAction extends ServletFilter implements AuthenticationWsActio
}
private void logout(HttpServletRequest request, HttpServletResponse response) {
+ generateAuthenticationEvent(request, response);
+ jwtHttpHandler.removeToken(request, response);
+ }
+
+ /**
+ * The generation of the authentication event should not prevent the removal of JWT cookie, that's why it's done in a separate method
+ */
+ private void generateAuthenticationEvent(HttpServletRequest request, HttpServletResponse response) {
try {
- generateAuthenticationEvent(request, response);
- jwtHttpHandler.removeToken(request, response);
+ Optional<JwtHttpHandler.Token> token = jwtHttpHandler.getToken(request, response);
+ String userLogin = token.isPresent() ? token.get().getUserDto().getLogin() : null;
+ authenticationEvent.logoutSuccess(request, userLogin);
} catch (AuthenticationException e) {
- response.setStatus(HTTP_UNAUTHORIZED);
authenticationEvent.logoutFailure(request, e.getMessage());
}
}
- private void generateAuthenticationEvent(HttpServletRequest request, HttpServletResponse response) {
- Optional<JwtHttpHandler.Token> token = jwtHttpHandler.getToken(request, response);
- String userLogin = token.isPresent() ? token.get().getUserDto().getLogin() : null;
- authenticationEvent.logoutSuccess(request, userLogin);
- }
-
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Nothing to do
diff --git a/server/sonar-server/src/test/java/org/sonar/server/authentication/CookieUtilsTest.java b/server/sonar-server/src/test/java/org/sonar/server/authentication/CookieUtilsTest.java
deleted file mode 100644
index 02489f17594..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/authentication/CookieUtilsTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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 org.sonar.server.authentication;
-
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class CookieUtilsTest {
-
- private static final String HTTPS_HEADER = "X-Forwarded-Proto";
-
- HttpServletRequest request = mock(HttpServletRequest.class);
-
- @Test
- public void create_cookie() throws Exception {
- Cookie cookie = CookieUtils.createCookie("name", "value", true, 10, request);
- assertThat(cookie.getName()).isEqualTo("name");
- assertThat(cookie.getValue()).isEqualTo("value");
- assertThat(cookie.isHttpOnly()).isTrue();
- assertThat(cookie.getMaxAge()).isEqualTo(10);
- assertThat(cookie.getSecure()).isFalse();
- }
-
- @Test
- public void create_not_secured_cookie_when_header_is_not_http() throws Exception {
- when(request.getHeader(HTTPS_HEADER)).thenReturn("http");
- Cookie cookie = CookieUtils.createCookie("name", "value", true, 10, request);
- assertThat(cookie.getSecure()).isFalse();
- }
-
- @Test
- public void create_secured_cookie_when_X_Forwarded_Proto_header_is_https() throws Exception {
- when(request.getHeader(HTTPS_HEADER)).thenReturn("https");
- Cookie cookie = CookieUtils.createCookie("name", "value", true, 10, request);
- assertThat(cookie.getSecure()).isTrue();
- }
-
- @Test
- public void create_secured_cookie_when_X_Forwarded_Proto_header_is_HTTPS() throws Exception {
- when(request.getHeader(HTTPS_HEADER)).thenReturn("HTTPS");
- Cookie cookie = CookieUtils.createCookie("name", "value", true, 10, request);
- assertThat(cookie.getSecure()).isTrue();
- }
-
- @Test
- public void find_cookie() throws Exception {
- Cookie cookie = new Cookie("name", "value");
- when(request.getCookies()).thenReturn(new Cookie[] {cookie});
-
- assertThat(CookieUtils.findCookie("name", request)).isPresent();
- assertThat(CookieUtils.findCookie("NAME", request)).isEmpty();
- assertThat(CookieUtils.findCookie("unknown", request)).isEmpty();
- }
-
- @Test
- public void does_not_fail_to_find_cookie_when_no_cookie() throws Exception {
- assertThat(CookieUtils.findCookie("unknown", request)).isEmpty();
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/authentication/CookiesTest.java b/server/sonar-server/src/test/java/org/sonar/server/authentication/CookiesTest.java
new file mode 100644
index 00000000000..c9c4f011b37
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/authentication/CookiesTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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 org.sonar.server.authentication;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.server.authentication.Cookies.findCookie;
+import static org.sonar.server.authentication.Cookies.newCookieBuilder;
+
+public class CookiesTest {
+
+ private static final String HTTPS_HEADER = "X-Forwarded-Proto";
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private HttpServletRequest request = mock(HttpServletRequest.class);
+
+ @Test
+ public void create_cookie() throws Exception {
+ Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").setHttpOnly(true).setExpiry(10).build();
+ assertThat(cookie.getName()).isEqualTo("name");
+ assertThat(cookie.getValue()).isEqualTo("value");
+ assertThat(cookie.isHttpOnly()).isTrue();
+ assertThat(cookie.getMaxAge()).isEqualTo(10);
+ assertThat(cookie.getSecure()).isFalse();
+ assertThat(cookie.getPath()).isEqualTo("/");
+ }
+
+ @Test
+ public void create_cookie_without_value() throws Exception {
+ Cookie cookie = newCookieBuilder(request).setName("name").build();
+ assertThat(cookie.getName()).isEqualTo("name");
+ assertThat(cookie.getValue()).isNull();
+ }
+
+ @Test
+ public void create_cookie_when_web_context() throws Exception {
+ when(request.getContextPath()).thenReturn("/sonarqube");
+ Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").setHttpOnly(true).setExpiry(10).build();
+ assertThat(cookie.getName()).isEqualTo("name");
+ assertThat(cookie.getValue()).isEqualTo("value");
+ assertThat(cookie.isHttpOnly()).isTrue();
+ assertThat(cookie.getMaxAge()).isEqualTo(10);
+ assertThat(cookie.getSecure()).isFalse();
+ assertThat(cookie.getPath()).isEqualTo("/sonarqube");
+ }
+
+ @Test
+ public void create_not_secured_cookie_when_header_is_not_http() throws Exception {
+ when(request.getHeader(HTTPS_HEADER)).thenReturn("http");
+ Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").setHttpOnly(true).setExpiry(10).build();
+ assertThat(cookie.getSecure()).isFalse();
+ }
+
+ @Test
+ public void create_secured_cookie_when_X_Forwarded_Proto_header_is_https() throws Exception {
+ when(request.getHeader(HTTPS_HEADER)).thenReturn("https");
+ Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").setHttpOnly(true).setExpiry(10).build();
+ assertThat(cookie.getSecure()).isTrue();
+ }
+
+ @Test
+ public void create_secured_cookie_when_X_Forwarded_Proto_header_is_HTTPS() throws Exception {
+ when(request.getHeader(HTTPS_HEADER)).thenReturn("HTTPS");
+ Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").setHttpOnly(true).setExpiry(10).build();
+ assertThat(cookie.getSecure()).isTrue();
+ }
+
+ @Test
+ public void find_cookie() throws Exception {
+ Cookie cookie = newCookieBuilder(request).setName("name").setValue("value").build();
+ when(request.getCookies()).thenReturn(new Cookie[] {cookie});
+
+ assertThat(findCookie("name", request)).isPresent();
+ assertThat(findCookie("NAME", request)).isEmpty();
+ assertThat(findCookie("unknown", request)).isEmpty();
+ }
+
+ @Test
+ public void does_not_fail_to_find_cookie_when_no_cookie() throws Exception {
+ assertThat(findCookie("unknown", request)).isEmpty();
+ }
+
+ @Test
+ public void fail_with_NPE_when_cookie_name_is_null() throws Exception {
+ expectedException.expect(NullPointerException.class);
+ newCookieBuilder(request).setName(null);
+ }
+
+ @Test
+ public void fail_with_NPE_when_cookie_has_no_name() throws Exception {
+ expectedException.expect(NullPointerException.class);
+ newCookieBuilder(request).setName(null);
+ }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/authentication/ws/LogoutActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/authentication/ws/LogoutActionTest.java
index 1382808223c..41949c870c3 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/authentication/ws/LogoutActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/authentication/ws/LogoutActionTest.java
@@ -40,7 +40,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -113,8 +112,7 @@ public class LogoutActionTest {
executeRequest();
verify(authenticationEvent).logoutFailure(request, "error!");
- verify(jwtHttpHandler, never()).removeToken(any(HttpServletRequest.class), any(HttpServletResponse.class));
- verify(response).setStatus(401);
+ verify(jwtHttpHandler).removeToken(any(HttpServletRequest.class), any(HttpServletResponse.class));
verifyZeroInteractions(chain);
}