1   package com.atlassian.security.auth.trustedapps.filter;
2   
3   import com.atlassian.security.auth.trustedapps.TransportErrorMessage;
4   import com.atlassian.security.auth.trustedapps.TrustedApplicationUtils;
5   import com.atlassian.security.auth.trustedapps.filter.Authenticator.Result;
6   
7   import com.mockobjects.servlet.MockFilterChain;
8   import com.mockobjects.servlet.MockFilterConfig;
9   import com.mockobjects.servlet.MockHttpServletRequest;
10  import com.mockobjects.servlet.MockHttpServletResponse;
11  import com.mockobjects.servlet.MockHttpSession;
12  
13  import java.io.IOException;
14  import java.io.StringWriter;
15  import java.security.Principal;
16  
17  import javax.servlet.FilterChain;
18  import javax.servlet.ServletException;
19  import javax.servlet.ServletOutputStream;
20  import javax.servlet.ServletRequest;
21  import javax.servlet.ServletResponse;
22  import javax.servlet.http.HttpSession;
23  
24  import junit.framework.TestCase;
25  
26  public class TestTrustedApplicationsFilter extends TestCase
27  {
28      public void testAuthenticatorResultCtor() throws Exception
29      {
30          try
31          {
32              new Authenticator.Result(null, new TransportErrorMessage.UserUnknown("dodgy"), new Principal()
33              {
34                  public String getName()
35                  {
36                      return "dodgy";
37                  }
38              });
39              fail("null Status should have thrown IllegalArg");
40          }
41          catch (final IllegalArgumentException expected)
42          {
43              // yay
44          }
45      }
46  
47      @SuppressWarnings("deprecation")
48      public void testFilterLifecycle() throws Exception
49      {
50          final TrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
51          final MockFilterConfig config = new MockFilterConfig();
52  
53          assertNull(filter.getFilterConfig());
54  
55          filter.init(config);
56          assertSame(config, filter.getFilterConfig());
57  
58          filter.destroy();
59          assertNull(filter.getFilterConfig());
60  
61          filter.setFilterConfig(config);
62          assertSame(config, filter.getFilterConfig());
63  
64          filter.setFilterConfig(null); // should not clear if null passed
65          assertSame(config, filter.getFilterConfig());
66      }
67  
68      public void testGetPathInfoNullContext() throws Exception
69      {
70          final TrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
71          final MockRequest request = new MockRequest("/some/path")
72          {
73              @Override
74              public String getRequestURI()
75              {
76                  return getPathInfo();
77              }
78  
79              @Override
80              public String getContextPath()
81              {
82                  return null;
83              }
84          };
85          assertEquals("/some/path", filter.getPathInfo(request));
86      }
87  
88      public void testGetPathInfoWithContext() throws Exception
89      {
90          final TrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
91          final MockRequest request = new MockRequest("/some/context/some/path")
92          {
93              @Override
94              public String getRequestURI()
95              {
96                  return getPathInfo();
97              }
98  
99              @Override
100             public String getContextPath()
101             {
102                 return "/some/context";
103             }
104         };
105         assertEquals("/some/path", filter.getPathInfo(request));
106     }
107 
108     public void testCertificateServerCalledForTrustURL() throws Exception
109     {
110         final String certificate = "Certificate server called!";
111         final String contextPath = "/some/context";
112 
113         final MockTrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
114         filter.getMockCertificateServer().setCertificate(certificate);
115 
116         final MockHttpServletRequest request = new MockHttpServletRequest();
117         request.setupGetContextPath(contextPath);
118         request.setupGetRequestURI(contextPath + TrustedApplicationUtils.Constant.CERTIFICATE_URL_PATH);
119 
120         final FilterChain chain = new MockFilterChain();
121         final StringWriter writer = new StringWriter();
122         final ServletOutputStream stream = new ServletOutputStream()
123         {
124             @Override
125             public void write(final int b) throws IOException
126             {
127                 writer.write(b);
128             }
129         };
130 
131         final MockResponse response = new MockResponse()
132         {
133             @Override
134             public ServletOutputStream getOutputStream() throws IOException
135             {
136                 return stream;
137             }
138         };
139 
140         filter.doFilter(request, response, chain);
141         assertEquals(certificate, writer.toString());
142     }
143 
144     public void testAuthenticateCalledForNonCertURL() throws Exception
145     {
146         final MockTrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
147         filter.getMockAuthenticator().setResult(new Result(Result.Status.SUCCESS));
148 
149         final boolean[] invalidateCalled = new boolean[] { false };
150         final MockHttpSession session = new MockHttpSession()
151         {
152             @Override
153             public void invalidate()
154             {
155                 invalidateCalled[0] = true;
156             }
157         };
158 
159         final MockHttpServletRequest mockRequest = new MockHttpServletRequest();
160         mockRequest.setupGetContextPath("/some/context");
161         mockRequest.setupGetRequestURI("/some/context/some/url");
162         mockRequest.setSession(session);
163         mockRequest.setupGetAttribute(null);
164 
165         final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
166 
167         final FilterChain chain = new MockFilterChain()
168         {
169             @Override
170             public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException
171             {
172                 assertSame(mockRequest, request);
173                 assertSame(mockResponse, response);
174             }
175         };
176 
177         filter.doFilter(mockRequest, mockResponse, chain);
178         assertTrue(invalidateCalled[0]);
179     }
180 
181     public void testSessionInvalidateCalledForNonCertURLWhenExceptionThrown() throws Exception
182     {
183         final MockTrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
184         filter.getMockAuthenticator().setResult(new Result(Result.Status.SUCCESS));
185 
186         final boolean[] invalidateCalled = new boolean[] { false };
187         final MockHttpSession session = new MockHttpSession()
188         {
189             @Override
190             public void invalidate()
191             {
192                 invalidateCalled[0] = true;
193             }
194         };
195 
196         final MockHttpServletRequest mockRequest = new MockHttpServletRequest();
197         mockRequest.setupGetContextPath("/some/context");
198         mockRequest.setupGetRequestURI("/some/context/some/url");
199         mockRequest.setSession(session);
200         mockRequest.setupGetAttribute(null);
201 
202         final MockResponse mockResponse = new MockResponse();
203         final FilterChain chain = new MockFilterChain()
204         {
205             @Override
206             public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException
207             {
208                 assertSame(mockRequest, request);
209                 assertSame(mockResponse, response);
210                 throw new RuntimeException("poo");
211             }
212         };
213         try
214         {
215             filter.doFilter(mockRequest, mockResponse, chain);
216             fail("filter should not swallow exceptions");
217         }
218         catch (final RuntimeException expected)
219         {
220             // yay
221         }
222         assertTrue(invalidateCalled[0]);
223     }
224 
225     public void testSessionInvalidateNotCalledForNonCertURLWhenResultFailed() throws Exception
226     {
227         final TrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
228         final boolean[] invalidateCalled = new boolean[] { false };
229         final MockHttpSession session = new MockHttpSession()
230         {
231             @Override
232             public void invalidate()
233             {
234                 invalidateCalled[0] = true;
235             }
236         };
237 
238         final MockRequest mockRequest = new MockRequest("/some/context/some/url")
239         {
240             @Override
241             public String getRequestURI()
242             {
243                 return getPathInfo();
244             }
245 
246             @Override
247             public String getContextPath()
248             {
249                 return "/some/context";
250             }
251 
252             @Override
253             public HttpSession getSession()
254             {
255                 return session;
256             }
257         };
258 
259         mockRequest.setupGetAttribute(null);
260 
261         final MockResponse mockResponse = new MockResponse();
262         final FilterChain chain = new MockFilterChain()
263         {
264             @Override
265             public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException
266             {
267                 assertSame(mockRequest, request);
268                 assertSame(mockResponse, response);
269                 throw new RuntimeException("poo");
270             }
271         };
272         try
273         {
274             filter.doFilter(mockRequest, mockResponse, chain);
275             fail("filter should not swallow exceptions");
276         }
277         catch (final RuntimeException expected)
278         {
279             // yay
280         }
281         assertFalse(invalidateCalled[0]);
282     }
283 
284     public void testSessionInvalidateNotCalledForNonCertURLWhenResultError() throws Exception
285     {
286         final TrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
287         final boolean[] invalidateCalled = new boolean[] { false };
288         final MockHttpSession session = new MockHttpSession()
289         {
290             @Override
291             public void invalidate()
292             {
293                 invalidateCalled[0] = true;
294             }
295         };
296 
297         final MockRequest mockRequest = new MockRequest("/some/context/some/url")
298         {
299             @Override
300             public String getRequestURI()
301             {
302                 return getPathInfo();
303             }
304 
305             @Override
306             public String getContextPath()
307             {
308                 return "/some/context";
309             }
310 
311             @Override
312             public HttpSession getSession()
313             {
314                 return session;
315             }
316         };
317 
318         mockRequest.setupGetAttribute(null);
319 
320         final MockResponse mockResponse = new MockResponse();
321         final FilterChain chain = new MockFilterChain()
322         {
323             @Override
324             public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException
325             {
326                 assertSame(mockRequest, request);
327                 assertSame(mockResponse, response);
328                 throw new RuntimeException("poo");
329             }
330         };
331         try
332         {
333             filter.doFilter(mockRequest, mockResponse, chain);
334             fail("filter should not swallow exceptions");
335         }
336         catch (final RuntimeException expected)
337         {
338             // yay
339         }
340         assertFalse(invalidateCalled[0]);
341     }
342 
343     public void testSessionInvalidateNotCalledForNonCertURLWhenResultNoAttempt() throws Exception
344     {
345         final TrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
346         final boolean[] invalidateCalled = new boolean[] { false };
347         final MockHttpSession session = new MockHttpSession()
348         {
349             @Override
350             public void invalidate()
351             {
352                 invalidateCalled[0] = true;
353             }
354         };
355 
356         final MockRequest mockRequest = new MockRequest("/some/context/some/url")
357         {
358             @Override
359             public String getRequestURI()
360             {
361                 return getPathInfo();
362             }
363 
364             @Override
365             public String getContextPath()
366             {
367                 return "/some/context";
368             }
369 
370             @Override
371             public HttpSession getSession()
372             {
373                 return session;
374             }
375         };
376 
377         mockRequest.setupGetAttribute(null);
378 
379         final MockResponse mockResponse = new MockResponse();
380         final FilterChain chain = new MockFilterChain()
381         {
382             @Override
383             public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException
384             {
385                 assertSame(mockRequest, request);
386                 assertSame(mockResponse, response);
387                 throw new RuntimeException("poo");
388             }
389         };
390         try
391         {
392             filter.doFilter(mockRequest, mockResponse, chain);
393             fail("filter should not swallow exceptions");
394         }
395         catch (final RuntimeException expected)
396         {
397             // yay
398         }
399         assertFalse(invalidateCalled[0]);
400     }
401 
402     public void testAythenticateNotCalledWhenAlreadyLoggedIn() throws Exception
403     {
404         final TrustedApplicationsFilter filter = new MockTrustedApplicationsFilter();
405 
406         final MockRequest mockRequest = new MockRequest("/some/context/some/url")
407         {
408             @Override
409             public String getRequestURI()
410             {
411                 return getPathInfo();
412             }
413 
414             @Override
415             public String getContextPath()
416             {
417                 return "/some/context";
418             }
419         };
420 
421         mockRequest.setupGetAttribute("LOGGED_IN");
422 
423         final MockResponse mockResponse = new MockResponse();
424         final FilterChain chain = new MockFilterChain()
425         {
426             @Override
427             public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException
428             {
429                 assertSame(mockRequest, request);
430                 assertSame(mockResponse, response);
431                 throw new RuntimeException("poo");
432             }
433         };
434         try
435         {
436             filter.doFilter(mockRequest, mockResponse, chain);
437             fail("filter should not swallow exceptions");
438         }
439         catch (final RuntimeException expected)
440         {
441             // yay
442         }
443     }
444 
445     public void testResultStatusSuccess() throws Exception
446     {
447         assertEquals("success", Result.Status.SUCCESS.toString());
448     }
449 
450     public void testResultStatusFailed() throws Exception
451     {
452         assertEquals("failed", Result.Status.FAILED.toString());
453     }
454 
455     public void testResultStatusError() throws Exception
456     {
457         assertEquals("error", Result.Status.ERROR.toString());
458     }
459 
460     public void testResultStatusNoAttempt() throws Exception
461     {
462         assertEquals("no attempt", Result.Status.NO_ATTEMPT.toString());
463     }
464 }