/* * **************************************************************************** * Cloud Foundry * Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product includes a number of subcomponents with * separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. * **************************************************************************** */ package org.cloudfoundry.identity.uaa.web; import org.cloudfoundry.identity.uaa.web.UaaSavedRequestCache.ClientRedirectSavedRequest; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.http.HttpMethod; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.savedrequest.SavedRequest; import javax.servlet.FilterChain; import javax.servlet.ServletResponse; import javax.servlet.http.HttpSession; import static org.cloudfoundry.identity.uaa.web.UaaSavedRequestAwareAuthenticationSuccessHandler.FORM_REDIRECT_PARAMETER; import static org.cloudfoundry.identity.uaa.web.UaaSavedRequestAwareAuthenticationSuccessHandler.SAVED_REQUEST_SESSION_ATTRIBUTE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; public class UaaSavedRequestCacheTests { private UaaSavedRequestCache cache; private UaaSavedRequestCache spy; private MockHttpSession session; private MockHttpServletRequest request; private String redirectUri; @Before public void setup() { cache = new UaaSavedRequestCache(); session = new MockHttpSession(); request = new MockHttpServletRequest(POST.name(), "/login.do"); redirectUri = "http://test"; spy = spy(cache); } @After public void reset() { SecurityContextHolder.clearContext(); } @Test public void creatingASavedRequestShouldParseParameters() { String url = "http://localhost:8080/?param1=value1¶m1=value12¶m2=value2"; ClientRedirectSavedRequest saved = new ClientRedirectSavedRequest(request, url); assertNotNull(saved.getParameterMap()); String[] param1s = saved.getParameterMap().get("param1"); assertNotNull(param1s); assertArrayEquals(new String[] {"value1", "value12"}, param1s); param1s = saved.getParameterValues("param1"); assertNotNull(param1s); assertArrayEquals(new String[] {"value1", "value12"}, param1s); assertArrayEquals(new String[] {"param1", "param2"}, saved.getParameterNames().toArray(new String[0])); String[] param2 = saved.getParameterMap().get("param2"); assertNotNull(param2); assertArrayEquals(new String[] {"value2"}, param2); param2 = saved.getParameterValues("param2"); assertNotNull(param2); assertArrayEquals(new String[] {"value2"}, param2); } @Test public void filter_saves_when_needed() throws Exception { FilterChain chain = mock(FilterChain.class); request.setPathInfo("/login.do"); request.setRequestURI("/login.do"); request.setParameter(FORM_REDIRECT_PARAMETER, redirectUri); assertTrue(cache.shouldSaveFormRedirectParameter(request)); ServletResponse response = new MockHttpServletResponse(); spy.doFilter(request, response, chain); verify(spy, times(1)).shouldSaveFormRedirectParameter(request); verify(spy, times(1)).saveClientRedirect(anyObject(), anyString()); Authentication auth = mock(Authentication.class); when(auth.isAuthenticated()).thenReturn(true); SecurityContextHolder.getContext().setAuthentication(auth); spy.doFilter(request, response, chain); verify(spy, times(2)).shouldSaveFormRedirectParameter(request); verify(spy, times(1)).saveClientRedirect(anyObject(), anyString()); verify(chain, times(2)).doFilter(request, response); } @Test public void saveClientRedirect_On_Regular_Get() throws Exception { request.setSession(session); request.setScheme("http"); request.setServerName("localhost"); request.setRequestURI("/test"); request.setMethod(HttpMethod.GET.name()); spy.saveRequest(request, new MockHttpServletResponse()); verify(spy, times(1)).saveClientRedirect(request, "http://localhost/test"); } @Test public void saveFormRedirectRequest_GET_Method() throws Exception { request.setSession(session); request.setParameter(FORM_REDIRECT_PARAMETER, "http://login"); request.setMethod(HttpMethod.GET.name()); spy.saveRequest(request, new MockHttpServletResponse()); verify(spy, never()).saveClientRedirect(request, request.getParameter(FORM_REDIRECT_PARAMETER)); } @Test public void saveFormRedirectRequest() throws Exception { request.setSession(session); request.setParameter(FORM_REDIRECT_PARAMETER, "http://login"); spy.saveRequest(request, new MockHttpServletResponse()); verify(spy).saveClientRedirect(request, request.getParameter(FORM_REDIRECT_PARAMETER)); } @Test public void do_not_save_form() throws Exception { request.setSession(session); spy.saveRequest(request, new MockHttpServletResponse()); verify(spy, never()).saveClientRedirect(request, request.getParameter(FORM_REDIRECT_PARAMETER)); } @Test public void only_save_for_POST_calls() { request.setMethod(GET.name()); assertFalse(cache.shouldSaveFormRedirectParameter(request)); request.setPathInfo("/login.do"); assertFalse(cache.shouldSaveFormRedirectParameter(request)); request.setParameter(FORM_REDIRECT_PARAMETER, redirectUri); assertFalse(cache.shouldSaveFormRedirectParameter(request)); } @Test public void should_save_condition_works() { assertFalse(cache.shouldSaveFormRedirectParameter(request)); request.setPathInfo("/login.do"); assertFalse(cache.shouldSaveFormRedirectParameter(request)); request.setParameter(FORM_REDIRECT_PARAMETER, redirectUri); assertTrue(cache.shouldSaveFormRedirectParameter(request)); request.setSession(session); assertTrue(cache.shouldSaveFormRedirectParameter(request)); ClientRedirectSavedRequest savedRequest = new ClientRedirectSavedRequest(request, redirectUri); session.setAttribute(SAVED_REQUEST_SESSION_ATTRIBUTE, savedRequest); assertFalse(cache.shouldSaveFormRedirectParameter(request)); } @Test public void save_returns_correct_object() { request.setParameter(FORM_REDIRECT_PARAMETER, redirectUri); cache.saveClientRedirect(request, request.getParameter(FORM_REDIRECT_PARAMETER)); HttpSession session = request.getSession(false); assertNotNull(session); SavedRequest savedRequest = (SavedRequest) session.getAttribute(SAVED_REQUEST_SESSION_ATTRIBUTE); assertNotNull(savedRequest); assertEquals(redirectUri, savedRequest.getRedirectUrl()); assertEquals(GET.name(), savedRequest.getMethod()); } @Test public void saved_request_matcher() { String redirectUrl = "https://example.com/example?name=value"; request.setScheme("https"); request.setRequestURI("/example"); request.setServerName("example.com"); request.setQueryString("name=value"); request.setServerPort(443); ClientRedirectSavedRequest saved = new ClientRedirectSavedRequest(request, redirectUrl); assertTrue(saved.doesRequestMatch(request, null)); request.setQueryString("name=value&name2=value2"); assertFalse(saved.doesRequestMatch(request, null)); request.setQueryString("name=value"); request = new MockHttpServletRequest(POST.name(), "/login.do"); request.setParameter(FORM_REDIRECT_PARAMETER, redirectUrl); assertTrue(saved.doesRequestMatch(request, null)); } }