1 package it.com.atlassian.rest.cors;
2
3 import com.atlassian.rest.jersey.client.WebResourceFactory;
4 import com.google.common.collect.ImmutableMap;
5 import org.junit.Test;
6
7 import java.io.BufferedOutputStream;
8 import java.io.BufferedReader;
9 import java.io.IOException;
10 import java.io.InputStreamReader;
11 import java.io.PrintWriter;
12 import java.net.Socket;
13 import java.net.URL;
14 import java.util.Map;
15
16 import static com.atlassian.plugins.rest.common.security.CorsHeaders.*;
17 import static com.atlassian.plugins.rest.cors.SimpleCorsDefaults.*;
18 import static com.google.common.collect.Maps.newHashMap;
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNull;
21
22 public class CorsCheckTest {
23 @Test
24 public void testSimpleGetWithOrigin() throws IOException {
25 Map<String, String> headers = makeRequest("GET", ImmutableMap.<String, String>of(ORIGIN.value(), CREDENTIALS));
26 assertEquals(CREDENTIALS, headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
27 assertEquals("true", headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
28 assertEquals("X-Response-Header", headers.get(ACCESS_CONTROL_EXPOSE_HEADERS.value()));
29 }
30
31 @Test
32 public void testSimpleGetWithNoCredentialsOrigin() throws IOException {
33 Map<String, String> headers = makeRequest("GET", ImmutableMap.<String, String>of(ORIGIN.value(), NO_CREDENTIALS));
34 assertEquals(NO_CREDENTIALS, headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
35 assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
36 assertEquals("X-Response-Header", headers.get(ACCESS_CONTROL_EXPOSE_HEADERS.value()));
37 }
38
39 @Test
40 public void testPreflight() throws IOException {
41 Map<String, String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
42 ORIGIN.value(), CREDENTIALS,
43 ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
44 ));
45 assertEquals(CREDENTIALS, headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
46 assertEquals("true", headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
47 assertEquals(String.valueOf(60 * 60), headers.get(ACCESS_CONTROL_MAX_AGE.value()));
48 assertEquals("PUT", headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
49 assertEquals("X-Custom-Header", headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
50 }
51
52 @Test
53 public void testPreflightWithWrongHeaders() throws Exception {
54 Map<String, String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
55 ORIGIN.value(), NO_CREDENTIALS,
56 ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT",
57 ACCESS_CONTROL_REQUEST_HEADERS.value(), "X-Unexpected-Header"
58 ));
59 assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
60 assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
61 assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
62 assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
63 assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
64 }
65
66 @Test
67 public void testPreflightWithWrongOrigin() throws IOException {
68 Map<String, String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
69 ORIGIN.value(), "http://www.invalid.com",
70 ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
71 ));
72 assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
73 assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
74 assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
75 assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
76 assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
77 }
78
79 @Test
80 public void testPreflightWithWrongMethod() throws IOException {
81 Map<String, String> headers = makeRequest(
82 WebResourceFactory.anonymous().path("cors").path("none").getURI().toString(),
83 "OPTIONS", ImmutableMap.<String, String>of(
84 ORIGIN.value(), CREDENTIALS,
85 ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
86 ));
87 assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
88 assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
89 assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
90 assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
91 assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
92 }
93
94 private Map<String, String> makeRequest(String method, Map<String, String> headers) throws IOException {
95 return makeRequest(WebResourceFactory.anonymous().path("cors").getURI().toString(), method, headers);
96 }
97
98 private Map<String, String> makeRequest(String uri, String method, Map<String, String> headers) throws IOException {
99 URL url = new URL(uri);
100 Socket socket = new Socket(url.getHost(), url.getPort());
101
102 PrintWriter writer = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
103 writer.write(method + " " + url.getPath() + " HTTP/1.1\r\n");
104 for (String key : headers.keySet()) {
105 writer.write(key + ": " + headers.get(key) + "\r\n");
106 }
107 writer.write("Accept: text/html\r\n");
108 writer.write("User-Agent: Me\r\n");
109 writer.write("Connection: keep-alive\r\n");
110 writer.write("Host: 127.0.0.1:" + url.getPort() + " \r\n");
111 writer.write("\n\n");
112 writer.flush();
113
114 Map<String, String> responseHeaders = newHashMap();
115 BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
116 String line;
117 while ((line = reader.readLine()) != null) {
118 if ("".equals(line)) {
119 socket.close();
120 break;
121 }
122 int pos = line.indexOf(':');
123 if (pos > -1) {
124 String key = line.substring(0, pos).trim();
125 String value = line.substring(pos + 1).trim();
126 responseHeaders.put(key, value);
127 }
128 }
129
130 return responseHeaders;
131 }
132 }