1   package com.atlassian.seraph.cookie;
2   
3   import junit.framework.TestCase;
4   
5   import java.io.IOException;
6   import java.io.PrintWriter;
7   import java.util.HashMap;
8   import java.util.Locale;
9   import java.util.Map;
10  import javax.servlet.ServletOutputStream;
11  import javax.servlet.http.Cookie;
12  import javax.servlet.http.HttpServletResponse;
13  
14  /**
15   */
16  public class TestHttpOnlyCookieKit extends TestCase
17  {
18      private CapturingHttpServletResponse response;
19  
20      protected void setUp() throws Exception
21      {
22          super.setUp();
23          response = new CapturingHttpServletResponse();
24      }
25  
26      public void testVersions()
27      {
28  
29          Cookie cookieV0 = new Cookie("cookiev0", "value0");
30          cookieV0.setMaxAge(10);
31          cookieV0.setComment("comment");
32          cookieV0.setDomain("domain");
33          cookieV0.setPath("path");
34  
35          HttpOnlyCookieKit.setCookie(response, cookieV0);
36          checkCookieValue(response, "cookiev0", "value0");
37  
38          String header = response.headers.get("Set-Cookie");
39          assertTrue(header.indexOf("Version=") == -1);
40          assertTrue(header.indexOf("Max-Age=") == -1);
41          assertTrue(header.indexOf("Comment=") == -1);
42          assertTrue(header.indexOf("Expires=") != -1);
43          assertTrue(header.indexOf("Domain=domain") != -1);
44          assertTrue(header.indexOf("Path=path") != -1);
45          assertTrue(header.indexOf("HttpOnly") != -1);
46  
47          Cookie cookieV1 = new Cookie("cookiev1", "value1");
48          cookieV1.setVersion(1);
49          cookieV1.setMaxAge(10);
50          cookieV1.setComment("comment");
51          cookieV1.setDomain("domain");
52          cookieV1.setPath("path");
53  
54          HttpOnlyCookieKit.setCookie(response, cookieV1);
55          checkCookieValue(response, "cookiev1", "value1");
56          header = response.headers.get("Set-Cookie");
57  
58          assertTrue(header.indexOf("Expires=") == -1);
59          assertTrue(header.indexOf("Max-Age=10") != -1);
60          assertTrue(header.indexOf("Comment=comment") != -1);
61          assertTrue(header.indexOf("Domain=domain") != -1);
62          assertTrue(header.indexOf("Path=path") != -1);
63          assertTrue(header.indexOf("HttpOnly") != -1);
64  
65      }
66  
67      public void testValueEscaping()
68      {
69          // encodes values with bad characters
70          Cookie cookie2 = new Cookie("cookie2", "val;ue2");
71          cookie2.setPath("Path,WithCommas");
72          cookie2.setDomain("Domain;,WithCommas");
73  
74          HttpOnlyCookieKit.setCookie(response, cookie2);
75          checkCookieValue(response, "cookie2", "\"val;ue2\"");
76          checkCookiePath(response,"\"Path,WithCommas\"");
77          checkCookieDomain(response,"\"domain;,withcommas\"");
78  
79          Cookie cookie3 = new Cookie("cookie3", "val,ue3");
80          HttpOnlyCookieKit.setCookie(response, cookie3);
81          checkCookieValue(response, "cookie3", "\"val,ue3\"");
82      }
83  
84  
85      public void testMissingParts()
86      {
87          Cookie cookieV1 = new Cookie("cookiev1", "value1");
88          cookieV1.setVersion(1);
89          cookieV1.setMaxAge(10);
90          cookieV1.setSecure(false);
91  
92          HttpOnlyCookieKit.setCookie(response, cookieV1);
93          String header = response.headers.get("Set-Cookie");
94  
95          assertTrue(header.indexOf("Comment") == -1);
96          assertTrue(header.indexOf("Domain") == -1);
97          assertTrue(header.indexOf("Path") == -1);
98          assertTrue(header.indexOf("Secure") == -1);
99  
100         cookieV1.setDomain("domain");
101         cookieV1.setPath("path");
102         cookieV1.setComment("comment");
103         cookieV1.setSecure(true);
104 
105         HttpOnlyCookieKit.setCookie(response, cookieV1);
106         header = response.headers.get("Set-Cookie");
107         
108         assertTrue(header.indexOf("Comment") != -1);
109         assertTrue(header.indexOf("Domain") != -1);
110         assertTrue(header.indexOf("Path") != -1);
111         assertTrue(header.indexOf("Secure") != -1);
112     }
113 
114     public void testMaxAgeIsnegative()
115     {
116         Cookie cookieV0 = new Cookie("cookiev1", "value1");
117         cookieV0.setVersion(0);
118         cookieV0.setMaxAge(-1);
119 
120         HttpOnlyCookieKit.setCookie(response, cookieV0);
121         String header = response.headers.get("Set-Cookie");
122 
123         assertTrue(header.indexOf("Expires") == -1);
124 
125         // v1
126         
127         Cookie cookieV1 = new Cookie("cookiev1", "value1");
128         cookieV1.setVersion(1);
129         cookieV1.setMaxAge(-1);
130 
131         HttpOnlyCookieKit.setCookie(response, cookieV1);
132         header = response.headers.get("Set-Cookie");
133 
134         assertTrue(header.indexOf("Max Age") == -1);
135     }
136 
137     private void checkCookieValue(final CapturingHttpServletResponse response, final String name, final String value)
138     {
139         String header = response.headers.get("Set-Cookie");
140         assertNotNull(header);
141         final String lookingFor = name + "=" + value;
142         assertTrue(expectationMsg(header, lookingFor), header.indexOf(lookingFor) == 0);
143     }
144 
145     private void checkCookiePath(final CapturingHttpServletResponse response, final String value)
146     {
147         String header = response.headers.get("Set-Cookie");
148         assertNotNull(header);
149         final String lookingFor = "; Path" + "=" + value;
150         assertTrue(expectationMsg(header, lookingFor), header.indexOf(lookingFor) != -1);
151     }
152 
153     private void checkCookieDomain(final CapturingHttpServletResponse response, final String value)
154     {
155         String header = response.headers.get("Set-Cookie");
156         assertNotNull(header);
157         final String lookingFor = "; Domain" + "=" + value;
158         assertTrue(expectationMsg(header, lookingFor), header.indexOf(lookingFor) != -1);
159     }
160 
161     private String expectationMsg(final String header, final String lookingFor)
162     {
163         return "Got header :'" + header + "' \n\tlooking for ' " + lookingFor + "'\n";
164     }
165 
166     class CapturingHttpServletResponse implements HttpServletResponse
167     {
168 
169         private Map<String, String> headers = new HashMap<String, String>();
170 
171         public void addHeader(final String name, final String value)
172         {
173             headers.put(name, value);
174         }
175 
176         public void addCookie(final Cookie cookie)
177         {
178         }
179 
180         public boolean containsHeader(final String name)
181         {
182             return false;
183         }
184 
185         public String encodeURL(final String url)
186         {
187             return null;
188         }
189 
190         public String encodeRedirectURL(final String url)
191         {
192             return null;
193         }
194 
195         public String encodeUrl(final String url)
196         {
197             return null;
198         }
199 
200         public String encodeRedirectUrl(final String url)
201         {
202             return null;
203         }
204 
205         public void sendError(final int sc, final String msg) throws IOException
206         {
207         }
208 
209         public void sendError(final int sc) throws IOException
210         {
211         }
212 
213         public void sendRedirect(final String location) throws IOException
214         {
215         }
216 
217         public void setDateHeader(final String name, final long date)
218         {
219         }
220 
221         public void addDateHeader(final String name, final long date)
222         {
223         }
224 
225         public void setHeader(final String name, final String value)
226         {
227         }
228 
229         public void setIntHeader(final String name, final int value)
230         {
231         }
232 
233         public void addIntHeader(final String name, final int value)
234         {
235         }
236 
237         public void setStatus(final int sc)
238         {
239         }
240 
241         public void setStatus(final int sc, final String sm)
242         {
243         }
244 
245         public String getCharacterEncoding()
246         {
247             return null;
248         }
249 
250         public ServletOutputStream getOutputStream() throws IOException
251         {
252             return null;
253         }
254 
255         public PrintWriter getWriter() throws IOException
256         {
257             return null;
258         }
259 
260         public void setContentLength(final int len)
261         {
262         }
263 
264         public void setContentType(final String type)
265         {
266         }
267 
268         public void setBufferSize(final int size)
269         {
270         }
271 
272         public int getBufferSize()
273         {
274             return 0;
275         }
276 
277         public void flushBuffer() throws IOException
278         {
279         }
280 
281         public void resetBuffer()
282         {
283         }
284 
285         public boolean isCommitted()
286         {
287             return false;
288         }
289 
290         public void reset()
291         {
292         }
293 
294         public void setLocale(final Locale loc)
295         {
296         }
297 
298         public Locale getLocale()
299         {
300             return null;
301         }
302     }
303 }