View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.web.servlet;
20  
21  import junit.framework.TestCase;
22  import org.easymock.IArgumentMatcher;
23  import org.junit.Before;
24  import org.junit.Test;
25  
26  import javax.servlet.http.HttpServletRequest;
27  import javax.servlet.http.HttpServletResponse;
28  import java.util.Locale;
29  
30  import static org.easymock.EasyMock.*;
31  
32  /**
33   * TODO - Class JavaDoc
34   *
35   * @since Apr 22, 2010 9:40:47 PM
36   */
37  public class SimpleCookieTest extends TestCase {
38  
39      private SimpleCookie cookie;
40  
41      private HttpServletRequest mockRequest;
42      private HttpServletResponse mockResponse;
43  
44      @Before
45      public void setUp() throws Exception {
46          this.mockRequest = createMock(HttpServletRequest.class);
47          this.mockResponse = createMock(HttpServletResponse.class);
48          this.cookie = new SimpleCookie("test");
49      }
50  
51      @Test
52      //Verifies fix for JSEC-94
53      public void testRemoveValue() throws Exception {
54  
55          //verify that the cookie header starts with what we want
56          //we can't verify the exact date format string that is appended, so we resort to just
57          //simple 'startsWith' matching, which is good enough:
58          String name = "test";
59          String value = "deleteMe";
60          String path = "/somepath";
61  
62          String headerValue = this.cookie.buildHeaderValue(name, value, null, null, path,
63                  0, SimpleCookie.DEFAULT_VERSION, false, false, null);
64  
65          String expectedStart = new StringBuilder()
66                  .append(name).append(SimpleCookie.NAME_VALUE_DELIMITER).append(value)
67                  .append(SimpleCookie.ATTRIBUTE_DELIMITER)
68                  .append(SimpleCookie.PATH_ATTRIBUTE_NAME).append(SimpleCookie.NAME_VALUE_DELIMITER).append(path)
69                  .toString();
70  
71          assertTrue(headerValue.startsWith(expectedStart));
72  
73          expect(mockRequest.getContextPath()).andReturn(path).times(1);
74          mockResponse.addHeader(eq(SimpleCookie.COOKIE_HEADER_NAME), isA(String.class)); //can't calculate the date format in the test
75          replay(mockRequest);
76          replay(mockResponse);
77  
78          this.cookie.removeFrom(mockRequest, mockResponse);
79  
80          verify(mockRequest);
81          verify(mockResponse);
82      }
83  
84      private void testRootContextPath(String contextPath) {
85          this.cookie.setValue("blah");
86  
87          String expectedCookieValue = new StringBuilder()
88                  .append("test").append(SimpleCookie.NAME_VALUE_DELIMITER).append("blah")
89                  .append(SimpleCookie.ATTRIBUTE_DELIMITER)
90                  .append(SimpleCookie.PATH_ATTRIBUTE_NAME).append(SimpleCookie.NAME_VALUE_DELIMITER).append(Cookie.ROOT_PATH)
91                  .append(SimpleCookie.ATTRIBUTE_DELIMITER)
92                  .append(SimpleCookie.HTTP_ONLY_ATTRIBUTE_NAME)
93                  .append(SimpleCookie.ATTRIBUTE_DELIMITER)
94                  .append(SimpleCookie.SAME_SITE_ATTRIBUTE_NAME).append(SimpleCookie.NAME_VALUE_DELIMITER)
95                      .append(Cookie.SameSiteOptions.LAX.toString().toLowerCase(Locale.ENGLISH))
96                  .toString();
97  
98          expect(mockRequest.getContextPath()).andReturn(contextPath);
99          mockResponse.addHeader(SimpleCookie.COOKIE_HEADER_NAME, expectedCookieValue);
100 
101         replay(mockRequest);
102         replay(mockResponse);
103 
104         this.cookie.saveTo(mockRequest, mockResponse);
105 
106         verify(mockRequest);
107         verify(mockResponse);
108     }
109 
110     @Test
111     /** Verifies fix for <a href="http://issues.apache.org/jira/browse/JSEC-34">JSEC-34</a> (1 of 2)*/
112     public void testEmptyContextPath() throws Exception {
113         testRootContextPath("");
114     }
115 
116 
117     @Test
118     /** Verifies fix for <a href="http://issues.apache.org/jira/browse/JSEC-34">JSEC-34</a> (2 of 2)*/
119     public void testNullContextPath() throws Exception {
120         testRootContextPath(null);
121     }
122 
123     @Test
124     public void testReadValueInvalidPath() throws Exception {
125         expect(mockRequest.getRequestURI()).andStubReturn("/foo/index.jsp");
126         expect(mockRequest.getCookies()).andStubReturn(new javax.servlet.http.Cookie[] { new javax.servlet.http.Cookie(this.cookie.getName(), "value") });
127         replay(mockRequest);
128         replay(mockResponse);
129 
130         this.cookie.setPath("/bar/index.jsp");
131         assertEquals(null, this.cookie.readValue(mockRequest, mockResponse));
132     }
133 
134     @Test
135     public void testReadValuePrefixPath() throws Exception {
136         expect(mockRequest.getRequestURI()).andStubReturn("/bar/index.jsp");
137         expect(mockRequest.getCookies()).andStubReturn(new javax.servlet.http.Cookie[] { new javax.servlet.http.Cookie(this.cookie.getName(), "value") });
138         replay(mockRequest);
139         replay(mockResponse);
140 
141         this.cookie.setPath("/bar");
142         assertEquals("value", this.cookie.readValue(mockRequest, mockResponse));
143     }
144 
145     @Test
146     public void testReadValueInvalidPrefixPath() throws Exception {
147         expect(mockRequest.getRequestURI()).andStubReturn("/foobar/index.jsp");
148         expect(mockRequest.getCookies()).andStubReturn(new javax.servlet.http.Cookie[] { new javax.servlet.http.Cookie(this.cookie.getName(), "value") });
149         replay(mockRequest);
150         replay(mockResponse);
151 
152         this.cookie.setPath("/foo");
153         assertEquals(null, this.cookie.readValue(mockRequest, mockResponse));
154     }
155 
156     private static <T extends javax.servlet.http.Cookie> T eqCookie(final T in) {
157         reportMatcher(new IArgumentMatcher() {
158             public boolean matches(Object o) {
159                 javax.servlet.http.Cookie c = (javax.servlet.http.Cookie) o;
160                 return c.getName().equals(in.getName()) &&
161                         c.getValue().equals(in.getValue()) &&
162                         c.getPath().equals(in.getPath()) &&
163                         c.getMaxAge() == in.getMaxAge() &&
164                         c.getSecure() == in.getSecure() &&
165                         c.getValue().equals(in.getValue());
166             }
167 
168             public void appendTo(StringBuffer sb) {
169                 sb.append("eqCookie(");
170                 sb.append(in.getClass().getName());
171                 sb.append(")");
172 
173             }
174         });
175         return null;
176     }
177 
178 }