diff --git a/core/pom.xml b/core/pom.xml index 9d7ccebd..db1ef8ce 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.9.1-SNAPSHOT + 3.0.0-SNAPSHOT jar diff --git a/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java b/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java index ec3b0abf..13761029 100644 --- a/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java +++ b/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java @@ -15,6 +15,7 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathExpressionException; +import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.model.hsm.HSM; import org.apache.commons.lang3.StringUtils; @@ -28,7 +29,6 @@ import org.xml.sax.SAXException; import com.onelogin.saml2.exception.SettingsException; import com.onelogin.saml2.exception.ValidationError; -import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.model.SamlResponseStatus; import com.onelogin.saml2.model.SubjectConfirmationIssue; import com.onelogin.saml2.settings.Saml2Settings; diff --git a/core/src/main/java/com/onelogin/saml2/http/HttpRequest.java b/core/src/main/java/com/onelogin/saml2/http/HttpRequest.java index 6567bcf5..00e5ee00 100644 --- a/core/src/main/java/com/onelogin/saml2/http/HttpRequest.java +++ b/core/src/main/java/com/onelogin/saml2/http/HttpRequest.java @@ -1,150 +1,56 @@ package com.onelogin.saml2.http; -import static com.onelogin.saml2.util.Preconditions.checkNotNull; -import static java.util.Collections.unmodifiableList; -import static java.util.Collections.unmodifiableMap; +import com.onelogin.saml2.util.Util; -import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.commons.lang3.StringUtils; - -import com.onelogin.saml2.util.Util; - /** - * Framework-agnostic representation of an HTTP request. + * Framework-agnostic definition of an HTTP request with a very minimal set of + * methods needed to support the SAML handshake. * - * @since 2.0.0 + * @since 3.0.0 */ -public final class HttpRequest { +public interface HttpRequest { - public static final Map> EMPTY_PARAMETERS = Collections.>emptyMap(); + int getServerPort(); - private final String requestURL; - private final Map> parameters; - private final String queryString; + String getScheme(); - /** - * Creates a new HttpRequest. - * - * @param requestURL the request URL (up to but not including query parameters) - * @throws NullPointerException if requestURL is null - * @deprecated Not providing a queryString can cause HTTP Redirect binding to fail. - */ - @Deprecated - public HttpRequest(String requestURL) { - this(requestURL, EMPTY_PARAMETERS); - } + String getServerName(); - /** - * Creates a new HttpRequest. - * - * @param requestURL the request URL (up to but not including query parameters) - * @param queryString string that is contained in the request URL after the path - */ - public HttpRequest(String requestURL, String queryString) { - this(requestURL, EMPTY_PARAMETERS, queryString); - } + String getRequestURL(); - /** - * Creates a new HttpRequest. - * - * @param requestURL the request URL (up to but not including query parameters) - * @param parameters the request query parameters - * @throws NullPointerException if any of the parameters is null - * @deprecated Not providing a queryString can cause HTTP Redirect binding to fail. - */ - @Deprecated - public HttpRequest(String requestURL, Map> parameters) { - this(requestURL, parameters, null); - } + String getRequestURI(); - /** - * Creates a new HttpRequest. - * - * @param requestURL the request URL (up to but not including query parameters) - * @param parameters the request query parameters - * @param queryString string that is contained in the request URL after the path - * @throws NullPointerException if any of the parameters is null - */ - public HttpRequest(String requestURL, Map> parameters, String queryString) { - this.requestURL = checkNotNull(requestURL, "requestURL"); - this.parameters = unmodifiableCopyOf(checkNotNull(parameters, "queryParams")); - this.queryString = StringUtils.trimToEmpty(queryString); - } - - /** - * @param name the query parameter name - * @param value the query parameter value - * @return a new HttpRequest with the given query parameter added - * @throws NullPointerException if any of the parameters is null - */ - public HttpRequest addParameter(String name, String value) { - checkNotNull(name, "name"); - checkNotNull(value, "value"); + String getQueryString(); - final List oldValues = parameters.containsKey(name) ? parameters.get(name) : new ArrayList(); - final List newValues = new ArrayList<>(oldValues); - newValues.add(value); - final Map> params = new HashMap<>(parameters); - params.put(name, newValues); - - return new HttpRequest(requestURL, params, queryString); - } + void invalidateSession(); - /** - * @param name the query parameter name - * @return a new HttpRequest with the given query parameter removed - * @throws NullPointerException if any of the parameters is null - */ - public HttpRequest removeParameter(String name) { - checkNotNull(name, "name"); + Map getParameterMap(); - final Map> params = new HashMap<>(parameters); - params.remove(name); + default List getParameters(String name) { + final Map paramsAsArray = getParameterMap(); + final Map> paramsAsList = new HashMap<>(); + for (Map.Entry param : paramsAsArray.entrySet()) { + paramsAsList.put(param.getKey(), Arrays.asList(param.getValue())); + } - return new HttpRequest(requestURL, params, queryString); - } - - /** - * The URL the client used to make the request. Includes a protocol, server name, port number, and server path, but - * not the query string parameters. - * - * @return the request URL - */ - public String getRequestURL() { - return requestURL; + return paramsAsList.get(name); } - /** - * @param name the query parameter name - * @return the first value for the parameter, or null - */ - public String getParameter(String name) { + default String getParameter(String name) { List values = getParameters(name); return values.isEmpty() ? null : values.get(0); } - /** - * @param name the query parameter name - * @return a List containing all values for the parameter - */ - public List getParameters(String name) { - List values = parameters.get(name); - return values != null ? values : Collections.emptyList(); - } - - /** - * @return a map of all query parameters - */ - public Map> getParameters() { - return parameters; + default String getEncodedParameter(String name, String defaultValue) { + String value = getEncodedParameter(name); + return (value != null) ? value : Util.urlEncoder(defaultValue); } /** @@ -155,7 +61,8 @@ public Map> getParameters() { * @param name * @return the first value for the parameter, or null */ - public String getEncodedParameter(String name) { + default String getEncodedParameter(String name) { + String queryString = getQueryString(); Matcher matcher = Pattern.compile(Pattern.quote(name) + "=([^&#]+)").matcher(queryString); if (matcher.find()) { return matcher.group(1); @@ -164,58 +71,4 @@ public String getEncodedParameter(String name) { } } - /** - * Return an url encoded get parameter value - * Prefer to extract the original encoded value directly from queryString since url - * encoding is not canonical. - * - * @param name - * @param defaultValue - * @return the first value for the parameter, or url encoded default value - */ - public String getEncodedParameter(String name, String defaultValue) { - String value = getEncodedParameter(name); - return (value != null ? value : Util.urlEncoder(defaultValue)); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - HttpRequest that = (HttpRequest) o; - return Objects.equals(requestURL, that.requestURL) && - Objects.equals(parameters, that.parameters) && - Objects.equals(queryString, that.queryString); - } - - @Override - public int hashCode() { - return Objects.hash(requestURL, parameters, queryString); - } - - @Override - public String toString() { - return "HttpRequest{" + - "requestURL='" + requestURL + '\'' + - ", parameters=" + parameters + - ", queryString=" + queryString + - '}'; - } - - private static Map> unmodifiableCopyOf(Map> orig) { - Map> copy = new HashMap<>(); - for (Map.Entry> entry : orig.entrySet()) { - copy.put(entry.getKey(), unmodifiableList(new ArrayList<>(entry.getValue()))); - } - - return unmodifiableMap(copy); - } - - } diff --git a/core/src/main/java/com/onelogin/saml2/http/HttpRequestUtils.java b/core/src/main/java/com/onelogin/saml2/http/HttpRequestUtils.java new file mode 100644 index 00000000..a24dd088 --- /dev/null +++ b/core/src/main/java/com/onelogin/saml2/http/HttpRequestUtils.java @@ -0,0 +1,83 @@ +package com.onelogin.saml2.http; + +import org.apache.commons.lang3.StringUtils; + +public class HttpRequestUtils { + + private HttpRequestUtils() { + } + + /** + * Returns the protocol + the current host + the port (if different than + * common ports). + * + * @param request + * HttpServletRequest object to be processed + * + * @return the HOST URL + */ + public static String getSelfURLhost(HttpRequest request) { + String hostUrl = StringUtils.EMPTY; + final int serverPort = request.getServerPort(); + if ((serverPort == 80) || (serverPort == 443) || serverPort == 0) { + hostUrl = String.format("%s://%s", request.getScheme(), request.getServerName()); + } else { + hostUrl = String.format("%s://%s:%s", request.getScheme(), request.getServerName(), serverPort); + } + return hostUrl; + } + + /** + * Returns the URL of the current context + current view + query + * + * @param request + * HttpServletRequest object to be processed + * + * @return current context + current view + query + */ + public static String getSelfURL(HttpRequest request) { + String url = getSelfURLhost(request); + + String requestUri = request.getRequestURI(); + String queryString = request.getQueryString(); + + if (null != requestUri && !requestUri.isEmpty()) { + url += requestUri; + } + + if (null != queryString && !queryString.isEmpty()) { + url += '?' + queryString; + } + return url; + } + + /** + * Returns the URL of the current host + current view. + * + * @param request + * HttpServletRequest object to be processed + * + * @return current host + current view + */ + public static String getSelfURLNoQuery(HttpRequest request) { + return request.getRequestURL(); + } + + /** + * Returns the routed URL of the current host + current view. + * + * @param request + * HttpServletRequest object to be processed + * + * @return the current routed url + */ + public static String getSelfRoutedURLNoQuery(HttpRequest request) { + String url = getSelfURLhost(request); + String requestUri = request.getRequestURI(); + if (null != requestUri && !requestUri.isEmpty()) { + url += requestUri; + } + return url; + } + +} diff --git a/core/src/main/java/com/onelogin/saml2/http/HttpResponse.java b/core/src/main/java/com/onelogin/saml2/http/HttpResponse.java new file mode 100644 index 00000000..7c200a6d --- /dev/null +++ b/core/src/main/java/com/onelogin/saml2/http/HttpResponse.java @@ -0,0 +1,15 @@ +package com.onelogin.saml2.http; + +import java.io.IOException; + +/** + * Framework-agnostic definition of an HTTP response with a very minimal set of + * methods needed to support the SAML handshake. + * + * @since 3.0.0 + */ +public interface HttpResponse { + + void sendRedirect(String location) throws IOException; + +} diff --git a/core/src/main/java/com/onelogin/saml2/http/HttpResponseUtils.java b/core/src/main/java/com/onelogin/saml2/http/HttpResponseUtils.java new file mode 100644 index 00000000..9a8054b5 --- /dev/null +++ b/core/src/main/java/com/onelogin/saml2/http/HttpResponseUtils.java @@ -0,0 +1,85 @@ +package com.onelogin.saml2.http; + +import com.onelogin.saml2.util.Util; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class HttpResponseUtils { + + private HttpResponseUtils() { + } + + /** + * Redirect to location url + * + * @param response + * HttpServletResponse object to be used + * @param location + * target location url + * @param parameters + * GET parameters to be added + * @param stay + * True if we want to stay (returns the url string) False to execute redirection + * + * @return string the target URL + * @throws IOException + */ + public static String sendRedirect(HttpResponse response, String location, Map parameters, Boolean stay) throws IOException { + String target = location; + + if (!parameters.isEmpty()) { + boolean first = !location.contains("?"); + for (Map.Entry parameter : parameters.entrySet()) { + if (first) { + target += "?"; + first = false; + } else { + target += "&"; + } + target += parameter.getKey(); + if (!parameter.getValue().isEmpty()) { + target += "=" + Util.urlEncoder(parameter.getValue()); + } + } + } + if (!stay) { + response.sendRedirect(target); + } + + return target; + } + + /** + * Redirect to location url + * + * @param response + * HttpServletResponse object to be used + * @param location + * target location url + * @param parameters + * GET parameters to be added + * + * @throws IOException + */ + public static void sendRedirect(HttpResponse response, String location, Map parameters) throws IOException { + sendRedirect(response, location, parameters, false); + } + + /** + * Redirect to location url + * + * @param response + * HttpServletResponse object to be used + * @param location + * target location url + * + * @throws IOException + */ + public static void sendRedirect(HttpResponse response, String location) throws IOException { + Map parameters = new HashMap<>(); + sendRedirect(response, location, parameters); + } + +} diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java index 83d51767..0eb4612d 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java @@ -13,6 +13,7 @@ import javax.xml.xpath.XPathExpressionException; +import com.onelogin.saml2.http.HttpRequest; import org.apache.commons.lang3.text.StrSubstitutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,7 +23,6 @@ import com.onelogin.saml2.exception.ValidationError; import com.onelogin.saml2.exception.SettingsException; -import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.util.Util; import com.onelogin.saml2.util.Constants; @@ -593,7 +593,7 @@ public static String getId(String samlLogoutRequestString) { /** * Returns the issue instant of the Logout Request Document. * - * @param samlLogoutRequestDocument + * @param samlLogoutRequestString * A DOMDocument object loaded from the SAML Logout Request. * * @return the issue instant of the Logout Request. diff --git a/core/src/test/java/com/onelogin/saml2/http/HttpRequestTest.java b/core/src/test/java/com/onelogin/saml2/http/HttpRequestTest.java deleted file mode 100644 index edf04c9f..00000000 --- a/core/src/test/java/com/onelogin/saml2/http/HttpRequestTest.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.onelogin.saml2.http; - -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; - -import com.onelogin.saml2.test.NaiveUrlEncoder; -import com.onelogin.saml2.util.Util; - -public class HttpRequestTest { - @Test - public void testConstructorWithNoQueryParams() throws Exception { - final String url = "url"; - - final HttpRequest request = new HttpRequest(url, (String)null); - assertThat(request.getRequestURL(), equalTo(url)); - assertThat(request.getParameters(), equalTo(Collections.>emptyMap())); - assertThat(request.getParameters("x"), equalTo(Collections.emptyList())); - assertThat(request.getParameter("x"), nullValue()); - } - - @Test - public void testConstructorWithQueryParams() throws Exception { - final String url = "url"; - final String name = "name"; - final String value1 = "val1"; - final String value2 = "val2"; - - final List values = Arrays.asList(value1, value2); - final Map> parametersMap = singletonMap(name, values); - - final HttpRequest request = new HttpRequest(url, parametersMap, null); - assertThat(request.getRequestURL(), equalTo(url)); - assertThat(request.getParameters(), equalTo(parametersMap)); - assertThat(request.getParameters(name), equalTo(values)); - assertThat(request.getParameter(name), equalTo(value1)); - } - - @Test - public void testAddParameter() throws Exception { - final String url = "some_url"; - final String name = "name"; - final String value = "value"; - - final HttpRequest request = new HttpRequest(url, (String)null).addParameter(name, value); - assertThat(request.getRequestURL(), equalTo(url)); - assertThat(request.getParameters(), equalTo(singletonMap(name, singletonList(value)))); - assertThat(request.getParameters(name), equalTo(singletonList(value))); - assertThat(request.getParameter(name), equalTo(value)); - - final HttpRequest request2 = request.addParameter(name, value); - assertThat(request2.getParameters(name), equalTo(Arrays.asList(value, value))); - } - - @Test - public void testRemoveParameter() throws Exception { - final String url = "some_url"; - final String name = "name"; - final String value = "value"; - - HttpRequest request = new HttpRequest(url, (String)null).addParameter(name, value); - assertThat(request.getRequestURL(), equalTo(url)); - assertThat(request.getParameters(), equalTo(singletonMap(name, singletonList(value)))); - assertThat(request.getParameters(name), equalTo(singletonList(value))); - assertThat(request.getParameter(name), equalTo(value)); - - request = request.removeParameter(name); - assertThat(request.getRequestURL(), equalTo(url)); - assertTrue(request.getParameters().isEmpty()); - assertTrue(request.getParameters(name).isEmpty()); - assertNull(request.getParameter(name)); - } - - @Test - public void testGetEncodedParameter_encodesParametersNotOnQueryString() throws Exception { - final String url = "url"; - final String name = "name"; - final String value1 = "val/1!"; - final String addedName = "added"; - final String addedValue = "added#value!"; - - final List values = Arrays.asList(value1); - final Map> parametersMap = singletonMap(name, values); - - final HttpRequest request = new HttpRequest(url, parametersMap, null).addParameter(addedName, addedValue); - - assertThat(request.getEncodedParameter(name), equalTo(Util.urlEncoder(value1))); - assertThat(request.getEncodedParameter(addedName), equalTo(Util.urlEncoder(addedValue))); - } - - @Test - public void testGetEncodedParameter_prefersValueFromQueryString() throws Exception { - final String url = "url"; - final String name = "name"; - final String value1 = "value1"; - final String urlValue1 = "onUrl1"; - final String queryString = name + "=" + urlValue1; - - final List values = Arrays.asList(value1); - final Map> parametersMap = singletonMap(name, values); - - final HttpRequest request = new HttpRequest(url, parametersMap, queryString); - - assertThat(request.getEncodedParameter(name), equalTo(urlValue1)); - assertThat(request.getParameter(name), equalTo(value1)); - } - - @Test - public void testGetEncodedParameter_returnsExactAsGivenInQueryString() throws Exception { - final String url = "url"; - final String name = "name"; - String encodedValue1 = NaiveUrlEncoder.encode("do not alter!"); - final String queryString = name + "=" + encodedValue1; - - final HttpRequest request = new HttpRequest(url, queryString); - - assertThat(request.getEncodedParameter(name), equalTo(encodedValue1)); - } - - @Test - public void testGetEncodedParameter_handlesMultipleValuesOnQueryString() throws Exception { - final String url = "url"; - final String queryString = "k1=v1&k2=v2&k3=v3"; - - final Map> parametersMap = new HashMap<>(); - final HttpRequest request = new HttpRequest(url, parametersMap, queryString); - - assertThat(request.getEncodedParameter("k1"), equalTo("v1")); - assertThat(request.getEncodedParameter("k2"), equalTo("v2")); - assertThat(request.getEncodedParameter("k3"), equalTo("v3")); - } - - @Test - public void testGetEncodedParameter_stopsAtUrlFragment() throws Exception { - final String url = "url"; - final String queryString = "first=&foo=bar#ignore"; - - final HttpRequest request = new HttpRequest(url, queryString); - - assertThat(request.getEncodedParameter("foo"), equalTo("bar")); - } - - @Test - public void testGetEncodedParameter_withDefault_usesDefaultWhenParameterMissing() throws Exception { - final String url = "url"; - final String foobar = "foo/bar!"; - - final HttpRequest request = new HttpRequest(url, (String)null); - assertThat(request.getEncodedParameter("missing", foobar), equalTo(Util.urlEncoder(foobar))); - } - - - @Test - public void testAddParameter_preservesQueryString() throws Exception { - final String url = "url"; - final String name = "name"; - final String value1 = "val/1!"; - String encodedValue1 = NaiveUrlEncoder.encode(value1); - final String queryString = name + "=" + encodedValue1; - - final Map> parametersMap = new HashMap<>(); - final HttpRequest request = new HttpRequest(url, parametersMap, queryString).addParameter(name, value1); - - assertThat(request.getEncodedParameter(name), equalTo(encodedValue1)); - } - - @Test - public void testRemoveParameter_preservesQueryString() throws Exception { - final String url = "url"; - final String name = "name"; - final String value1 = "val/1!"; - String encodedValue1 = NaiveUrlEncoder.encode(value1); - final String queryString = name + "=" + encodedValue1; - - final List values = Arrays.asList(value1); - final Map> parametersMap = singletonMap(name, values); - - final HttpRequest request = new HttpRequest(url, parametersMap, queryString).removeParameter(name); - - assertThat(request.getEncodedParameter(name), equalTo(encodedValue1)); - } - -} diff --git a/core/src/test/java/com/onelogin/saml2/http/HttpRequestUtilsTest.java b/core/src/test/java/com/onelogin/saml2/http/HttpRequestUtilsTest.java new file mode 100644 index 00000000..897af06e --- /dev/null +++ b/core/src/test/java/com/onelogin/saml2/http/HttpRequestUtilsTest.java @@ -0,0 +1,117 @@ +package com.onelogin.saml2.http; + +import org.junit.Test; + +import static java.util.Collections.singletonMap; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class HttpRequestUtilsTest { + + /** + * Tests the getSelfURLhost method + * + * @see HttpRequestUtils#getSelfURLhost + */ + @Test + public void testGetSelfURLhost() { + HttpRequest request_1 = mock(HttpRequest.class); + when(request_1.getScheme()).thenReturn("http"); + when(request_1.getServerName()).thenReturn("example.com"); + when(request_1.getServerPort()).thenReturn(80); + assertEquals("http://example.com", HttpRequestUtils.getSelfURLhost(request_1)); + + when(request_1.getServerPort()).thenReturn(81); + assertEquals("http://example.com:81", HttpRequestUtils.getSelfURLhost(request_1)); + + when(request_1.getScheme()).thenReturn("https"); + when(request_1.getServerPort()).thenReturn(443); + assertEquals("https://example.com", HttpRequestUtils.getSelfURLhost(request_1)); + + when(request_1.getServerPort()).thenReturn(444); + assertEquals("https://example.com:444", HttpRequestUtils.getSelfURLhost(request_1)); + } + + /** + * Tests the getSelfURL method + * + * @see HttpRequestUtils#getSelfURL + */ + @Test + public void testGetSelfURL() { + HttpRequest request_1 = mock(HttpRequest.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", HttpRequestUtils.getSelfURL(request_1)); + + when(request_1.getRequestURI()).thenReturn("/"); + assertEquals("http://example.com/?novalue&test=true&value1=a", HttpRequestUtils.getSelfURL(request_1)); + + when(request_1.getRequestURI()).thenReturn(""); + assertEquals("http://example.com?novalue&test=true&value1=a", HttpRequestUtils.getSelfURL(request_1)); + + when(request_1.getRequestURI()).thenReturn(null); + assertEquals("http://example.com?novalue&test=true&value1=a", HttpRequestUtils.getSelfURL(request_1)); + + HttpRequest request_2 = mock(HttpRequest.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", HttpRequestUtils.getSelfURL(request_2)); + + when(request_2.getQueryString()).thenReturn(""); + assertEquals("http://example.com/test", HttpRequestUtils.getSelfURL(request_2)); + + when(request_2.getQueryString()).thenReturn(null); + assertEquals("http://example.com/test", HttpRequestUtils.getSelfURL(request_2)); + } + + /** + * Tests the getSelfURLNoQuery method + * + * @see HttpRequestUtils#getSelfURLNoQuery + */ + @Test + public void testGetSelfURLNoQuery() { + HttpRequest request_1 = mock(HttpRequest.class); + when(request_1.getRequestURL()).thenReturn("http://example.com/test"); + assertEquals("http://example.com/test", HttpRequestUtils.getSelfURLNoQuery(request_1)); + } + + /** + * Tests the getSelfRoutedURLNoQuery method + * + * @see HttpRequestUtils#getSelfRoutedURLNoQuery + */ + @Test + public void testGetSelfRoutedURLNoQuery() { + HttpRequest request_1 = mock(HttpRequest.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", HttpRequestUtils.getSelfRoutedURLNoQuery(request_1)); + + when(request_1.getRequestURI()).thenReturn(""); + assertEquals("http://example.com", HttpRequestUtils.getSelfRoutedURLNoQuery(request_1)); + + when(request_1.getRequestURI()).thenReturn(null); + assertEquals("http://example.com", HttpRequestUtils.getSelfRoutedURLNoQuery(request_1)); + } + + @Test + public void sendRedirectToShouldHandleUrlsWithQueryParams() throws Exception { + // having + final HttpResponse response = mock(HttpResponse.class); + + // when + HttpResponseUtils.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"); + } + +} diff --git a/core/src/test/java/com/onelogin/saml2/http/HttpResponseUtilsTest.java b/core/src/test/java/com/onelogin/saml2/http/HttpResponseUtilsTest.java new file mode 100644 index 00000000..a15f6280 --- /dev/null +++ b/core/src/test/java/com/onelogin/saml2/http/HttpResponseUtilsTest.java @@ -0,0 +1,132 @@ +package com.onelogin.saml2.http; + +import org.junit.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static java.util.Collections.singletonMap; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class HttpResponseUtilsTest { + + /** + * Tests the sendRedirect method + * Use Case: Check relative and absolute urls + * + * @throws IOException + * + * @see HttpResponseUtils#sendRedirect + */ + @Test + public void testSendRedirectRelative() throws IOException { + HttpRequest request_1 = mock(HttpRequest.class); + HttpResponse response_1 = mock(HttpResponse.class); + // mock the getRequestURI() response + when(request_1.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.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"); + + HttpRequest request_2 = mock(HttpRequest.class); + HttpResponse response_2 = mock(HttpResponse.class); + when(request_2.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.sendRedirect(response_2, "/expectedurl.jsp"); + verify(response_2).sendRedirect("/expectedurl.jsp"); + } + + /** + * Tests the sendRedirect method + * Use Case: Support https and http + * + * @throws IOException + * + * @see HttpResponseUtils#sendRedirect + */ + @Test + public void testSendRedirectProtocol() throws IOException { + HttpRequest request_1 = mock(HttpRequest.class); + HttpResponse response_1 = mock(HttpResponse.class); + when(request_1.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.sendRedirect(response_1, "http://example.com/expectedurl.jsp"); + verify(response_1).sendRedirect("http://example.com/expectedurl.jsp"); + + HttpRequest request_2 = mock(HttpRequest.class); + HttpResponse response_2 = mock(HttpResponse.class); + when(request_2.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.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 HttpResponseUtils#sendRedirect + */ + @Test + public void testSendRedirectParams() throws IOException { + Map parameters = new HashMap(); + HttpRequest request_1 = mock(HttpRequest.class); + HttpResponse response_1 = mock(HttpResponse.class); + when(request_1.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.sendRedirect(response_1, "http://example.com/expectedurl.jsp", parameters); + verify(response_1).sendRedirect("http://example.com/expectedurl.jsp"); + + parameters.put("test", "true"); + HttpRequest request_2 = mock(HttpRequest.class); + HttpResponse response_2 = mock(HttpResponse.class); + when(request_2.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.sendRedirect(response_2, "http://example.com/expectedurl.jsp", parameters); + verify(response_2).sendRedirect("http://example.com/expectedurl.jsp?test=true"); + + parameters.put("value1", "a"); + HttpRequest request_3 = mock(HttpRequest.class); + HttpResponse response_3 = mock(HttpResponse.class); + when(request_3.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.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", ""); + HttpRequest request_4 = mock(HttpRequest.class); + HttpResponse response_4 = mock(HttpResponse.class); + when(request_4.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.sendRedirect(response_4, "http://example.com/expectedurl.jsp", parameters); + verify(response_4).sendRedirect("http://example.com/expectedurl.jsp?novalue&test=true&value1=a"); + + Map parameters_2 = new HashMap(); + parameters_2.put("novalue", ""); + HttpRequest request_5 = mock(HttpRequest.class); + HttpResponse response_5 = mock(HttpResponse.class); + when(request_5.getRequestURI()).thenReturn("/initial.jsp"); + HttpResponseUtils.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 HttpResponseUtils#sendRedirect + */ + @Test + public void testSendRedirectStay() throws IOException { + HttpResponse response = mock(HttpResponse.class); + Map parameters = new HashMap(); + + String url = HttpResponseUtils.sendRedirect(response, "http://example.com/expectedurl.jsp", parameters, true); + assertEquals("http://example.com/expectedurl.jsp", url); + + url = HttpResponseUtils.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); + } + +} diff --git a/core/src/test/java/com/onelogin/saml2/http/TestHttpRequest.java b/core/src/test/java/com/onelogin/saml2/http/TestHttpRequest.java new file mode 100644 index 00000000..566eaba9 --- /dev/null +++ b/core/src/test/java/com/onelogin/saml2/http/TestHttpRequest.java @@ -0,0 +1,178 @@ +package com.onelogin.saml2.http; + +import static com.onelogin.saml2.util.Preconditions.checkNotNull; +import static java.util.Collections.unmodifiableList; +import static java.util.Collections.unmodifiableMap; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.apache.commons.lang3.StringUtils; + +/** + * Framework-agnostic representation of an HTTP request, used only for testing. + * + * @since 3.0.0 + */ +public class TestHttpRequest implements HttpRequest { + + public static final Map> EMPTY_PARAMETERS = Collections.emptyMap(); + + private final String requestURL; + private final Map> parameters; + private final String queryString; + + /** + * Creates a new HttpRequest. + * + * @param requestURL the request URL (up to but not including query parameters) + * @param queryString string that is contained in the request URL after the path + */ + public TestHttpRequest(String requestURL, String queryString) { + this(requestURL, EMPTY_PARAMETERS, queryString); + } + + /** + * Creates a new HttpRequest. + * + * @param requestURL the request URL (up to but not including query parameters) + * @param parameters the request query parameters + * @param queryString string that is contained in the request URL after the path + * @throws NullPointerException if any of the parameters is null + */ + public TestHttpRequest(String requestURL, Map> parameters, String queryString) { + this.requestURL = checkNotNull(requestURL, "requestURL"); + this.parameters = unmodifiableCopyOf(checkNotNull(parameters, "queryParams")); + this.queryString = StringUtils.trimToEmpty(queryString); + } + + /** + * @param name the query parameter name + * @param value the query parameter value + * @return a new HttpRequest with the given query parameter added + * @throws NullPointerException if any of the parameters is null + */ + public TestHttpRequest addParameter(String name, String value) { + checkNotNull(name, "name"); + checkNotNull(value, "value"); + + final List oldValues = parameters.containsKey(name) ? parameters.get(name) : new ArrayList(); + final List newValues = new ArrayList<>(oldValues); + newValues.add(value); + final Map> params = new HashMap<>(parameters); + params.put(name, newValues); + + return new TestHttpRequest(requestURL, params, queryString); + } + + /** + * @param name the query parameter name + * @return a new HttpRequest with the given query parameter removed + * @throws NullPointerException if any of the parameters is null + */ + public TestHttpRequest removeParameter(String name) { + checkNotNull(name, "name"); + + final Map> params = new HashMap<>(parameters); + params.remove(name); + + return new TestHttpRequest(requestURL, params, queryString); + } + + @Override + public int getServerPort() { + throw new UnsupportedOperationException(); + } + + @Override + public String getScheme() { + throw new UnsupportedOperationException(); + } + + @Override + public String getServerName() { + throw new UnsupportedOperationException(); + } + + /** + * The URL the client used to make the request. Includes a protocol, server name, port number, and server path, but + * not the query string parameters. + * + * @return the request URL + */ + @Override + public String getRequestURL() { + return requestURL; + } + + @Override + public String getRequestURI() { + throw new UnsupportedOperationException(); + } + + @Override + public String getQueryString() { + return queryString; + } + + @Override + public Map getParameterMap() { + throw new UnsupportedOperationException(); + } + + @Override + public void invalidateSession() { + throw new UnsupportedOperationException(); + } + + /** + * @return a map of all query parameters + */ + public Map> getParameters() { + return parameters; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + TestHttpRequest that = (TestHttpRequest) o; + return Objects.equals(requestURL, that.requestURL) && + Objects.equals(parameters, that.parameters) && + Objects.equals(queryString, that.queryString); + } + + @Override + public int hashCode() { + return Objects.hash(requestURL, parameters, queryString); + } + + @Override + public String toString() { + return "TestHttpRequest{" + + "requestURL='" + requestURL + '\'' + + ", parameters=" + parameters + + ", queryString=" + queryString + + '}'; + } + + private static Map> unmodifiableCopyOf(Map> orig) { + Map> copy = new HashMap<>(); + for (Map.Entry> entry : orig.entrySet()) { + copy.put(entry.getKey(), unmodifiableList(new ArrayList<>(entry.getValue()))); + } + + return unmodifiableMap(copy); + } + +} diff --git a/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java b/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java index 7cec9efa..b57175b5 100644 --- a/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java @@ -5,7 +5,7 @@ import com.onelogin.saml2.exception.SettingsException; import com.onelogin.saml2.exception.ValidationError; import com.onelogin.saml2.http.HttpRequest; -import com.onelogin.saml2.logout.LogoutRequest; +import com.onelogin.saml2.http.TestHttpRequest; import com.onelogin.saml2.model.SamlResponseStatus; import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.settings.SettingsBuilder; @@ -3328,7 +3328,7 @@ private static HttpRequest newHttpRequest(String samlResponseEncoded) { } private static HttpRequest newHttpRequest(String requestURL, String samlResponseEncoded) { - return new HttpRequest(requestURL, (String)null).addParameter("SAMLResponse", samlResponseEncoded); + return new TestHttpRequest(requestURL, (String)null).addParameter("SAMLResponse", samlResponseEncoded); } } diff --git a/core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java b/core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java index c81f172e..61a227ea 100644 --- a/core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java @@ -23,6 +23,8 @@ import java.security.PrivateKey; +import com.onelogin.saml2.http.HttpRequest; +import com.onelogin.saml2.http.TestHttpRequest; import org.w3c.dom.Document; import org.junit.Rule; import org.junit.Test; @@ -30,7 +32,6 @@ import com.onelogin.saml2.logout.LogoutRequest; import com.onelogin.saml2.logout.LogoutRequestParams; -import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.exception.XMLEntityException; import com.onelogin.saml2.exception.Error; import com.onelogin.saml2.exception.SettingsException; @@ -869,7 +870,7 @@ public void testIsInValidSign_defaultUrlEncode() throws Exception { //This signature is based on the query string above String signature = "cxDTcLRHhXJKGYcjZE2RRz5p7tVg/irNimq48KkJ0n10wiGwAmuzUByxEm4OHbetDrHGtxI5ygjrR0/HcrD8IkYyI5Ie4r5tJYkfdtpUrvOQ7khbBvP9GzEbZIrz7eH1ALdCDchORaRB/cs6v+OZbBj5uPTrN//wOhZl2k9H2xVW/SYy17jDoIKh/wvqtQ9FF+h2UxdUEhxeB/UUXOC6nVLMo+RGaamSviYkUE1Zu1tmalO+F6FivNQ31T/TkqzWz0KEjmnFs3eKbHakPVuUHpDQm7Gf2gBS1TXwVQsL7e2axtvv4RH5djlq1Z2WH2V+PwGOkIvLxf3igGUSR1A8bw=="; - HttpRequest httpRequest = new HttpRequest(requestURL, queryString) + TestHttpRequest httpRequest = new TestHttpRequest(requestURL, queryString) .addParameter("SAMLRequest", samlRequestEncoded) .addParameter("RelayState", relayState) .addParameter("SigAlg", sigAlg) @@ -897,7 +898,7 @@ public void testIsInValidSign_naiveUrlEncoding() throws Exception { //This signature is based on the query string above String signatureNaiveEncoding = "Gj2mUq6RBPAPXI9VjDDlwAxueSEBlOfgpWKLpsQbqIp+2XPFtC/vPAZpuPjHCDNNnAI3WKZa4l8ijwQBTqQwKz88k9gTx6vcLxPl2L4SrWdLOokiGrIVYJ+0sK2hapHHMa7WzGiTgpeTuejHbD4ptneaRXl4nrJAEo0WJ/rNTSWbJpnb+ENtgBnsfkmj+6z1KFY70ruo7W/vme21Jg+4XNfBSGl6LLSjEnZHJG0ET80HKvJEZayv4BQGZ3MShcSMyab/w+rLfDvDRA5RcRxw+NHOXo/kxZ3qhpa6daOwG69+PiiWmusmB2gaSq6jy2L55zFks9a36Pt5l5fYA2dE4g=="; - HttpRequest httpRequest = new HttpRequest(requestURL, queryString) + TestHttpRequest httpRequest = new TestHttpRequest(requestURL, queryString) .addParameter("SAMLRequest", samlRequestEncoded) .addParameter("RelayState", relayState) .addParameter("SigAlg", sigAlg) @@ -926,7 +927,7 @@ public void testIsInValidSign() throws Exception { String sigAlg = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; String signature = "XCwCyI5cs7WhiJlB5ktSlWxSBxv+6q2xT3c8L7dLV6NQG9LHWhN7gf8qNsahSXfCzA0Ey9dp5BQ0EdRvAk2DIzKmJY6e3hvAIEp1zglHNjzkgcQmZCcrkK9Czi2Y1WkjOwR/WgUTUWsGJAVqVvlRZuS3zk3nxMrLH6f7toyvuJc="; - HttpRequest httpRequest = new HttpRequest(requestURL, (String)null) + TestHttpRequest httpRequest = new TestHttpRequest(requestURL, (String)null) .addParameter("SAMLRequest", samlRequestEncoded) .addParameter("RelayState", relayState) .addParameter("SigAlg", sigAlg) @@ -991,7 +992,7 @@ public void testIsInValidSignWithDeprecatedAlg() throws Exception { String sigAlg = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; String signature = "XCwCyI5cs7WhiJlB5ktSlWxSBxv+6q2xT3c8L7dLV6NQG9LHWhN7gf8qNsahSXfCzA0Ey9dp5BQ0EdRvAk2DIzKmJY6e3hvAIEp1zglHNjzkgcQmZCcrkK9Czi2Y1WkjOwR/WgUTUWsGJAVqVvlRZuS3zk3nxMrLH6f7toyvuJc="; - HttpRequest httpRequest = new HttpRequest(requestURL, (String)null) + TestHttpRequest httpRequest = new TestHttpRequest(requestURL, (String)null) .addParameter("SAMLRequest", samlRequestEncoded) .addParameter("RelayState", relayState) .addParameter("SigAlg", sigAlg) @@ -1082,7 +1083,7 @@ public void testGetError() throws Exception { } private static HttpRequest newHttpRequest(String requestURL, String samlRequestEncoded) { - return new HttpRequest(requestURL, (String)null).addParameter("SAMLRequest", samlRequestEncoded); + return new TestHttpRequest(requestURL, (String)null).addParameter("SAMLRequest", samlRequestEncoded); } /** @@ -1090,7 +1091,7 @@ private static HttpRequest newHttpRequest(String requestURL, String samlRequestE * * @throws Exception * - * @see com.onelogin.saml2.logout.LogoutRequest#postProcessXml + * @see com.onelogin.saml2.logout.LogoutRequest#postProcessXml(String, LogoutRequestParams, Saml2Settings) */ @Test public void testPostProcessXml() throws Exception { diff --git a/core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java b/core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java index dbc68c51..462abf2d 100644 --- a/core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java @@ -18,11 +18,12 @@ import javax.xml.xpath.XPathExpressionException; +import com.onelogin.saml2.http.HttpRequest; +import com.onelogin.saml2.http.TestHttpRequest; import org.junit.Test; import com.onelogin.saml2.exception.Error; import com.onelogin.saml2.exception.XMLEntityException; -import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.logout.LogoutResponse; import com.onelogin.saml2.logout.LogoutResponseParams; import com.onelogin.saml2.model.SamlResponseStatus; @@ -46,7 +47,7 @@ public void testGetEncodedLogoutResponseSimulated() throws Exception { Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); final String logoutResponseString = Util.getFileAsString("data/logout_responses/logout_response.xml"); final String requestURL = "/"; - HttpRequest httpRequest = new HttpRequest(requestURL, (String)null); + HttpRequest httpRequest = new TestHttpRequest(requestURL, (String)null); LogoutResponse logoutResponseBuilder = new LogoutResponse(settings, httpRequest) { @Override @@ -202,7 +203,7 @@ public void testBuild() throws IOException, XMLEntityException, URISyntaxExcepti Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); final String requestURL = "/"; - HttpRequest httpRequest = new HttpRequest(requestURL, (String)null); + HttpRequest httpRequest = new TestHttpRequest(requestURL, (String)null); LogoutResponse logoutResponse = new LogoutResponse(settings, httpRequest); assertFalse(logoutResponse.isValid()); @@ -523,7 +524,7 @@ public void testIsValidNoResponse() throws XMLEntityException, IOException, Erro assertFalse(logoutResponse.isValid()); assertEquals("SAML Logout Response is not loaded", logoutResponse.getError()); - httpRequest = new HttpRequest(requestURL, (String)null); + httpRequest = new TestHttpRequest(requestURL, (String)null); logoutResponse = new LogoutResponse(settings, httpRequest); assertFalse(logoutResponse.isValid()); assertEquals("SAML Logout Response is not loaded", logoutResponse.getError()); @@ -706,7 +707,7 @@ public void testIsInValidSign_defaultUrlEncode() throws Exception { //This signature is based on the query string above String signature = "czxEy2WDRZS1U4b2PQFpE4KRhRs8jt5bBKdTFx5oIXpte6qtm0Lk/5lzw/2S6Y1NJpj5DJvSLJvylgNE+RYfJR1GX0zQplm2dZYtlo7CZUyfS3JCLsWviEtPXaon+8Z0lQQkPt4yxCf9v8Qd0pvxHglTUCK/sU0NXnZQdpSxxfsaNCcjQf5gTg/gj8oI7xdrnamBPFtsaH6tAirkjGMoYS4Otju3mcrdcNBIHG40wrffUDnE83Jw4AOFCp8Vsf0zPTQOQsxS4HF4VS78OvGn7jLi2MdabeAQcK5+tP3mUB4vO8AAt8QbkEEiWQbcvA9i1Ezma92CdNYgaf4B3JYpPA=="; - HttpRequest httpRequest = new HttpRequest(requestURL, queryString) + TestHttpRequest httpRequest = new TestHttpRequest(requestURL, queryString) .addParameter("SAMLResponse", samlResponseEncoded) .addParameter("RelayState", relayState) .addParameter("SigAlg", sigAlg) @@ -734,7 +735,7 @@ public void testIsInValidSign_naiveUrlEncoding() throws Exception { //This signature is based on the query string above String signature = "eSoTB+0GA/HfncASEFk7ONHbB3+9YrOBgK9xUyRoCDY97oXw49JYoXOL07kHrVvbngKmKFNx5fnYtDaL8WCe5LfRRgjJz1LLacriHn2ggeMmY/fTaXPoy2zQW0Fv1H362QXicTWQXgWFS5cJAIcBa2I7TLgNwXsMgjdBF2hyacW0IwfkAceGiBwDDTy6XIBAZk2Ff7w5lbZh+fa5JLNKrbvoveJk2NS3KK6INYO7UW5hukWz2cpzbHsx9lfxUJi8/ZCwUtFWZ4rdXVN+Qiw5y8S2eE2BIEfFmz7IfvrMRXa2la/rXFQfmteQo+N1sO3K1YZyoT/aA3k36glXvnj3kw=="; - HttpRequest httpRequest = new HttpRequest(requestURL, queryString) + TestHttpRequest httpRequest = new TestHttpRequest(requestURL, queryString) .addParameter("SAMLResponse", samlResponseEncoded) .addParameter("RelayState", relayState) .addParameter("SigAlg", sigAlg) @@ -766,7 +767,7 @@ public void testIsInValidSign() throws URISyntaxException, IOException, XMLEntit String sigAlg = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; String signature = "vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVfNKGA="; - HttpRequest httpRequest = new HttpRequest(requestURL, (String)null) + TestHttpRequest httpRequest = new TestHttpRequest(requestURL, (String)null) .addParameter("SAMLResponse", samlResponseEncoded) .addParameter("RelayState", relayState) .addParameter("SigAlg", sigAlg) @@ -832,7 +833,7 @@ public void testIsInValidSignWithDeprecatedAlg() throws URISyntaxException, IOEx String sigAlg = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; String signature = "vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVfNKGA="; - HttpRequest httpRequest = new HttpRequest(requestURL, (String)null) + TestHttpRequest httpRequest = new TestHttpRequest(requestURL, (String)null) .addParameter("SAMLResponse", samlResponseEncoded) .addParameter("RelayState", relayState) .addParameter("SigAlg", sigAlg) @@ -901,7 +902,7 @@ public void testGetError() throws URISyntaxException, IOException, XMLEntityExce } private static HttpRequest newHttpRequest(String requestURL, String samlResponseEncoded) { - return new HttpRequest(requestURL, (String)null).addParameter("SAMLResponse", samlResponseEncoded); + return new TestHttpRequest(requestURL, (String)null).addParameter("SAMLResponse", samlResponseEncoded); } /** diff --git a/pom.xml b/pom.xml index d6ebe7a8..8c723a3b 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.onelogin java-saml-toolkit - 2.9.1-SNAPSHOT + 3.0.0-SNAPSHOT pom java-saml Toolkit Project @@ -22,6 +22,9 @@ core toolkit samples + + servlet-javax + servlet-jakarta diff --git a/samples/java-saml-tookit-jspsample/pom.xml b/samples/java-saml-tookit-jspsample/pom.xml index d960d4f7..e0007cdf 100644 --- a/samples/java-saml-tookit-jspsample/pom.xml +++ b/samples/java-saml-tookit-jspsample/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-tookit-samples - 2.9.1-SNAPSHOT + 3.0.0-SNAPSHOT java-saml-tookit-jspsample diff --git a/samples/pom.xml b/samples/pom.xml index 36ab644b..a1d245a5 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.9.1-SNAPSHOT + 3.0.0-SNAPSHOT java-saml-tookit-samples diff --git a/servlet-jakarta/pom.xml b/servlet-jakarta/pom.xml new file mode 100644 index 00000000..d5131464 --- /dev/null +++ b/servlet-jakarta/pom.xml @@ -0,0 +1,93 @@ + + 4.0.0 + + com.onelogin + java-saml-toolkit + 3.0.0-SNAPSHOT + + + jar + java-saml Jakarta servlet EE9 bindings + java-saml-servlet-jakarta + + + + com.onelogin + java-saml-core + ${project.version} + + + + jakarta.servlet + jakarta.servlet-api + 5.0.0 + provided + + + + + com.onelogin + java-saml-core + ${project.version} + test-jar + test + + + org.hamcrest + hamcrest-core + test + + + org.hamcrest + hamcrest-library + test + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.6 + + jacoco.agent.argLine + + + + prepare-agent + + prepare-agent + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + ${project.build.sourceEncoding} + ${project.build.sourceEncoding} + ${project.build.sourceEncoding} + ${jacoco.agent.argLine} -Dfile.encoding=${project.build.sourceEncoding} -Dline.separator=\n + + + + + + diff --git a/servlet-jakarta/src/main/java/com/onelogin/saml2/servlet/jakarta/JakartaSamlHttpRequest.java b/servlet-jakarta/src/main/java/com/onelogin/saml2/servlet/jakarta/JakartaSamlHttpRequest.java new file mode 100644 index 00000000..fadc4d45 --- /dev/null +++ b/servlet-jakarta/src/main/java/com/onelogin/saml2/servlet/jakarta/JakartaSamlHttpRequest.java @@ -0,0 +1,68 @@ +package com.onelogin.saml2.servlet.jakarta; + +import com.onelogin.saml2.http.HttpRequest; +import jakarta.servlet.http.HttpServletRequest; + +import java.util.Map; + +import static com.onelogin.saml2.util.Preconditions.checkNotNull; + +/** + * An EE9 or later implementation of {@link HttpRequest} based the {@code jakarta} flavor + * of {@link HttpServletRequest}. + * + * @see JakartaSamlHttpRequest#makeHttpRequest(HttpServletRequest) + */ +public class JakartaSamlHttpRequest implements HttpRequest { + + private final HttpServletRequest delegate; + + private JakartaSamlHttpRequest(HttpServletRequest delegate) { + this.delegate = checkNotNull(delegate, "Servlet request cannot be null."); + } + + @Override + public int getServerPort() { + return delegate.getServerPort(); + } + + @Override + public String getScheme() { + return delegate.getScheme(); + } + + @Override + public String getServerName() { + return delegate.getServerName(); + } + + @Override + public String getRequestURL() { + return delegate.getRequestURL().toString(); + } + + @Override + public String getRequestURI() { + return delegate.getRequestURI(); + } + + @Override + public String getQueryString() { + return delegate.getQueryString(); + } + + @Override + public Map getParameterMap() { + return delegate.getParameterMap(); + } + + @Override + public void invalidateSession() { + delegate.getSession().invalidate(); + } + + public static HttpRequest makeHttpRequest(HttpServletRequest delegate) { + return new JakartaSamlHttpRequest(delegate); + } + +} diff --git a/servlet-jakarta/src/main/java/com/onelogin/saml2/servlet/jakarta/JakartaSamlHttpResponse.java b/servlet-jakarta/src/main/java/com/onelogin/saml2/servlet/jakarta/JakartaSamlHttpResponse.java new file mode 100644 index 00000000..d6f14f04 --- /dev/null +++ b/servlet-jakarta/src/main/java/com/onelogin/saml2/servlet/jakarta/JakartaSamlHttpResponse.java @@ -0,0 +1,33 @@ +package com.onelogin.saml2.servlet.jakarta; + +import com.onelogin.saml2.http.HttpResponse; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; + +import static com.onelogin.saml2.util.Preconditions.checkNotNull; + +/** + * An EE9 or later implementation of {@link HttpResponse} based the {@code jakarta} flavor + * of {@link HttpServletResponse}. + * + * @see JakartaSamlHttpResponse#makeHttpResponse(HttpServletResponse) + */ +public class JakartaSamlHttpResponse implements HttpResponse { + + private final HttpServletResponse delegate; + + private JakartaSamlHttpResponse(HttpServletResponse delegate) { + this.delegate = checkNotNull(delegate, "Servlet response cannot be null."); + } + + @Override + public void sendRedirect(String location) throws IOException { + delegate.sendRedirect(location); + } + + public static HttpResponse makeHttpResponse(HttpServletResponse delegate) { + return new JakartaSamlHttpResponse(delegate); + } + +} diff --git a/servlet-jakarta/src/test/java/com/onelogin/saml2/test/servlet/jakarta/.gitkeep b/servlet-jakarta/src/test/java/com/onelogin/saml2/test/servlet/jakarta/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/servlet-jakarta/src/test/resources/logback-test.xml b/servlet-jakarta/src/test/resources/logback-test.xml new file mode 100644 index 00000000..60ee6121 --- /dev/null +++ b/servlet-jakarta/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/servlet-javax/pom.xml b/servlet-javax/pom.xml new file mode 100644 index 00000000..f9fc510b --- /dev/null +++ b/servlet-javax/pom.xml @@ -0,0 +1,93 @@ + + 4.0.0 + + com.onelogin + java-saml-toolkit + 3.0.0-SNAPSHOT + + + jar + java-saml Javax Servlet bindings + java-saml-servlet-javax + + + + com.onelogin + java-saml-core + ${project.version} + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + + + + com.onelogin + java-saml-core + ${project.version} + test-jar + test + + + org.hamcrest + hamcrest-core + test + + + org.hamcrest + hamcrest-library + test + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.6 + + jacoco.agent.argLine + + + + prepare-agent + + prepare-agent + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + ${project.build.sourceEncoding} + ${project.build.sourceEncoding} + ${project.build.sourceEncoding} + ${jacoco.agent.argLine} -Dfile.encoding=${project.build.sourceEncoding} -Dline.separator=\n + + + + + + diff --git a/servlet-javax/src/main/java/com/onelogin/saml2/servlet/javax/JavaxSamlHttpRequest.java b/servlet-javax/src/main/java/com/onelogin/saml2/servlet/javax/JavaxSamlHttpRequest.java new file mode 100644 index 00000000..56b0d1dd --- /dev/null +++ b/servlet-javax/src/main/java/com/onelogin/saml2/servlet/javax/JavaxSamlHttpRequest.java @@ -0,0 +1,68 @@ +package com.onelogin.saml2.servlet.javax; + +import com.onelogin.saml2.http.HttpRequest; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +import static com.onelogin.saml2.util.Preconditions.checkNotNull; + +/** + * A pre EE9 implementation of {@link HttpRequest} based the {@code javax} flavor + * of {@link HttpServletRequest}. + * + * @see JavaxSamlHttpRequest#makeHttpRequest(HttpServletRequest) + */ +public class JavaxSamlHttpRequest implements HttpRequest { + + private final HttpServletRequest delegate; + + private JavaxSamlHttpRequest(HttpServletRequest delegate) { + this.delegate = checkNotNull(delegate, "Servlet request cannot be null."); + } + + @Override + public int getServerPort() { + return delegate.getServerPort(); + } + + @Override + public String getScheme() { + return delegate.getScheme(); + } + + @Override + public String getServerName() { + return delegate.getServerName(); + } + + @Override + public String getRequestURL() { + return delegate.getRequestURL().toString(); + } + + @Override + public String getRequestURI() { + return delegate.getRequestURI(); + } + + @Override + public String getQueryString() { + return delegate.getQueryString(); + } + + @Override + public Map getParameterMap() { + return delegate.getParameterMap(); + } + + @Override + public void invalidateSession() { + delegate.getSession().invalidate(); + } + + public static HttpRequest makeHttpRequest(HttpServletRequest delegate) { + return new JavaxSamlHttpRequest(delegate); + } + +} diff --git a/servlet-javax/src/main/java/com/onelogin/saml2/servlet/javax/JavaxSamlHttpResponse.java b/servlet-javax/src/main/java/com/onelogin/saml2/servlet/javax/JavaxSamlHttpResponse.java new file mode 100644 index 00000000..8fe21f3c --- /dev/null +++ b/servlet-javax/src/main/java/com/onelogin/saml2/servlet/javax/JavaxSamlHttpResponse.java @@ -0,0 +1,33 @@ +package com.onelogin.saml2.servlet.javax; + +import com.onelogin.saml2.http.HttpResponse; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static com.onelogin.saml2.util.Preconditions.checkNotNull; + +/** + * A pre EE9 implementation of {@link HttpResponse} based the {@code javax} flavor + * of {@link HttpServletResponse}. + * + * @see JavaxSamlHttpResponse#makeHttpResponse(HttpServletResponse) + */ +public class JavaxSamlHttpResponse implements HttpResponse { + + private final HttpServletResponse delegate; + + private JavaxSamlHttpResponse(HttpServletResponse delegate) { + this.delegate = checkNotNull(delegate, "Servlet response cannot be null."); + } + + @Override + public void sendRedirect(String location) throws IOException { + delegate.sendRedirect(location); + } + + public static HttpResponse makeHttpResponse(HttpServletResponse delegate) { + return new JavaxSamlHttpResponse(delegate); + } + +} diff --git a/servlet-javax/src/test/java/com/onelogin/saml2/test/servlet/javax/.gitkeep b/servlet-javax/src/test/java/com/onelogin/saml2/test/servlet/javax/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/servlet-javax/src/test/resources/logback-test.xml b/servlet-javax/src/test/resources/logback-test.xml new file mode 100644 index 00000000..60ee6121 --- /dev/null +++ b/servlet-javax/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/toolkit/pom.xml b/toolkit/pom.xml index 3cb2ab03..f848a229 100644 --- a/toolkit/pom.xml +++ b/toolkit/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.9.1-SNAPSHOT + 3.0.0-SNAPSHOT jar @@ -57,14 +57,6 @@ true - - - javax.servlet - javax.servlet-api - 4.0.1 - provided - - org.apache.commons diff --git a/toolkit/src/main/java/com/onelogin/saml2/Auth.java b/toolkit/src/main/java/com/onelogin/saml2/Auth.java index 9d8f29cb..79e0c4f4 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/Auth.java +++ b/toolkit/src/main/java/com/onelogin/saml2/Auth.java @@ -14,9 +14,10 @@ import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.onelogin.saml2.http.HttpRequestUtils; +import com.onelogin.saml2.http.HttpResponseUtils; +import com.onelogin.saml2.http.HttpRequest; +import com.onelogin.saml2.http.HttpResponse; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,14 +28,12 @@ import com.onelogin.saml2.exception.SettingsException; import com.onelogin.saml2.factory.SamlMessageFactory; import com.onelogin.saml2.exception.Error; -import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.logout.LogoutRequest; import com.onelogin.saml2.logout.LogoutRequestParams; import com.onelogin.saml2.logout.LogoutResponse; import com.onelogin.saml2.logout.LogoutResponseParams; import com.onelogin.saml2.model.SamlResponseStatus; import com.onelogin.saml2.model.KeyStoreSettings; -import com.onelogin.saml2.servlet.ServletUtils; import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.settings.SettingsBuilder; import com.onelogin.saml2.util.Constants; @@ -62,14 +61,14 @@ public class Auth { private Saml2Settings settings; /** - * HttpServletRequest object to be processed (Contains GET and POST parameters, session, ...). + * HttpRequest object to be processed (Contains GET and POST parameters, session, ...). */ - private HttpServletRequest request; + private HttpRequest request; /** - * HttpServletResponse object to be used (For example to execute the redirections). + * HttpResponse object to be used (For example to execute the redirections). */ - private HttpServletResponse response; + private HttpResponse response; /** * NameID. @@ -228,14 +227,14 @@ public Auth(String filename, KeyStoreSettings keyStoreSetting) /** * Initializes the SP SAML instance. * - * @param request HttpServletRequest object to be processed - * @param response HttpServletResponse object to be used + * @param request HttpRequest object to be processed + * @param response HttpResponse object to be used * * @throws IOException * @throws SettingsException * @throws Error */ - public Auth(HttpServletRequest request, HttpServletResponse response) throws IOException, SettingsException, Error { + public Auth(HttpRequest request, HttpResponse response) throws IOException, SettingsException, Error { this(new SettingsBuilder().fromFile("onelogin.saml.properties").build(), request, response); } @@ -243,14 +242,14 @@ public Auth(HttpServletRequest request, HttpServletResponse response) throws IOE * Initializes the SP SAML instance. * * @param keyStoreSetting KeyStoreSettings is a KeyStore which have the Private/Public keys - * @param request HttpServletRequest object to be processed - * @param response HttpServletResponse object to be used + * @param request HttpRequest object to be processed + * @param response HttpResponse object to be used * * @throws IOException * @throws SettingsException * @throws Error */ - public Auth(KeyStoreSettings keyStoreSetting, HttpServletRequest request, HttpServletResponse response) + public Auth(KeyStoreSettings keyStoreSetting, HttpRequest request, HttpResponse response) throws IOException, SettingsException, Error { this(new SettingsBuilder().fromFile("onelogin.saml.properties", keyStoreSetting).build(), request, response); @@ -260,14 +259,14 @@ public Auth(KeyStoreSettings keyStoreSetting, HttpServletRequest request, HttpSe * Initializes the SP SAML instance. * * @param filename String Filename with the settings - * @param request HttpServletRequest object to be processed - * @param response HttpServletResponse object to be used + * @param request HttpRequest object to be processed + * @param response HttpResponse object to be used * * @throws SettingsException * @throws IOException * @throws Error */ - public Auth(String filename, HttpServletRequest request, HttpServletResponse response) + public Auth(String filename, HttpRequest request, HttpResponse response) throws SettingsException, IOException, Error { this(filename, null, request, response); } @@ -277,15 +276,15 @@ public Auth(String filename, HttpServletRequest request, HttpServletResponse res * * @param filename String Filename with the settings * @param keyStoreSetting KeyStoreSettings is a KeyStore which have the Private/Public keys - * @param request HttpServletRequest object to be processed - * @param response HttpServletResponse object to be used + * @param request HttpRequest object to be processed + * @param response HttpResponse object to be used * * @throws SettingsException * @throws IOException * @throws Error */ - public Auth(String filename, KeyStoreSettings keyStoreSetting, HttpServletRequest request, - HttpServletResponse response) throws SettingsException, IOException, Error { + public Auth(String filename, KeyStoreSettings keyStoreSetting, HttpRequest request, + HttpResponse response) throws SettingsException, IOException, Error { this(new SettingsBuilder().fromFile(filename, keyStoreSetting).build(), request, response); } @@ -293,12 +292,12 @@ public Auth(String filename, KeyStoreSettings keyStoreSetting, HttpServletReques * Initializes the SP SAML instance. * * @param settings Saml2Settings object. Setting data - * @param request HttpServletRequest object to be processed - * @param response HttpServletResponse object to be used + * @param request HttpRequest object to be processed + * @param response HttpResponse object to be used * * @throws SettingsException */ - public Auth(Saml2Settings settings, HttpServletRequest request, HttpServletResponse response) + public Auth(Saml2Settings settings, HttpRequest request, HttpResponse response) throws SettingsException { this.settings = settings; this.request = request; @@ -625,7 +624,7 @@ public String login(String relayState, AuthnRequestParams authnRequestParams, Bo parameters.put("SAMLRequest", samlRequest); if (relayState == null) { - relayState = ServletUtils.getSelfRoutedURLNoQuery(request); + relayState = HttpRequestUtils.getSelfRoutedURLNoQuery(request); } if (!relayState.isEmpty()) { @@ -648,7 +647,7 @@ public String login(String relayState, AuthnRequestParams authnRequestParams, Bo if (!stay) { LOGGER.debug("AuthNRequest sent to " + ssoUrl + " --> " + samlRequest); } - return ServletUtils.sendRedirect(response, ssoUrl, parameters, stay); + return HttpResponseUtils.sendRedirect(response, ssoUrl, parameters, stay); } /** @@ -795,7 +794,7 @@ public String logout(String relayState, LogoutRequestParams logoutRequestParams, parameters.put("SAMLRequest", samlLogoutRequest); if (relayState == null) { - relayState = ServletUtils.getSelfRoutedURLNoQuery(request); + relayState = HttpRequestUtils.getSelfRoutedURLNoQuery(request); } if (!relayState.isEmpty()) { @@ -818,7 +817,7 @@ public String logout(String relayState, LogoutRequestParams logoutRequestParams, if (!stay) { LOGGER.debug("Logout request sent to " + sloUrl + " --> " + samlLogoutRequest); } - return ServletUtils.sendRedirect(response, sloUrl, parameters, stay); + return HttpResponseUtils.sendRedirect(response, sloUrl, parameters, stay); } /** @@ -1197,11 +1196,10 @@ public String getSLOResponseUrl() { */ public void processResponse(String requestId) throws Exception { authenticated = false; - final HttpRequest httpRequest = ServletUtils.makeHttpRequest(this.request); - final String samlResponseParameter = httpRequest.getParameter("SAMLResponse"); + final String samlResponseParameter = request.getParameter("SAMLResponse"); if (samlResponseParameter != null) { - SamlResponse samlResponse = samlMessageFactory.createSamlResponse(settings, httpRequest); + SamlResponse samlResponse = samlMessageFactory.createSamlResponse(settings, request); lastResponse = samlResponse.getSAMLResponseXml(); if (samlResponse.isValid(requestId)) { @@ -1268,13 +1266,11 @@ public void processResponse() throws Exception { * @throws Exception */ public String processSLO(Boolean keepLocalSession, String requestId, Boolean stay) throws Exception { - final HttpRequest httpRequest = ServletUtils.makeHttpRequest(this.request); - - final String samlRequestParameter = httpRequest.getParameter("SAMLRequest"); - final String samlResponseParameter = httpRequest.getParameter("SAMLResponse"); + final String samlRequestParameter = request.getParameter("SAMLRequest"); + final String samlResponseParameter = request.getParameter("SAMLResponse"); if (samlResponseParameter != null) { - LogoutResponse logoutResponse = samlMessageFactory.createIncomingLogoutResponse(settings, httpRequest); + LogoutResponse logoutResponse = samlMessageFactory.createIncomingLogoutResponse(settings, request); lastResponse = logoutResponse.getLogoutResponseXml(); if (!logoutResponse.isValid(requestId)) { errors.add("invalid_logout_response"); @@ -1298,13 +1294,13 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta lastMessageIssueInstant = logoutResponse.getIssueInstant(); LOGGER.debug("processSLO success --> " + samlResponseParameter); if (!keepLocalSession) { - request.getSession().invalidate(); + request.invalidateSession(); } } } return null; } else if (samlRequestParameter != null) { - LogoutRequest logoutRequest = samlMessageFactory.createIncomingLogoutRequest(settings, httpRequest); + LogoutRequest logoutRequest = samlMessageFactory.createIncomingLogoutRequest(settings, request); lastRequest = logoutRequest.getLogoutRequestXml(); if (!logoutRequest.isValid()) { errors.add("invalid_logout_request"); @@ -1318,7 +1314,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta lastMessageIssueInstant = logoutRequest.getIssueInstant(); LOGGER.debug("processSLO success --> " + samlRequestParameter); if (!keepLocalSession) { - request.getSession().invalidate(); + request.invalidateSession(); } String inResponseTo = logoutRequest.id; @@ -1350,7 +1346,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta if (!stay) { LOGGER.debug("Logout response sent to " + sloUrl + " --> " + samlLogoutResponse); } - return ServletUtils.sendRedirect(response, sloUrl, parameters, stay); + return HttpResponseUtils.sendRedirect(response, sloUrl, parameters, stay); } } else { errors.add("invalid_binding"); diff --git a/toolkit/src/main/java/com/onelogin/saml2/servlet/ServletUtils.java b/toolkit/src/main/java/com/onelogin/saml2/servlet/ServletUtils.java deleted file mode 100644 index 1c2f7bb9..00000000 --- a/toolkit/src/main/java/com/onelogin/saml2/servlet/ServletUtils.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.onelogin.saml2.servlet; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; - -import com.onelogin.saml2.http.HttpRequest; -import com.onelogin.saml2.util.Util; - -/** - * ServletUtils class of Java Toolkit. - * - * A class that contains several auxiliary methods related to HttpServletRequest and HttpServletResponse - */ -public class ServletUtils { - - private ServletUtils() { - //not called - } - - /** - * Creates an HttpRequest from an HttpServletRequest. - * - * @param req the incoming HttpServletRequest - * @return a HttpRequest - */ - public static HttpRequest makeHttpRequest(HttpServletRequest req) { - @SuppressWarnings("unchecked") - final Map paramsAsArray = (Map) req.getParameterMap(); - final Map> paramsAsList = new HashMap<>(); - for (Map.Entry param : paramsAsArray.entrySet()) { - paramsAsList.put(param.getKey(), Arrays.asList(param.getValue())); - } - - return new HttpRequest(req.getRequestURL().toString(), paramsAsList, req.getQueryString()); - } - - /** - * Returns the protocol + the current host + the port (if different than - * common ports). - * - * @param request - * HttpServletRequest object to be processed - * - * @return the HOST URL - */ - public static String getSelfURLhost(HttpServletRequest request) { - String hostUrl = StringUtils.EMPTY; - final int serverPort = request.getServerPort(); - if ((serverPort == 80) || (serverPort == 443) || serverPort == 0) { - hostUrl = String.format("%s://%s", request.getScheme(), request.getServerName()); - } else { - hostUrl = String.format("%s://%s:%s", request.getScheme(), request.getServerName(), serverPort); - } - return hostUrl; - } - - /** - * @param request - * HttpServletRequest object to be processed - * - * @return the server name - */ - public static String getSelfHost(HttpServletRequest request) { - return request.getServerName(); - } - - /** - * Check if under https or http protocol - * - * @param request - * HttpServletRequest object to be processed - * - * @return false if https is not active - */ - public static boolean isHTTPS(HttpServletRequest request) { - return request.isSecure(); - } - - /** - * Returns the URL of the current context + current view + query - * - * @param request - * HttpServletRequest object to be processed - * - * @return current context + current view + query - */ - public static String getSelfURL(HttpServletRequest request) { - String url = getSelfURLhost(request); - - String requestUri = request.getRequestURI(); - String queryString = request.getQueryString(); - - if (null != requestUri && !requestUri.isEmpty()) { - url += requestUri; - } - - if (null != queryString && !queryString.isEmpty()) { - url += '?' + queryString; - } - return url; - } - - /** - * Returns the URL of the current host + current view. - * - * @param request - * HttpServletRequest object to be processed - * - * @return current host + current view - */ - public static String getSelfURLNoQuery(HttpServletRequest request) { - return request.getRequestURL().toString(); - } - - /** - * Returns the routed URL of the current host + current view. - * - * @param request - * HttpServletRequest object to be processed - * - * @return the current routed url - */ - public static String getSelfRoutedURLNoQuery(HttpServletRequest request) { - String url = getSelfURLhost(request); - String requestUri = request.getRequestURI(); - if (null != requestUri && !requestUri.isEmpty()) { - url += requestUri; - } - return url; - } - - /** - * Redirect to location url - * - * @param response - * HttpServletResponse object to be used - * @param location - * target location url - * @param parameters - * GET parameters to be added - * @param stay - * True if we want to stay (returns the url string) False to execute redirection - * - * @return string the target URL - * @throws IOException - * - * @see javax.servlet.http.HttpServletResponse#sendRedirect(String) - */ - public static String sendRedirect(HttpServletResponse response, String location, Map parameters, Boolean stay) throws IOException { - String target = location; - - if (!parameters.isEmpty()) { - boolean first = !location.contains("?"); - for (Map.Entry parameter : parameters.entrySet()) - { - if (first) { - target += "?"; - first = false; - } else { - target += "&"; - } - target += parameter.getKey(); - if (!parameter.getValue().isEmpty()) { - target += "=" + Util.urlEncoder(parameter.getValue()); - } - } - } - if (!stay) { - response.sendRedirect(target); - } - - return target; - } - - /** - * Redirect to location url - * - * @param response - * HttpServletResponse object to be used - * @param location - * target location url - * @param parameters - * GET parameters to be added - * - * @throws IOException - * - * @see javax.servlet.http.HttpServletResponse#sendRedirect(String) - */ - public static void sendRedirect(HttpServletResponse response, String location, Map parameters) throws IOException { - sendRedirect(response, location, parameters, false); - } - - /** - * Redirect to location url - * - * @param response - * HttpServletResponse object to be used - * @param location - * target location url - * - * @throws IOException - * - * @see HttpServletResponse#sendRedirect(String) - */ - public static void sendRedirect(HttpServletResponse response, String location) throws IOException { - Map parameters =new HashMap(); - sendRedirect(response, location, parameters); - } -} diff --git a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java index 53c82ef5..f803d9c7 100644 --- a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java +++ b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java @@ -1,52 +1,5 @@ package com.onelogin.saml2.test; - -import static java.util.Collections.singletonMap; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.Matchers.contains; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.matches; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentCaptor; -import org.w3c.dom.Document; - import com.onelogin.saml2.Auth; import com.onelogin.saml2.authn.AuthnRequest; import com.onelogin.saml2.authn.AuthnRequestParams; @@ -57,17 +10,55 @@ import com.onelogin.saml2.exception.XMLEntityException; import com.onelogin.saml2.factory.SamlMessageFactory; import com.onelogin.saml2.http.HttpRequest; +import com.onelogin.saml2.http.HttpResponse; import com.onelogin.saml2.logout.LogoutRequest; import com.onelogin.saml2.logout.LogoutRequestParams; import com.onelogin.saml2.logout.LogoutResponse; import com.onelogin.saml2.logout.LogoutResponseParams; import com.onelogin.saml2.model.KeyStoreSettings; import com.onelogin.saml2.model.SamlResponseStatus; -import com.onelogin.saml2.servlet.ServletUtils; import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.settings.SettingsBuilder; import com.onelogin.saml2.util.Constants; import com.onelogin.saml2.util.Util; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.w3c.dom.Document; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.time.Instant; +import java.util.*; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.Matchers.contains; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.matches; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class AuthTest { @@ -179,7 +170,7 @@ public void testConstructorWithFilenameAndKeyStore() throws IOException, Setting /** * Tests the constructor of Auth - * Case: HttpServletRequest and HttpServletResponse provided + * Case: HttpRequest and HttpResponse provided * * @throws SettingsException * @throws IOException @@ -190,10 +181,10 @@ public void testConstructorWithFilenameAndKeyStore() throws IOException, Setting */ @Test public void testConstructorWithReqRes() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth = new Auth(request, response); assertTrue(auth.getSettings() != null); @@ -205,7 +196,7 @@ public void testConstructorWithReqRes() throws IOException, SettingsException, U /** * Tests the constructor of Auth - * Case: KeyStore and HttpServletRequest and HttpServletResponse provided + * Case: KeyStore and HttpRequest and HttpResponse provided * * @throws SettingsException * @throws IOException @@ -219,8 +210,8 @@ public void testConstructorWithReqRes() throws IOException, SettingsException, U */ @Test public void testConstructorWithReqResAndKeyStore() throws IOException, SettingsException, URISyntaxException, Error, KeyStoreException, NoSuchAlgorithmException, CertificateException { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); Auth auth = new Auth(getKeyStoreSettings(), request, response); assertTrue(auth.getSettings() != null); @@ -234,7 +225,7 @@ public void testConstructorWithReqResAndKeyStore() throws IOException, SettingsE /** * Tests the constructor of Auth - * Case: filename, HttpServletRequest and HttpServletResponse provided + * Case: filename, HttpRequest and HttpResponse provided * * @throws SettingsException * @throws IOException @@ -245,10 +236,10 @@ public void testConstructorWithReqResAndKeyStore() throws IOException, SettingsE */ @Test public void testConstructorWithFilenameReqRes() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth = new Auth("config/config.min.properties", request, response); assertTrue(auth.getSettings() != null); @@ -260,7 +251,7 @@ public void testConstructorWithFilenameReqRes() throws IOException, SettingsExce /** * Tests the constructor of Auth - * Case: settings, HttpServletRequest and HttpServletResponse provided + * Case: settings, HttpRequest and HttpResponse provided * * @throws SettingsException * @throws IOException @@ -271,10 +262,10 @@ public void testConstructorWithFilenameReqRes() throws IOException, SettingsExce */ @Test public void testConstructorWithSettingsReqRes() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); @@ -284,7 +275,7 @@ public void testConstructorWithSettingsReqRes() throws IOException, SettingsExce /** * Tests the constructor of Auth - * Case: settings, HttpServletRequest and HttpServletResponse provided + * Case: settings, HttpRequest and HttpResponse provided * * @throws SettingsException * @throws IOException @@ -295,10 +286,10 @@ public void testConstructorWithSettingsReqRes() throws IOException, SettingsExce */ @Test public void testConstructorInvalidSettings() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.sperrors.properties").build(); @@ -367,10 +358,10 @@ public void testSetStrict() throws IOException, SettingsException, URISyntaxExce */ @Test public void testIsDebugActive() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletResponse response = mock(HttpServletResponse.class); - HttpServletRequest request = mock(HttpServletRequest.class); + HttpResponse response = mock(HttpResponse.class); + HttpRequest request = mock(HttpRequest.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); settings.setDebug(false); @@ -395,10 +386,10 @@ public void testIsDebugActive() throws IOException, SettingsException, URISyntax */ @Test public void testGetSSOurl() throws URISyntaxException, IOException, SettingsException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); @@ -418,10 +409,10 @@ public void testGetSSOurl() throws URISyntaxException, IOException, SettingsExce */ @Test public void testGetSLOurl() throws URISyntaxException, IOException, SettingsException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); @@ -442,10 +433,10 @@ public void testGetSLOurl() throws URISyntaxException, IOException, SettingsExce */ @Test public void testGetSLOResponseUrl() throws URISyntaxException, IOException, SettingsException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.all.properties").build(); @@ -465,10 +456,10 @@ public void testGetSLOResponseUrl() throws URISyntaxException, IOException, Sett */ @Test public void testGetSLOResponseUrlNull() throws URISyntaxException, IOException, SettingsException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); @@ -485,9 +476,9 @@ public void testGetSLOResponseUrlNull() throws URISyntaxException, IOException, */ @Test public void testProcessNoResponse() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -517,12 +508,12 @@ public void testProcessNoResponse() throws Exception { */ @Test public void testProcessResponse() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -533,7 +524,7 @@ public void testProcessResponse() throws Exception { assertTrue(auth.getAttributes().isEmpty()); samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth2 = new Auth(settings, request, response); HashMap> expectedAttributes = new LinkedHashMap>(); @@ -577,21 +568,19 @@ public void testProcessResponse() throws Exception { */ @Test public void testProcessResponseStatusResponder() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("https://example.com/opensso/Consumer/metaAlias/sp")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("https://example.com/opensso/Consumer/metaAlias/sp"); String samlResponseEncoded = Util.getFileAsString("data/responses/invalids/status_code_and_sub_status_code_responder_and_msg.xml.base64"); Document samlResponseDoc = Util.loadXML(new String(Util.base64decoder(samlResponseEncoded))); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); auth.processResponse(); - verify(session, times(0)).invalidate(); + verify(request, times(0)).invalidateSession(); assertFalse(auth.getErrors().isEmpty()); assertEquals("The status code of the Response was not Success, was urn:oasis:names:tc:SAML:2.0:status:Responder -> something_is_wrong", auth.getLastErrorReason()); assertTrue(auth.getErrors().contains("response_not_success")); @@ -608,9 +597,9 @@ public void testProcessResponseStatusResponder() throws Exception { */ @Test public void testProcessSLONoMessage() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -638,14 +627,12 @@ public void testProcessSLONoMessage() throws Exception { */ @Test public void testProcessSLORequestKeepSession() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded})); + when(request.getParameter(eq("SAMLRequest"))).thenReturn(samlRequestEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); @@ -653,7 +640,7 @@ public void testProcessSLORequestKeepSession() throws Exception { assertTrue(auth.getErrors().isEmpty()); auth.processSLO(true, null); verify(response).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*")); - verify(session, times(0)).invalidate(); + verify(request, times(0)).invalidateSession(); assertTrue(auth.getErrors().isEmpty()); } @@ -667,21 +654,19 @@ public void testProcessSLORequestKeepSession() throws Exception { */ @Test public void testProcessSLORequestRemoveSession() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded})); + when(request.getParameter(eq("SAMLRequest"))).thenReturn(samlRequestEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); auth.processSLO(); verify(response).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*")); - verify(session, times(1)).invalidate(); + verify(request, times(1)).invalidateSession(); assertTrue(auth.getErrors().isEmpty()); } @@ -695,21 +680,19 @@ public void testProcessSLORequestRemoveSession() throws Exception { */ @Test public void testProcessSLORequestStay() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded})); + when(request.getParameter(eq("SAMLRequest"))).thenReturn(samlRequestEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); auth.processSLO(false, null); verify(response).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*")); - verify(session, times(1)).invalidate(); + verify(request, times(1)).invalidateSession(); assertTrue(auth.getErrors().isEmpty()); } @@ -723,14 +706,12 @@ public void testProcessSLORequestStay() throws Exception { */ @Test public void testProcessSLORequestStayFalse() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded})); + when(request.getParameter(eq("SAMLRequest"))).thenReturn(samlRequestEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); @@ -738,7 +719,7 @@ public void testProcessSLORequestStayFalse() throws Exception { String target = auth.processSLO(false, null, false); verify(response).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*")); verify(response, times(1)).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*")); - verify(session, times(1)).invalidate(); + verify(request, times(1)).invalidateSession(); assertTrue(auth.getErrors().isEmpty()); assertThat(target, startsWith("http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php?SAMLResponse=")); } @@ -753,21 +734,19 @@ public void testProcessSLORequestStayFalse() throws Exception { */ @Test public void testProcessSLORequestStayTrue() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded})); + when(request.getParameter(eq("SAMLRequest"))).thenReturn(samlRequestEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); String target = auth.processSLO(false, null, true); verify(response, times(0)).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*")); - verify(session, times(1)).invalidate(); + verify(request, times(1)).invalidateSession(); assertTrue(auth.getErrors().isEmpty()); assertThat(target, startsWith("http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php?SAMLResponse=")); } @@ -782,19 +761,13 @@ public void testProcessSLORequestStayTrue() throws Exception { */ @Test public void testProcessSLORequestSignRes() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String relayState = "http://localhost:8080/expected.jsp"; String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64"); - Map paramsAsArray = new HashMap<>(); - paramsAsArray.put("SAMLRequest", new String[]{samlRequestEncoded}); - paramsAsArray.put("RelayState", new String[]{relayState}); - when(request.getParameterMap()).thenReturn(paramsAsArray); - when(request.getParameter("RelayState")).thenReturn(relayState); - + when(request.getParameter(eq("SAMLRequest"))).thenReturn(samlRequestEncoded); + when(request.getParameter(eq("RelayState"))).thenReturn(relayState); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.all.properties").build(); settings.setWantMessagesSigned(false); @@ -804,7 +777,7 @@ public void testProcessSLORequestSignRes() throws Exception { assertTrue(auth.getErrors().isEmpty()); auth.processSLO(); verify(response).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutServiceResponse.php\\?SAMLResponse=(.)*&RelayState=http%3A%2F%2Flocalhost%3A8080%2Fexpected.jsp&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha512&Signature=(.)*")); - verify(session, times(1)).invalidate(); + verify(request, times(1)).invalidateSession(); assertTrue(auth.getErrors().isEmpty()); } @@ -818,21 +791,19 @@ public void testProcessSLORequestSignRes() throws Exception { */ @Test public void testProcessSLORequestInvalid() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/sls.jsp")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/sls.jsp"); String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded})); + when(request.getParameter(eq("SAMLRequest"))).thenReturn(samlRequestEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); settings.setStrict(true); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); auth.processSLO(); - verify(session, times(0)).invalidate(); + verify(request, times(0)).invalidateSession(); assertFalse(auth.getErrors().isEmpty()); assertTrue(auth.getErrors().contains("invalid_logout_request")); assertThat(auth.getLastErrorReason(), containsString("The LogoutRequest was received at")); @@ -849,20 +820,18 @@ public void testProcessSLORequestInvalid() throws Exception { */ @Test public void testProcessSLOResponseKeepSession() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlResponseEncoded = Util.getFileAsString("data/logout_responses/logout_response_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); auth.processSLO(true, null); - verify(session, times(0)).invalidate(); + verify(request, times(0)).invalidateSession(); assertTrue(auth.getErrors().isEmpty()); } @@ -876,20 +845,18 @@ public void testProcessSLOResponseKeepSession() throws Exception { */ @Test public void testProcessSLOResponseRemoveSession() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlResponseEncoded = Util.getFileAsString("data/logout_responses/logout_response_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); auth.processSLO(); - verify(session, times(1)).invalidate(); + verify(request, times(1)).invalidateSession(); assertTrue(auth.getErrors().isEmpty()); } @@ -903,21 +870,19 @@ public void testProcessSLOResponseRemoveSession() throws Exception { */ @Test public void testProcessSLOResponseWrongRequestId() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlResponseEncoded = Util.getFileAsString("data/logout_responses/logout_response_deflated.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); settings.setStrict(true); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); auth.processSLO(false, "wrong_request_id"); - verify(session, times(0)).invalidate(); + verify(request, times(0)).invalidateSession(); assertTrue(auth.getErrors().contains("invalid_logout_response")); assertEquals("The InResponseTo of the Logout Response: ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e, does not match the ID of the Logout request sent by the SP: wrong_request_id", auth.getLastErrorReason()); } @@ -932,20 +897,18 @@ public void testProcessSLOResponseWrongRequestId() throws Exception { */ @Test public void testProcessSLOResponseStatusResponder() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - HttpSession session = mock(HttpSession.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); - when(request.getSession()).thenReturn(session); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("http://stuff.com/endpoints/endpoints/sls.php"); String samlResponseEncoded = Util.getFileAsString("data/logout_responses/invalids/status_code_responder.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); assertFalse(auth.isAuthenticated()); assertTrue(auth.getErrors().isEmpty()); auth.processSLO(); - verify(session, times(0)).invalidate(); + verify(request, times(0)).invalidateSession(); assertFalse(auth.getErrors().isEmpty()); assertTrue(auth.getErrors().contains("logout_not_success")); assertTrue(auth.getErrors().contains(Constants.STATUS_RESPONDER)); @@ -962,11 +925,11 @@ public void testProcessSLOResponseStatusResponder() throws Exception { */ @Test public void testIsAuthenticated() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response4.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -982,7 +945,7 @@ public void testIsAuthenticated() throws Exception { assertTrue(auth.getLastValidationException() instanceof ValidationError); samlResponseEncoded = Util.getFileAsString("data/responses/valid_encrypted_assertion.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth2 = new Auth(settings, request, response); assertFalse(auth2.isAuthenticated()); assertTrue(auth2.getErrors().isEmpty()); @@ -996,7 +959,7 @@ public void testIsAuthenticated() throws Exception { assertTrue(auth2.getLastValidationException() instanceof ValidationError); samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth3 = new Auth(settings, request, response); assertFalse(auth3.isAuthenticated()); assertTrue(auth3.getErrors().isEmpty()); @@ -1017,11 +980,11 @@ public void testIsAuthenticated() throws Exception { */ @Test public void testGetNameID() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -1031,7 +994,7 @@ public void testGetNameID() throws Exception { assertNull(auth.getNameId()); samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth2 = new Auth(settings, request, response); assertNull(auth2.getNameId()); auth2.processResponse(); @@ -1039,8 +1002,8 @@ public void testGetNameID() throws Exception { assertEquals("492882615acf31c8096b627245d76ae53036c090", auth2.getNameId()); samlResponseEncoded = Util.getFileAsString("data/responses/response_encrypted_nameid.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("https://pitbulk.no-ip.org/newonelogin/demo1/index.php?acs")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("https://pitbulk.no-ip.org/newonelogin/demo1/index.php?acs"); settings.setStrict(false); Auth auth3 = new Auth(settings, request, response); assertNull(auth3.getNameId()); @@ -1059,11 +1022,11 @@ public void testGetNameID() throws Exception { */ @Test public void testGetNameIdFormat() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -1073,7 +1036,7 @@ public void testGetNameIdFormat() throws Exception { assertNull(auth.getNameIdFormat()); samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth2 = new Auth(settings, request, response); assertNull(auth2.getNameIdFormat()); auth2.processResponse(); @@ -1081,8 +1044,8 @@ public void testGetNameIdFormat() throws Exception { assertEquals("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", auth2.getNameIdFormat()); samlResponseEncoded = Util.getFileAsString("data/responses/response_encrypted_nameid.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("https://pitbulk.no-ip.org/newonelogin/demo1/index.php?acs")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("https://pitbulk.no-ip.org/newonelogin/demo1/index.php?acs"); settings.setStrict(false); Auth auth3 = new Auth(settings, request, response); assertNull(auth3.getNameIdFormat()); @@ -1100,11 +1063,11 @@ public void testGetNameIdFormat() throws Exception { */ @Test public void testGetNameIdNameQualifier() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -1115,7 +1078,7 @@ public void testGetNameIdNameQualifier() throws Exception { samlResponseEncoded = Util.getFileAsString("data/responses/valid_response_with_namequalifier.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth2 = new Auth(settings, request, response); assertNull(auth2.getNameIdNameQualifier()); auth2.processResponse(); @@ -1132,11 +1095,11 @@ public void testGetNameIdNameQualifier() throws Exception { */ @Test public void testGetNameIdSPNameQualifier() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -1147,7 +1110,7 @@ public void testGetNameIdSPNameQualifier() throws Exception { samlResponseEncoded = Util.getFileAsString("data/responses/valid_response_with_namequalifier.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth2 = new Auth(settings, request, response); assertNull(auth2.getNameIdSPNameQualifier()); auth2.processResponse(); @@ -1164,12 +1127,12 @@ public void testGetNameIdSPNameQualifier() throws Exception { */ @Test public void testGetNameIDEncWithNoKey() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.mywithnocert.properties").build(); String samlResponseEncoded = Util.getFileAsString("data/responses/response_encrypted_nameid.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("https://pitbulk.no-ip.org/newonelogin/demo1/index.php?acs")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("https://pitbulk.no-ip.org/newonelogin/demo1/index.php?acs"); settings.setStrict(false); expectedEx.expect(SettingsException.class); @@ -1186,11 +1149,11 @@ public void testGetNameIDEncWithNoKey() throws Exception { */ @Test public void testOnlyRetrieveAssertionWithIDThatMatchesSignatureReference() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/invalids/wrapped_response_2.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -1209,11 +1172,11 @@ public void testOnlyRetrieveAssertionWithIDThatMatchesSignatureReference() throw */ @Test public void testGetSessionIndex() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -1223,7 +1186,7 @@ public void testGetSessionIndex() throws Exception { assertNull(auth.getSessionIndex()); samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth2 = new Auth(settings, request, response); assertNull(auth2.getSessionIndex()); auth2.processResponse(); @@ -1233,11 +1196,11 @@ public void testGetSessionIndex() throws Exception { @Test public void testGetAssertionDetails() throws Exception { - HttpServletResponse response = mock(HttpServletResponse.class); - HttpServletRequest request = mock(HttpServletRequest.class); + HttpResponse response = mock(HttpResponse.class); + HttpRequest request = mock(HttpRequest.class); String samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -1256,11 +1219,11 @@ public void testGetAssertionDetails() throws Exception { */ @Test public void testGetSessionExpiration() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); - when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/java-saml-jspsample/acs.jsp")); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); + when(request.getRequestURL()).thenReturn("http://localhost:8080/java-saml-jspsample/acs.jsp"); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -1270,7 +1233,7 @@ public void testGetSessionExpiration() throws Exception { assertNull(auth.getSessionExpiration()); samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Auth auth2 = new Auth(settings, request, response); assertNull(auth2.getSessionExpiration()); auth2.processResponse(); @@ -1291,8 +1254,8 @@ public void testGetSessionExpiration() throws Exception { */ @Test public void testLogin() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1319,8 +1282,8 @@ public void testLogin() throws IOException, SettingsException, URISyntaxExceptio */ @Test public void testLoginWithRelayState() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1348,8 +1311,8 @@ public void testLoginWithRelayState() throws IOException, SettingsException, URI */ @Test public void testLoginWithoutRelayState() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1379,8 +1342,8 @@ public void testLoginWithoutRelayState() throws IOException, SettingsException, */ @Test public void testLoginWithExtraParameters() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = spy(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1410,8 +1373,8 @@ public void testLoginWithExtraParameters() throws IOException, SettingsException */ @Test public void testLoginStay() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1444,8 +1407,8 @@ public void testLoginStay() throws IOException, SettingsException, URISyntaxExce */ @Test public void testLoginSubject() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1493,8 +1456,8 @@ public void testLoginSubject() throws IOException, SettingsException, URISyntaxE */ @Test public void testLoginSignedFail() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1522,8 +1485,8 @@ public void testLoginSignedFail() throws IOException, SettingsException, URISynt */ @Test public void testLoginSigned() throws IOException, SettingsException, URISyntaxException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1556,8 +1519,8 @@ public void testLoginSigned() throws IOException, SettingsException, URISyntaxEx */ @Test public void testLogout() throws IOException, SettingsException, XMLEntityException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1585,8 +1548,8 @@ public void testLogout() throws IOException, SettingsException, XMLEntityExcepti */ @Test public void testLogoutWithExtraParameters() throws IOException, SettingsException, XMLEntityException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1615,8 +1578,8 @@ public void testLogoutWithExtraParameters() throws IOException, SettingsExceptio */ @Test public void testLogoutWithRelayState() throws IOException, SettingsException, XMLEntityException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1645,8 +1608,8 @@ public void testLogoutWithRelayState() throws IOException, SettingsException, XM */ @Test public void testLogoutWithoutRelayState() throws IOException, SettingsException, XMLEntityException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1677,8 +1640,8 @@ public void testLogoutWithoutRelayState() throws IOException, SettingsException, */ @Test public void testLogoutStay() throws IOException, SettingsException, XMLEntityException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1711,8 +1674,8 @@ public void testLogoutStay() throws IOException, SettingsException, XMLEntityExc */ @Test public void testLogoutSignedFail() throws IOException, SettingsException, XMLEntityException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -1740,8 +1703,8 @@ public void testLogoutSignedFail() throws IOException, SettingsException, XMLEnt */ @Test public void testLogoutSigned() throws IOException, SettingsException, XMLEntityException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); when(request.getScheme()).thenReturn("http"); when(request.getServerPort()).thenReturn(8080); when(request.getServerName()).thenReturn("localhost"); @@ -2092,8 +2055,8 @@ public void testBuildSignature() throws URISyntaxException, IOException, Setting */ @Test public void testGetLastAuthNRequest() throws IOException, SettingsException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); @@ -2118,8 +2081,8 @@ public void testGetLastAuthNRequest() throws IOException, SettingsException, Err */ @Test public void testGetLastLogoutRequestSent() throws IOException, SettingsException, XMLEntityException, Error { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); Auth auth = new Auth(settings, request, response); @@ -2141,11 +2104,11 @@ public void testGetLastLogoutRequestSent() throws IOException, SettingsException */ @Test public void testGetLastLogoutRequestReceived() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("/")); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("/"); String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded})); + when(request.getParameter(eq("SAMLRequest"))).thenReturn(samlRequestEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -2164,11 +2127,11 @@ public void testGetLastLogoutRequestReceived() throws Exception { */ @Test public void testGetLastSAMLResponse() throws Exception { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - when(request.getRequestURL()).thenReturn(new StringBuffer("/")); + HttpRequest request = mock(HttpRequest.class); + HttpResponse response = mock(HttpResponse.class); + when(request.getRequestURL()).thenReturn("/"); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); - when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + when(request.getParameter(eq("SAMLResponse"))).thenReturn(samlResponseEncoded); Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); Auth auth = new Auth(settings, request, response); @@ -2177,7 +2140,7 @@ public void testGetLastSAMLResponse() throws Exception { assertThat(samlResponseXML, containsString(" parameters = new HashMap(); - 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 parameters_2 = new HashMap(); - 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 parameters = new HashMap(); - - 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 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"); - } -}