commit | author | age
|
513246
|
1 |
package org.keycloak.protocol.cas; |
MP |
2 |
|
bce810
|
3 |
import com.jayway.jsonpath.JsonPath; |
MP |
4 |
import com.sun.xml.bind.v2.util.FatalAdapter; |
513246
|
5 |
import org.junit.Test; |
352436
|
6 |
import org.keycloak.protocol.cas.representations.CASErrorCode; |
8a5518
|
7 |
import org.keycloak.protocol.cas.representations.CASServiceResponse; |
513246
|
8 |
import org.keycloak.protocol.cas.utils.ServiceResponseHelper; |
MP |
9 |
import org.keycloak.protocol.cas.utils.ServiceResponseMarshaller; |
bce810
|
10 |
import org.w3c.dom.Document; |
MP |
11 |
import org.w3c.dom.Node; |
|
12 |
import org.xml.sax.helpers.DefaultHandler; |
|
13 |
import org.xmlunit.xpath.JAXPXPathEngine; |
|
14 |
import org.xmlunit.xpath.XPathEngine; |
513246
|
15 |
|
bce810
|
16 |
import javax.xml.XMLConstants; |
MP |
17 |
import javax.xml.parsers.DocumentBuilder; |
|
18 |
import javax.xml.parsers.DocumentBuilderFactory; |
|
19 |
import javax.xml.validation.Schema; |
|
20 |
import javax.xml.validation.SchemaFactory; |
|
21 |
import java.io.ByteArrayInputStream; |
|
22 |
import java.nio.charset.StandardCharsets; |
|
23 |
import java.util.*; |
513246
|
24 |
|
MP |
25 |
import static org.junit.Assert.assertEquals; |
|
26 |
|
|
27 |
public class ServiceResponseTest { |
bce810
|
28 |
private final XPathEngine xpath = new JAXPXPathEngine(); |
MP |
29 |
|
|
30 |
public ServiceResponseTest() { |
|
31 |
xpath.setNamespaceContext(Collections.singletonMap("cas", "http://www.yale.edu/tp/cas")); |
|
32 |
} |
513246
|
33 |
|
MP |
34 |
@Test |
|
35 |
public void testSuccessResponse() throws Exception { |
|
36 |
Map<String, Object> attributes = new HashMap<>(); |
|
37 |
attributes.put("list", Arrays.asList("a", "b")); |
|
38 |
attributes.put("int", 123); |
|
39 |
attributes.put("string", "abc"); |
|
40 |
|
bce810
|
41 |
List<String> proxies = Arrays.asList("https://proxy1/pgtUrl", "https://proxy2/pgtUrl"); |
8a5518
|
42 |
CASServiceResponse response = ServiceResponseHelper.createSuccess("username", attributes, "PGTIOU-test", |
bce810
|
43 |
proxies); |
513246
|
44 |
|
bce810
|
45 |
// Build and validate JSON response |
MP |
46 |
|
|
47 |
String json = ServiceResponseMarshaller.marshalJson(response); |
|
48 |
assertEquals("username", JsonPath.read(json, "$.serviceResponse.authenticationSuccess.user")); |
|
49 |
assertEquals(attributes.get("list"), JsonPath.read(json, "$.serviceResponse.authenticationSuccess.attributes.list")); |
|
50 |
assertEquals(attributes.get("int"), JsonPath.read(json, "$.serviceResponse.authenticationSuccess.attributes.int")); |
|
51 |
assertEquals(attributes.get("string"), JsonPath.read(json, "$.serviceResponse.authenticationSuccess.attributes.string")); |
|
52 |
assertEquals("PGTIOU-test", JsonPath.read(json, "$.serviceResponse.authenticationSuccess.proxyGrantingTicket")); |
|
53 |
assertEquals(proxies, JsonPath.read(json, "$.serviceResponse.authenticationSuccess.proxies")); |
|
54 |
|
|
55 |
// Build and validate XML response |
|
56 |
|
|
57 |
String xml = ServiceResponseMarshaller.marshalXml(response); |
|
58 |
Document doc = parseAndValidate(xml); |
|
59 |
assertEquals("username", xpath.evaluate("/cas:serviceResponse/cas:authenticationSuccess/cas:user", doc)); |
|
60 |
int idx = 0; |
|
61 |
for (Node node : xpath.selectNodes("/cas:serviceResponse/cas:authenticationSuccess/cas:attributes/cas:list", doc)) { |
|
62 |
assertEquals(((List)attributes.get("list")).get(idx), node.getTextContent()); |
|
63 |
idx++; |
|
64 |
} |
|
65 |
assertEquals(((List)attributes.get("list")).size(), idx); |
|
66 |
assertEquals(attributes.get("int").toString(), xpath.evaluate("/cas:serviceResponse/cas:authenticationSuccess/cas:attributes/cas:int", doc)); |
|
67 |
assertEquals(attributes.get("string").toString(), xpath.evaluate("/cas:serviceResponse/cas:authenticationSuccess/cas:attributes/cas:string", doc)); |
|
68 |
|
|
69 |
assertEquals("PGTIOU-test", xpath.evaluate("/cas:serviceResponse/cas:authenticationSuccess/cas:proxyGrantingTicket", doc)); |
|
70 |
idx = 0; |
|
71 |
for (Node node : xpath.selectNodes("/cas:serviceResponse/cas:authenticationSuccess/cas:proxies/cas:proxy", doc)) { |
|
72 |
assertEquals(proxies.get(idx), node.getTextContent()); |
|
73 |
idx++; |
|
74 |
} |
|
75 |
assertEquals(proxies.size(), idx); |
513246
|
76 |
} |
MP |
77 |
|
|
78 |
@Test |
|
79 |
public void testErrorResponse() throws Exception { |
8a5518
|
80 |
CASServiceResponse response = ServiceResponseHelper.createFailure(CASErrorCode.INVALID_REQUEST, "Error description"); |
513246
|
81 |
|
bce810
|
82 |
// Build and validate JSON response |
MP |
83 |
|
|
84 |
String json = ServiceResponseMarshaller.marshalJson(response); |
|
85 |
assertEquals(CASErrorCode.INVALID_REQUEST.name(), JsonPath.read(json, "$.serviceResponse.authenticationFailure.code")); |
|
86 |
assertEquals("Error description", JsonPath.read(json, "$.serviceResponse.authenticationFailure.description")); |
|
87 |
|
|
88 |
// Build and validate XML response |
|
89 |
|
|
90 |
String xml = ServiceResponseMarshaller.marshalXml(response); |
|
91 |
Document doc = parseAndValidate(xml); |
|
92 |
assertEquals(CASErrorCode.INVALID_REQUEST.name(), xpath.evaluate("/cas:serviceResponse/cas:authenticationFailure/@code", doc)); |
|
93 |
assertEquals("Error description", xpath.evaluate("/cas:serviceResponse/cas:authenticationFailure", doc)); |
|
94 |
} |
|
95 |
|
|
96 |
/** |
|
97 |
* Parse XML document and validate against CAS schema |
|
98 |
*/ |
|
99 |
private Document parseAndValidate(String xml) throws Exception { |
|
100 |
Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) |
|
101 |
.newSchema(getClass().getResource("cas-response-schema.xsd")); |
|
102 |
|
|
103 |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
|
104 |
factory.setSchema(schema); |
|
105 |
factory.setNamespaceAware(true); |
|
106 |
DocumentBuilder builder = factory.newDocumentBuilder(); |
|
107 |
builder.setErrorHandler(new FatalAdapter(new DefaultHandler())); |
|
108 |
return builder.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))); |
513246
|
109 |
} |
MP |
110 |
} |