package com.onelogin.saml2.test.servlet; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.junit.Test; import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.servlet.ServletUtils; import com.onelogin.saml2.test.NaiveUrlEncoder; public class ServletUtilsTest { /** * Tests the sendRedirect method * Use Case: Check relative and absolute urls * * @throws IOException * * @see ServletUtils#sendRedirect */ @Test public void testSendRedirectRelative() throws IOException { HttpServletRequest request_1 = mock(HttpServletRequest.class); HttpServletResponse response_1 = mock(HttpServletResponse.class); // mock the getRequestURI() response when(request_1.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_1, "http://example.com/expectedurl.jsp"); // verify if a sendRedirect() was performed with the expected value verify(response_1).sendRedirect("http://example.com/expectedurl.jsp"); HttpServletRequest request_2 = mock(HttpServletRequest.class); HttpServletResponse response_2 = mock(HttpServletResponse.class); when(request_2.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_2, "/expectedurl.jsp"); verify(response_2).sendRedirect("/expectedurl.jsp"); } /** * Tests the sendRedirect method * Use Case: Support https and http * * @throws IOException * * @see ServletUtils#sendRedirect */ @Test public void testSendRedirectProtocol() throws IOException { HttpServletRequest request_1 = mock(HttpServletRequest.class); HttpServletResponse response_1 = mock(HttpServletResponse.class); when(request_1.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_1, "http://example.com/expectedurl.jsp"); verify(response_1).sendRedirect("http://example.com/expectedurl.jsp"); HttpServletRequest request_2 = mock(HttpServletRequest.class); HttpServletResponse response_2 = mock(HttpServletResponse.class); when(request_2.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_2, "https://example.com/expectedurl.jsp"); verify(response_2).sendRedirect("https://example.com/expectedurl.jsp"); } /** * Tests the sendRedirect method * Use Case: Support parameters * * @throws IOException * * @see ServletUtils#sendRedirect */ @Test public void testSendRedirectParams() throws IOException { Map<String, String> parameters = new HashMap<String, String>(); HttpServletRequest request_1 = mock(HttpServletRequest.class); HttpServletResponse response_1 = mock(HttpServletResponse.class); when(request_1.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_1, "http://example.com/expectedurl.jsp", parameters); verify(response_1).sendRedirect("http://example.com/expectedurl.jsp"); parameters.put("test", "true"); HttpServletRequest request_2 = mock(HttpServletRequest.class); HttpServletResponse response_2 = mock(HttpServletResponse.class); when(request_2.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_2, "http://example.com/expectedurl.jsp", parameters); verify(response_2).sendRedirect("http://example.com/expectedurl.jsp?test=true"); parameters.put("value1", "a"); HttpServletRequest request_3 = mock(HttpServletRequest.class); HttpServletResponse response_3 = mock(HttpServletResponse.class); when(request_3.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_3, "http://example.com/expectedurl.jsp", parameters); verify(response_3).sendRedirect("http://example.com/expectedurl.jsp?test=true&value1=a"); parameters.put("novalue", ""); HttpServletRequest request_4 = mock(HttpServletRequest.class); HttpServletResponse response_4 = mock(HttpServletResponse.class); when(request_4.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_4, "http://example.com/expectedurl.jsp", parameters); verify(response_4).sendRedirect("http://example.com/expectedurl.jsp?novalue&test=true&value1=a"); Map<String, String> parameters_2 = new HashMap<String, String>(); parameters_2.put("novalue", ""); HttpServletRequest request_5 = mock(HttpServletRequest.class); HttpServletResponse response_5 = mock(HttpServletResponse.class); when(request_5.getRequestURI()).thenReturn("/initial.jsp"); ServletUtils.sendRedirect(response_5, "http://example.com/expectedurl.jsp", parameters_2); verify(response_5).sendRedirect("http://example.com/expectedurl.jsp?novalue"); } /** * Tests the sendRedirect method * Use Case: Stay and don't execute redirection * * @throws IOException * * @see ServletUtils#sendRedirect */ @Test public void testSendRedirectStay() throws IOException { HttpServletResponse response = mock(HttpServletResponse.class); Map<String, String> parameters = new HashMap<String, String>(); String url = ServletUtils.sendRedirect(response, "http://example.com/expectedurl.jsp", parameters, true); assertEquals("http://example.com/expectedurl.jsp", url); url = ServletUtils.sendRedirect(response, "http://example.com/expectedurl.jsp?idpid=ffee-aabbb", singletonMap("SAMLRequest", "data"), true); assertEquals("http://example.com/expectedurl.jsp?idpid=ffee-aabbb&SAMLRequest=data", url); } /** * Tests the getSelfURLhost method * * @see ServletUtils#getSelfURLhost */ @Test public void testGetSelfURLhost() { HttpServletRequest request_1 = mock(HttpServletRequest.class); when(request_1.getScheme()).thenReturn("http"); when(request_1.getServerName()).thenReturn("example.com"); when(request_1.getServerPort()).thenReturn(80); assertEquals("http://example.com", ServletUtils.getSelfURLhost(request_1)); when(request_1.getServerPort()).thenReturn(81); assertEquals("http://example.com:81", ServletUtils.getSelfURLhost(request_1)); when(request_1.getScheme()).thenReturn("https"); when(request_1.getServerPort()).thenReturn(443); assertEquals("https://example.com", ServletUtils.getSelfURLhost(request_1)); when(request_1.getServerPort()).thenReturn(444); assertEquals("https://example.com:444", ServletUtils.getSelfURLhost(request_1)); } /** * Tests the getSelfHost method * * @see ServletUtils#getSelfHost */ @Test public void testGetSelfHost() { HttpServletRequest request_1 = mock(HttpServletRequest.class); when(request_1.getServerName()).thenReturn("example.com"); assertEquals("example.com", ServletUtils.getSelfHost(request_1)); } /** * Tests the isHTTPS method * * @see ServletUtils#isHTTPS */ @Test public void testIsHTTPS() { HttpServletRequest request_1 = mock(HttpServletRequest.class); when(request_1.isSecure()).thenReturn(false); assertEquals(false, ServletUtils.isHTTPS(request_1)); when(request_1.isSecure()).thenReturn(true); assertEquals(true, ServletUtils.isHTTPS(request_1)); } /** * Tests the getSelfURL method * * @see ServletUtils#getSelfURL */ @Test public void testGetSelfURL() { HttpServletRequest request_1 = mock(HttpServletRequest.class); when(request_1.getScheme()).thenReturn("http"); when(request_1.getServerName()).thenReturn("example.com"); when(request_1.getRequestURI()).thenReturn("/test"); when(request_1.getQueryString()).thenReturn("novalue&test=true&value1=a"); assertEquals("http://example.com/test?novalue&test=true&value1=a", ServletUtils.getSelfURL(request_1)); when(request_1.getRequestURI()).thenReturn("/"); assertEquals("http://example.com/?novalue&test=true&value1=a", ServletUtils.getSelfURL(request_1)); when(request_1.getRequestURI()).thenReturn(""); assertEquals("http://example.com?novalue&test=true&value1=a", ServletUtils.getSelfURL(request_1)); when(request_1.getRequestURI()).thenReturn(null); assertEquals("http://example.com?novalue&test=true&value1=a", ServletUtils.getSelfURL(request_1)); HttpServletRequest request_2 = mock(HttpServletRequest.class); when(request_2.getScheme()).thenReturn("http"); when(request_2.getServerName()).thenReturn("example.com"); when(request_2.getRequestURI()).thenReturn("/test"); assertEquals("http://example.com/test", ServletUtils.getSelfURL(request_2)); when(request_2.getQueryString()).thenReturn(""); assertEquals("http://example.com/test", ServletUtils.getSelfURL(request_2)); when(request_2.getQueryString()).thenReturn(null); assertEquals("http://example.com/test", ServletUtils.getSelfURL(request_2)); } /** * Tests the getSelfURLNoQuery method * * @see ServletUtils#getSelfURLNoQuery */ @Test public void testGetSelfURLNoQuery() { HttpServletRequest request_1 = mock(HttpServletRequest.class); StringBuffer url = new StringBuffer("http://example.com/test"); when(request_1.getRequestURL()).thenReturn(url); assertEquals("http://example.com/test", ServletUtils.getSelfURLNoQuery(request_1)); } /** * Tests the getSelfRoutedURLNoQuery method * * @see ServletUtils#getSelfRoutedURLNoQuery */ @Test public void testGetSelfRoutedURLNoQuery() { HttpServletRequest request_1 = mock(HttpServletRequest.class); when(request_1.getScheme()).thenReturn("http"); when(request_1.getServerName()).thenReturn("example.com"); when(request_1.getRequestURI()).thenReturn("/test"); assertEquals("http://example.com/test", ServletUtils.getSelfRoutedURLNoQuery(request_1)); when(request_1.getRequestURI()).thenReturn(""); assertEquals("http://example.com", ServletUtils.getSelfRoutedURLNoQuery(request_1)); when(request_1.getRequestURI()).thenReturn(null); assertEquals("http://example.com", ServletUtils.getSelfRoutedURLNoQuery(request_1)); } @Test public void testMakeHttpRequest() throws Exception { final String url = "http://localhost:1234/a/b"; final Map<String, String[]> paramAsArray = singletonMap("name", new String[]{"a"}); final HttpServletRequest servletRequest = mock(HttpServletRequest.class); when(servletRequest.getRequestURL()).thenReturn(new StringBuffer(url)); when(servletRequest.getParameterMap()).thenReturn(paramAsArray); final String barNaiveEncoded = NaiveUrlEncoder.encode("bar"); //must differ from normal url encode when(servletRequest.getQueryString()).thenReturn("foo=" + barNaiveEncoded); final HttpRequest httpRequest = ServletUtils.makeHttpRequest(servletRequest); assertThat(httpRequest.getRequestURL(), equalTo(url)); assertThat(httpRequest.getParameters(), equalTo(singletonMap("name", singletonList("a")))); assertThat(httpRequest.getEncodedParameter("foo"), equalTo(barNaiveEncoded)); } @Test public void sendRedirectToShouldHandleUrlsWithQueryParams() throws Exception { // having final HttpServletResponse response = mock(HttpServletResponse.class); // when ServletUtils.sendRedirect(response, "https://sso.connect.pingidentity.com/sso/idp/SSO.saml2?idpid=ffee-aabbb", singletonMap("SAMLRequest", "data")); // then verify(response).sendRedirect("https://sso.connect.pingidentity.com/sso/idp/SSO.saml2?idpid=ffee-aabbb&SAMLRequest=data"); } }