This is an automated email from the ASF dual-hosted git repository. krisden pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push: new 1b01961 KNOX-2155 - KnoxSSO should handle multiple cookies with the same name 1b01961 is described below commit 1b019617d408312ac33bf8f07f0ec862f7b33382 Author: Kevin Risden <kris...@apache.org> AuthorDate: Fri Dec 20 14:14:41 2019 -0500 KNOX-2155 - KnoxSSO should handle multiple cookies with the same name This commit moves getting cookies by name to a new utility class. It forces callers to look through multiple cookies returned and handle that case. Signed-off-by: Kevin Risden <kris...@apache.org> --- .../jwt/filter/SSOCookieFederationFilter.java | 12 ---- .../provider/federation/jwt/JWTMessages.java | 3 - .../jwt/filter/SSOCookieFederationFilter.java | 77 ++++++++++------------ .../provider/federation/SSOCookieProviderTest.java | 14 ++-- .../gateway/service/knoxsso/KnoxSSOMessages.java | 5 +- .../gateway/service/knoxsso/WebSSOResource.java | 54 +++++++-------- .../gateway/i18n/GatewayUtilCommonMessages.java | 6 ++ .../org/apache/knox/gateway/util/CookieUtils.java | 50 ++++++++++++++ .../apache/knox/gateway/util/CookieUtilsTest.java | 68 +++++++++++++++++++ 9 files changed, 191 insertions(+), 98 deletions(-) diff --git a/gateway-adapter/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java b/gateway-adapter/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java index 0af0153..d4e4340 100644 --- a/gateway-adapter/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java +++ b/gateway-adapter/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java @@ -39,18 +39,6 @@ public class SSOCookieFederationFilter } /** - * Encapsulate the acquisition of the JWT token from HTTP cookies within the - * request. - * - * @param req servlet request to get the JWT token from - * @return serialized JWT token - */ - @Override - protected String getJWTFromCookie(HttpServletRequest req) { - return super.getJWTFromCookie(req); - } - - /** * Create the URL to be used for authentication of the user in the absence of * a JWT token within the incoming request. * diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java index 76d7837..e92d204 100644 --- a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java +++ b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java @@ -50,9 +50,6 @@ public interface JWTMessages { @Message( level = MessageLevel.WARN, text = "Configuration for authentication provider URL is missing - will derive default URL." ) void missingAuthenticationProviderUrlConfiguration(); - @Message( level = MessageLevel.DEBUG, text = "{0} Cookie has been found and is being processed." ) - void cookieHasBeenFound(String cookieName); - @Message( level = MessageLevel.DEBUG, text = "Audience claim has been validated." ) void jwtAudienceValidated(); } diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java index cbdbbd1..814a5a7 100644 --- a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java +++ b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java @@ -23,6 +23,7 @@ import org.apache.knox.gateway.security.PrimaryPrincipal; import org.apache.knox.gateway.services.security.token.impl.JWT; import org.apache.knox.gateway.services.security.token.impl.JWTToken; import org.apache.knox.gateway.util.CertificateUtils; +import org.apache.knox.gateway.util.CookieUtils; import org.eclipse.jetty.http.MimeTypes; import javax.security.auth.Subject; @@ -37,8 +38,11 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.text.ParseException; +import java.util.List; public class SSOCookieFederationFilter extends AbstractJWTFilter { + private static final JWTMessages LOGGER = MessagesFactory.get( JWTMessages.class ); + public static final String XHR_HEADER = "X-Requested-With"; public static final String XHR_VALUE = "XMLHttpRequest"; @@ -53,7 +57,6 @@ public class SSOCookieFederationFilter extends AbstractJWTFilter { private static final String ORIGINAL_URL_QUERY_PARAM = "originalUrl="; private static final String DEFAULT_SSO_COOKIE_NAME = "hadoop-jwt"; - private static JWTMessages log = MessagesFactory.get( JWTMessages.class ); private String cookieName; private String authenticationProviderUrl; @@ -78,7 +81,7 @@ public class SSOCookieFederationFilter extends AbstractJWTFilter { // url to SSO authentication provider authenticationProviderUrl = filterConfig.getInitParameter(SSO_AUTHENTICATION_PROVIDER_URL); if (authenticationProviderUrl == null) { - log.missingAuthenticationProviderUrlConfiguration(); + LOGGER.missingAuthenticationProviderUrlConfiguration(); } // token verification pem @@ -101,35 +104,50 @@ public class SSOCookieFederationFilter extends AbstractJWTFilter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - String wireToken; HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse res = (HttpServletResponse) response; - String loginURL = constructLoginURL(req); - wireToken = getJWTFromCookie(req); - if (wireToken == null) { + List<Cookie> ssoCookies = CookieUtils.getCookiesForName(req, cookieName); + if (ssoCookies.isEmpty()) { if (req.getMethod().equals("OPTIONS")) { // CORS preflight requests to determine allowed origins and related config // must be able to continue without being redirected Subject sub = new Subject(); sub.getPrincipals().add(new PrimaryPrincipal("anonymous")); - continueWithEstablishedSecurityContext(sub, req, (HttpServletResponse) response, chain); + continueWithEstablishedSecurityContext(sub, req, res, chain); + } else { + sendRedirectToLoginURL(req, res); } - log.sendRedirectToLoginURL(loginURL); - ((HttpServletResponse) response).sendRedirect(loginURL); - } - else { - try { - JWT token = new JWTToken(wireToken); - if (validateToken((HttpServletRequest)request, (HttpServletResponse)response, chain, token)) { - Subject subject = createSubjectFromToken(token); - continueWithEstablishedSecurityContext(subject, (HttpServletRequest)request, (HttpServletResponse)response, chain); + } else { + for(Cookie ssoCookie : ssoCookies) { + String wireToken = ssoCookie.getValue(); + try { + JWT token = new JWTToken(wireToken); + if (validateToken(req, res, chain, token)) { + Subject subject = createSubjectFromToken(token); + continueWithEstablishedSecurityContext(subject, req, res, chain); + + // we found a valid cookie we don't need to keep checking anymore + return; + } + } catch (ParseException ignore) { + // Ignore the error since cookie was invalid + // Fall through to keep checking if there are more cookies } - } catch (ParseException ex) { - ((HttpServletResponse) response).sendRedirect(loginURL); } + + // There were no valid cookies found so redirect to login url + sendRedirectToLoginURL(req, res); } } + private void sendRedirectToLoginURL(HttpServletRequest request, HttpServletResponse response) + throws IOException { + String loginURL = constructLoginURL(request); + LOGGER.sendRedirectToLoginURL(loginURL); + response.sendRedirect(loginURL); + } + @Override protected void handleValidationError(HttpServletRequest request, HttpServletResponse response, int status, String error) throws IOException { @@ -147,29 +165,6 @@ public class SSOCookieFederationFilter extends AbstractJWTFilter { String loginURL = constructLoginURL(request); response.sendRedirect(loginURL); } - - } - - /** - * Encapsulate the acquisition of the JWT token from HTTP cookies within the - * request. - * - * @param req servlet request to get the JWT token from - * @return serialized JWT token - */ - protected String getJWTFromCookie(HttpServletRequest req) { - String serializedJWT = null; - Cookie[] cookies = req.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - if (cookieName.equals(cookie.getName())) { - log.cookieHasBeenFound(cookieName); - serializedJWT = cookie.getValue(); - break; - } - } - } - return serializedJWT; } /** diff --git a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java index 4555461..720ed06 100644 --- a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java +++ b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java @@ -46,7 +46,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SSOCookieProviderTest extends AbstractJWTFilterTest { - private static Logger LOGGER = LoggerFactory.getLogger(SSOCookieProviderTest.class); + private static final Logger LOGGER = LoggerFactory.getLogger(SSOCookieProviderTest.class); private static final String SERVICE_URL = "https://localhost:8888/resource"; @@ -58,8 +58,9 @@ public class SSOCookieProviderTest extends AbstractJWTFilterTest { @Override protected void setTokenOnRequest(HttpServletRequest request, SignedJWT jwt) { - Cookie cookie = new Cookie("hadoop-jwt", jwt.serialize()); - EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie }); + Cookie cookie1 = new Cookie("hadoop-jwt", "garbage"); + Cookie cookie2 = new Cookie("hadoop-jwt", jwt.serialize()); + EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie1, cookie2 }); if(ThreadLocalRandom.current().nextBoolean()) { LOGGER.info("Using XHR header for request"); @@ -88,9 +89,10 @@ public class SSOCookieProviderTest extends AbstractJWTFilterTest { SignedJWT jwt = getJWT(AbstractJWTFilter.JWT_DEFAULT_ISSUER, "alice", new Date(new Date().getTime() + 5000), privateKey); - Cookie cookie = new Cookie("jowt", jwt.serialize()); + Cookie cookie1 = new Cookie("jowt", "garbage"); + Cookie cookie2 = new Cookie("jowt", jwt.serialize()); HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class); - EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie }); + EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie1, cookie2 }); EasyMock.expect(request.getRequestURL()).andReturn( new StringBuffer(SERVICE_URL)).anyTimes(); EasyMock.expect(request.getQueryString()).andReturn(null); @@ -103,7 +105,7 @@ public class SSOCookieProviderTest extends AbstractJWTFilterTest { handler.doFilter(request, response, chain); Assert.assertTrue("doFilterCalled should not be false.", chain.doFilterCalled ); Set<PrimaryPrincipal> principals = chain.subject.getPrincipals(PrimaryPrincipal.class); - Assert.assertTrue("No PrimaryPrincipal returned.", !principals.isEmpty()); + Assert.assertFalse("No PrimaryPrincipal returned.", principals.isEmpty()); Assert.assertEquals("Not the expected principal", "alice", ((Principal)principals.toArray()[0]).getName()); } catch (ServletException se) { fail("Should NOT have thrown a ServletException."); diff --git a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOMessages.java b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOMessages.java index 94de459..a1dc1bf 100644 --- a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOMessages.java +++ b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOMessages.java @@ -30,9 +30,6 @@ public interface KnoxSSOMessages { @Message( level = MessageLevel.DEBUG, text = "Adding the following JWT token as a cookie: {0}") void addingJWTCookie(String token); - @Message( level = MessageLevel.INFO, text = "Unable to find cookie with name: {0}") - void cookieNotFound(String name); - @Message( level = MessageLevel.ERROR, text = "Unable to properly send needed HTTP status code: {0}, {1}") void unableToCloseOutputStream(String message, String string); @@ -63,4 +60,4 @@ public interface KnoxSSOMessages { @Message( level = MessageLevel.ERROR, text = "The original URL: {0} for redirecting back after authentication is " + "not valid according to the configured whitelist: {1}. See documentation for KnoxSSO Whitelisting.") void whiteListMatchFail(String original, String whitelist); -} \ No newline at end of file +} diff --git a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java index 54a315f..1fb8aa5 100644 --- a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java +++ b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java @@ -55,6 +55,7 @@ import org.apache.knox.gateway.services.security.AliasServiceException; import org.apache.knox.gateway.services.security.token.JWTokenAuthority; import org.apache.knox.gateway.services.security.token.TokenServiceException; import org.apache.knox.gateway.services.security.token.impl.JWT; +import org.apache.knox.gateway.util.CookieUtils; import org.apache.knox.gateway.util.RegExUtils; import org.apache.knox.gateway.util.Urls; import org.apache.knox.gateway.util.WhitelistUtils; @@ -65,6 +66,8 @@ import static org.apache.knox.gateway.services.GatewayServices.GATEWAY_CLUSTER_A @Path( WebSSOResource.RESOURCE_PATH ) public class WebSSOResource { + private static final KnoxSSOMessages LOGGER = MessagesFactory.get( KnoxSSOMessages.class ); + private static final String SSO_COOKIE_NAME = "knoxsso.cookie.name"; private static final String SSO_COOKIE_SECURE_ONLY_INIT_PARAM = "knoxsso.cookie.secure.only"; private static final String SSO_COOKIE_MAX_AGE_INIT_PARAM = "knoxsso.cookie.max.age"; @@ -87,7 +90,6 @@ public class WebSSOResource { private static final String DEFAULT_SSO_COOKIE_NAME = "hadoop-jwt"; private static final long TOKEN_TTL_DEFAULT = 30000L; static final String RESOURCE_PATH = "/api/v1/websso"; - private static KnoxSSOMessages log = MessagesFactory.get( KnoxSSOMessages.class ); private String cookieName; private boolean secureOnly = true; private int maxAge = -1; @@ -143,17 +145,17 @@ public class WebSSOResource { secureOnly = Boolean.parseBoolean(secure); } if (!secureOnly) { - log.cookieSecureOnly(secureOnly); + LOGGER.cookieSecureOnly(secureOnly); } String age = context.getInitParameter(SSO_COOKIE_MAX_AGE_INIT_PARAM); if (age != null) { try { - log.setMaxAge(age); + LOGGER.setMaxAge(age); maxAge = Integer.parseInt(age); } catch (NumberFormatException nfe) { - log.invalidMaxAgeEncountered(age); + LOGGER.invalidMaxAgeEncountered(age); } } @@ -177,12 +179,12 @@ public class WebSSOResource { try { tokenTTL = Long.parseLong(ttl); if (tokenTTL < -1 || (tokenTTL + System.currentTimeMillis() < 0)) { - log.invalidTokenTTLEncountered(ttl); + LOGGER.invalidTokenTTLEncountered(ttl); tokenTTL = TOKEN_TTL_DEFAULT; } } catch (NumberFormatException nfe) { - log.invalidTokenTTLEncountered(ttl); + LOGGER.invalidTokenTTLEncountered(ttl); } } } @@ -203,14 +205,15 @@ public class WebSSOResource { GatewayServices services = (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE); boolean removeOriginalUrlCookie = true; - String original = getCookieValue(request, ORIGINAL_URL_COOKIE_NAME); - if (original == null) { + List<Cookie> originalUrlCookies = CookieUtils.getCookiesForName(request, ORIGINAL_URL_COOKIE_NAME); + String original; + if (originalUrlCookies.isEmpty()) { // in the case where there are no SAML redirects done before here // we need to get it from the request parameters removeOriginalUrlCookie = false; original = getOriginalUrlFromQueryParams(); if (original.isEmpty()) { - log.originalURLNotFound(); + LOGGER.originalURLNotFound(); throw new WebApplicationException("Original URL not found in the request.", Response.Status.BAD_REQUEST); } @@ -230,10 +233,13 @@ public class WebSSOResource { } if (!validRedirect) { - log.whiteListMatchFail(Log4jAuditor.maskTokenFromURL(original), whitelist); + LOGGER.whiteListMatchFail(Log4jAuditor.maskTokenFromURL(original), whitelist); throw new WebApplicationException("Original URL not valid according to the configured whitelist.", Response.Status.BAD_REQUEST); } + } else { + // There should only be one original url cookie for the given path + original = originalUrlCookies.get(0).getValue(); } AliasService as = services.getService(ServiceType.ALIAS_SERVICE); @@ -261,16 +267,16 @@ public class WebSSOResource { removeOriginalUrlCookie(response); } - log.aboutToRedirectToOriginal(Log4jAuditor.maskTokenFromURL(original)); + LOGGER.aboutToRedirectToOriginal(Log4jAuditor.maskTokenFromURL(original)); response.setStatus(statusCode); response.setHeader("Location", original); try { response.getOutputStream().close(); } catch (IOException e) { - log.unableToCloseOutputStream(e.getMessage(), Arrays.toString(e.getStackTrace())); + LOGGER.unableToCloseOutputStream(e.getMessage(), Arrays.toString(e.getStackTrace())); } } catch (TokenServiceException| AliasServiceException e) { - log.unableToIssueToken(e); + LOGGER.unableToIssueToken(e); } URI location = null; try { @@ -343,7 +349,7 @@ public class WebSSOResource { } private void addJWTHadoopCookie(String original, JWT token) { - log.addingJWTCookie(token.toString()); + LOGGER.addingJWTCookie(token.toString()); Cookie c = new Cookie(cookieName, token.toString()); c.setPath("/"); try { @@ -359,10 +365,10 @@ public class WebSSOResource { c.setMaxAge(maxAge); } response.addCookie(c); - log.addedJWTCookie(); + LOGGER.addedJWTCookie(); } catch(Exception e) { - log.unableAddCookieToResponse(e.getMessage(), Arrays.toString(e.getStackTrace())); + LOGGER.unableAddCookieToResponse(e.getMessage(), Arrays.toString(e.getStackTrace())); throw new WebApplicationException("Unable to add JWT cookie to response."); } } @@ -373,20 +379,4 @@ public class WebSSOResource { c.setPath(RESOURCE_PATH); response.addCookie(c); } - - private String getCookieValue(HttpServletRequest request, String name) { - Cookie[] cookies = request.getCookies(); - String value = null; - if (cookies != null) { - for(Cookie cookie : cookies){ - if(name.equals(cookie.getName())){ - value = cookie.getValue(); - } - } - } - if (value == null) { - log.cookieNotFound(name); - } - return value; - } } diff --git a/gateway-util-common/src/main/java/org/apache/knox/gateway/i18n/GatewayUtilCommonMessages.java b/gateway-util-common/src/main/java/org/apache/knox/gateway/i18n/GatewayUtilCommonMessages.java index 96a8e32..34afd21 100644 --- a/gateway-util-common/src/main/java/org/apache/knox/gateway/i18n/GatewayUtilCommonMessages.java +++ b/gateway-util-common/src/main/java/org/apache/knox/gateway/i18n/GatewayUtilCommonMessages.java @@ -38,4 +38,10 @@ public interface GatewayUtilCommonMessages { @Message(level = MessageLevel.ERROR, text = "Failed to serialize Object to Json string {0}: {1}" ) void failedToSerializeObjectToJSON( Object obj, @StackTrace( level = MessageLevel.DEBUG ) Exception e ); + + @Message( level = MessageLevel.INFO, text = "Unable to find cookie with name: {0}") + void cookieNotFound(String name); + + @Message( level = MessageLevel.DEBUG, text = "{0} Cookie has been found." ) + void cookieHasBeenFound(String cookieName); } diff --git a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/CookieUtils.java b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/CookieUtils.java new file mode 100644 index 0000000..6f94353 --- /dev/null +++ b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/CookieUtils.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.knox.gateway.util; + +import org.apache.knox.gateway.i18n.GatewayUtilCommonMessages; +import org.apache.knox.gateway.i18n.messages.MessagesFactory; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; + +public class CookieUtils { + private static final GatewayUtilCommonMessages LOGGER = MessagesFactory.get(GatewayUtilCommonMessages.class); + + private CookieUtils() { + } + + public static List<Cookie> getCookiesForName(HttpServletRequest request, String name) { + List<Cookie> cookiesByName = new ArrayList<>(); + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for(Cookie cookie : cookies){ + if(name.equals(cookie.getName())){ + cookiesByName.add(cookie); + } + } + } + if (cookiesByName.isEmpty()) { + LOGGER.cookieNotFound(name); + } + return cookiesByName; + } +} diff --git a/gateway-util-common/src/test/java/org/apache/knox/gateway/util/CookieUtilsTest.java b/gateway-util-common/src/test/java/org/apache/knox/gateway/util/CookieUtilsTest.java new file mode 100644 index 0000000..d2063e4 --- /dev/null +++ b/gateway-util-common/src/test/java/org/apache/knox/gateway/util/CookieUtilsTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.knox.gateway.util; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +public class CookieUtilsTest { + @Test + public void testNoCookies() { + HttpServletRequest httpServletRequest = EasyMock.createMock(HttpServletRequest.class); + EasyMock.expect(httpServletRequest.getCookies()).andReturn(null); + EasyMock.replay(httpServletRequest); + + Assert.assertTrue(CookieUtils.getCookiesForName(httpServletRequest, "any").isEmpty()); + } + + @Test + public void testNoCookiesByName() { + Cookie[] cookies = new Cookie[] { + new Cookie("one", "1"), + new Cookie("two", "2") + }; + + HttpServletRequest httpServletRequest = EasyMock.createMock(HttpServletRequest.class); + EasyMock.expect(httpServletRequest.getCookies()).andReturn(cookies); + EasyMock.replay(httpServletRequest); + + Assert.assertTrue(CookieUtils.getCookiesForName(httpServletRequest, "noMatch").isEmpty()); + } + + @Test + public void testCookiesByName() { + Cookie one = new Cookie("one", "1"); + Cookie two = new Cookie("two", "2"); + Cookie onea = new Cookie("one", "1a"); + Cookie[] expectedCookies = new Cookie[] { one, two, onea }; + + HttpServletRequest httpServletRequest = EasyMock.createMock(HttpServletRequest.class); + EasyMock.expect(httpServletRequest.getCookies()).andReturn(expectedCookies); + EasyMock.replay(httpServletRequest); + + List<Cookie> actualCookies = CookieUtils.getCookiesForName(httpServletRequest, "one"); + Assert.assertEquals(2, actualCookies.size()); + Assert.assertEquals(one, actualCookies.get(0)); + Assert.assertEquals(onea, actualCookies.get(1)); + } +}