1   package com.atlassian.security.auth.trustedapps;
2   
3   import com.mockobjects.servlet.MockHttpServletRequest;
4   
5   import java.util.ArrayList;
6   import java.util.List;
7   
8   import junit.framework.TestCase;
9   
10  public class TestDefaultRequestMatcher extends TestCase
11  {
12      public void testAllGood() throws Exception
13      {
14          final RequestValidator matcher = new DefaultRequestValidator(new IPMatcher()
15          {
16              public boolean match(final String ipAddress)
17              {
18                  assertEquals("123.12.0.89", ipAddress);
19                  return true;
20              }
21          }, new URLMatcher()
22          {
23              public boolean match(final String urlPath)
24              {
25                  assertEquals("/some/request/url", urlPath);
26                  return true;
27              }
28          });
29          final MockHttpServletRequest request = new MockHttpServletRequest();
30          request.setupGetRemoteAddr("123.12.0.89");
31          request.setupGetRequestURI("/some/request/url");
32          request.setupGetContextPath("");
33          request.setupAddHeader("X-Forwarded-For", null);
34          matcher.validate(request);
35      }
36  
37      public void testBadIpAddress() throws Exception
38      {
39          final RequestValidator matcher = new DefaultRequestValidator(new MockIPMatcher(false)
40          {
41              @Override
42              public boolean match(final String ipAddress)
43              {
44                  assertEquals("123.45.67.89", ipAddress);
45                  return super.match(ipAddress);
46              }
47          }, new MockURLMatcher(true));
48  
49          try
50          {
51              final MockHttpServletRequest request = new MockHttpServletRequest();
52              request.setupGetRemoteAddr("123.45.67.89");
53              matcher.validate(request);
54              fail("should have thrown invalid ip");
55          }
56          catch (final InvalidRemoteAddressException e)
57          {
58              // expected
59          }
60      }
61  
62      public void testIpAddressInXForwardedForChecked() throws Exception
63      {
64          final List<String> checkIps = new ArrayList<String>();
65          final RequestValidator matcher = new DefaultRequestValidator(new IPMatcher()
66          {
67              public boolean match(final String ipAddress)
68              {
69                  checkIps.add(ipAddress);
70                  return true;
71              }
72          }, new MockURLMatcher(true));
73  
74          final MockHttpServletRequest request = new MockHttpServletRequest();
75          request.setupGetRemoteAddr("123.45.67.89");
76          request.setupAddHeader("X-Forwarded-For", "192.68.0.123");
77          request.setupGetRequestURI("/some/request/url");
78          request.setupGetContextPath("");
79          matcher.validate(request);
80  
81          assertEquals(2, checkIps.size());
82          assertTrue(checkIps.contains("123.45.67.89"));
83          assertTrue(checkIps.contains("192.68.0.123"));
84      }
85  
86      public void testMultipleIpAddressesInXForwardedForChecked() throws Exception
87      {
88          final List<String> checkIps = new ArrayList<String>();
89          final RequestValidator matcher = new DefaultRequestValidator(new IPMatcher()
90          {
91              public boolean match(final String ipAddress)
92              {
93                  checkIps.add(ipAddress);
94                  return true;
95              }
96          }, new MockURLMatcher(true));
97  
98          final MockHttpServletRequest request = new MockHttpServletRequest();
99          request.setupGetRemoteAddr("123.45.67.89");
100         request.setupAddHeader("X-Forwarded-For", "192.68.0.123, 192.1.2.3, 192.4.5.6");
101         request.setupGetRequestURI("/some/request/url");
102         request.setupGetContextPath("");
103         matcher.validate(request);
104 
105         assertEquals(4, checkIps.size());
106         assertTrue(checkIps.contains("123.45.67.89"));
107         assertTrue(checkIps.contains("192.68.0.123"));
108         assertTrue(checkIps.contains("192.1.2.3"));
109         assertTrue(checkIps.contains("192.4.5.6"));
110     }
111 
112     public void testBadIpAddressInXForwardedFor() throws Exception
113     {
114         final RequestValidator matcher = new DefaultRequestValidator(new IPMatcher()
115         {
116             public boolean match(final String ipAddress)
117             {
118                 return "123.45.67.89".equals(ipAddress);
119             }
120         }, new MockURLMatcher(true));
121 
122         final MockHttpServletRequest request = new MockHttpServletRequest();
123         request.setupGetRemoteAddr("123.45.67.89");
124         request.setupGetRequestURI("/some/request/url");
125         request.setupGetContextPath("");
126         request.setupAddHeader("X-Forwarded-For", "192.68.0.123");
127         try
128         {
129             matcher.validate(request);
130             fail("Should have thrown illegal xforwarded ex");
131         }
132         catch (final InvalidXForwardedForAddressException e)
133         {
134             // expected
135         }
136     }
137 
138     public void testBadUrl() throws Exception
139     {
140         final RequestValidator matcher = new DefaultRequestValidator(new MockIPMatcher(true), new MockURLMatcher(false));
141         try
142         {
143             final MockHttpServletRequest request = new MockHttpServletRequest();
144             request.setupGetRemoteAddr("123.12.0.89");
145             request.setupGetRequestURI("/some/request/url");
146             request.setupGetContextPath("");
147             request.setupAddHeader("X-Forwarded-For", null);
148             matcher.validate(request);
149             fail("should have thrown invalid url");
150         }
151         catch (final InvalidRequestUrlException e)
152         {
153             // expected
154         }
155     }
156 
157     public void testContextPathRemoval() throws Exception
158     {
159         final RequestValidator matcher = new DefaultRequestValidator(new MockIPMatcher(true), new URLMatcher()
160         {
161             public boolean match(final String urlPath)
162             {
163                 assertEquals("/some/request/url", urlPath);
164                 return true;
165             }
166         });
167 
168         final MockHttpServletRequest request = new MockHttpServletRequest();
169         request.setupGetRemoteAddr("123.12.0.89");
170         request.setupGetRequestURI("/context/some/request/url");
171         request.setupGetContextPath("/context");
172         request.setupAddHeader("X-Forwarded-For", null);
173         matcher.validate(request);
174     }
175 
176     public void testNullIpMatcher() throws Exception
177     {
178         try
179         {
180             new DefaultRequestValidator(null, new MockURLMatcher(true));
181             fail("should have thrown NPE");
182         }
183         catch (final IllegalArgumentException e)
184         {
185             // expected
186         }
187     }
188 
189     public void testNullUrlMatcher() throws Exception
190     {
191         try
192         {
193             new DefaultRequestValidator(new MockIPMatcher(true), null);
194             fail("should have thrown NPE");
195         }
196         catch (final IllegalArgumentException e)
197         {
198             // expected
199         }
200     }
201 
202     static class MockIPMatcher implements IPMatcher
203     {
204         final boolean result;
205 
206         public MockIPMatcher(final boolean result)
207         {
208             this.result = result;
209         }
210 
211         public boolean match(final String ipAddress)
212         {
213             return result;
214         }
215     }
216 
217     static class MockURLMatcher implements URLMatcher
218     {
219         final boolean result;
220 
221         public MockURLMatcher(final boolean result)
222         {
223             this.result = result;
224         }
225 
226         public boolean match(final String urlPath)
227         {
228             return result;
229         }
230     }
231 
232 }