Skip to content

Commit

Permalink
ContextTypeHelper: do account for the "Accept" header (per CAS specs)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacekkow committed Nov 24, 2023
1 parent eda11af commit 81877a6
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protected Response errorResponse(CASValidationException e) {
}

private Response prepare(Response.Status status, CASServiceResponse serviceResponse) {
MediaType responseMediaType = new ContentTypeHelper(request, restRequest, session.getContext().getUri()).selectResponseType();
MediaType responseMediaType = new ContentTypeHelper(session.getContext().getUri()).selectResponseType();
return ServiceResponseHelper.createResponse(status, responseMediaType, serviceResponse);
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
package org.keycloak.protocol.cas.utils;

import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.core.*;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.protocol.cas.CASLoginProtocol;
import org.keycloak.protocol.cas.representations.CASErrorCode;

public class ContentTypeHelper {
private final HttpRequest request;
private final Request restRequest;
private final UriInfo uriInfo;

public ContentTypeHelper(HttpRequest request, Request restRequest, UriInfo uriInfo) {
this.request = request;
this.restRequest = restRequest;
public ContentTypeHelper(UriInfo uriInfo) {
this.uriInfo = uriInfo;
}

public MediaType selectResponseType() {
String format = uriInfo.getQueryParameters().getFirst(CASLoginProtocol.FORMAT_PARAM);
if (format != null && !format.isEmpty()) {
//if parameter is set, it overrides all header values (see spec section 2.5.1)
request.getMutableHeaders().putSingle(HttpHeaders.ACCEPT, "application/" + format.toLowerCase());
}
try {
Variant variant = restRequest.selectVariant(Variant.mediaTypes(MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_JSON_TYPE).build());
return variant == null ? MediaType.APPLICATION_XML_TYPE : variant.getMediaType();
} catch (BadRequestException e) {
//the default Accept header set by java.net.HttpURLConnection is invalid (cf. RESTEASY-960)
return MediaType.APPLICATION_XML_TYPE;
if (format.equalsIgnoreCase("json")) {
return MediaType.APPLICATION_JSON_TYPE;
} else if (format.equalsIgnoreCase("xml")) {
return MediaType.APPLICATION_XML_TYPE;
} else {
throw new CASValidationException(CASErrorCode.INVALID_REQUEST, "Unsupported value of parameter " + CASLoginProtocol.FORMAT_PARAM, Response.Status.BAD_REQUEST);
}
}
return MediaType.APPLICATION_XML_TYPE;
}
}
32 changes: 7 additions & 25 deletions src/test/java/org/keycloak/protocol/cas/ContentTypeHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,15 @@
public class ContentTypeHelperTest {
@Test
public void test() throws Exception {
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/", null).selectResponseType());
assertEquals(MediaType.APPLICATION_JSON_TYPE, get("http://example.com/?format=json", null).selectResponseType());
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/?format=xml", null).selectResponseType());
assertEquals(MediaType.APPLICATION_JSON_TYPE, get("http://example.com/?format=JSON", null).selectResponseType());
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/?format=XML", null).selectResponseType());

assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/", MediaType.APPLICATION_XML).selectResponseType());
assertEquals(MediaType.APPLICATION_JSON_TYPE, get("http://example.com/?format=json", MediaType.APPLICATION_XML).selectResponseType());
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/?format=xml", MediaType.APPLICATION_XML).selectResponseType());

assertEquals(MediaType.APPLICATION_JSON_TYPE, get("http://example.com/", MediaType.APPLICATION_JSON).selectResponseType());
assertEquals(MediaType.APPLICATION_JSON_TYPE, get("http://example.com/?format=json", MediaType.APPLICATION_JSON).selectResponseType());
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/?format=xml", MediaType.APPLICATION_JSON).selectResponseType());

assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/", MediaType.TEXT_PLAIN).selectResponseType());
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2").selectResponseType());
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/").selectResponseType());
assertEquals(MediaType.APPLICATION_JSON_TYPE, get("http://example.com/?format=json").selectResponseType());
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/?format=xml").selectResponseType());
assertEquals(MediaType.APPLICATION_JSON_TYPE, get("http://example.com/?format=JSON").selectResponseType());
assertEquals(MediaType.APPLICATION_XML_TYPE, get("http://example.com/?format=XML").selectResponseType());
}

private ContentTypeHelper get(String uri, String acceptHeader) throws Exception {
private ContentTypeHelper get(String uri) throws Exception {
MockHttpRequest req = MockHttpRequest.get(uri);
MockHttpResponse res = new MockHttpResponse();
RequestImpl restReq = new RequestImpl(req, res);

if (acceptHeader != null) {
req = req.header(HttpHeaders.ACCEPT, acceptHeader);
}

return new ContentTypeHelper(req, restReq, req.getUri());
return new ContentTypeHelper(req.getUri());
}
}

0 comments on commit 81877a6

Please sign in to comment.