2 * The Shibboleth License, Version 1.
4 * University Corporation for Advanced Internet Development, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution, if any, must include
17 * the following acknowledgment: "This product includes software developed by
18 * the University Corporation for Advanced Internet Development
19 * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
20 * may appear in the software itself, if and wherever such third-party
21 * acknowledgments normally appear.
23 * Neither the name of Shibboleth nor the names of its contributors, nor
24 * Internet2, nor the University Corporation for Advanced Internet Development,
25 * Inc., nor UCAID may be used to endorse or promote products derived from this
26 * software without specific prior written permission. For written permission,
27 * please contact shibboleth@shibboleth.org
29 * Products derived from this software may not be called Shibboleth, Internet2,
30 * UCAID, or the University Corporation for Advanced Internet Development, nor
31 * may Shibboleth appear in their name, without prior written permission of the
32 * University Corporation for Advanced Internet Development.
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36 * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
38 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
39 * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
40 * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
41 * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
42 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 package edu.internet2.middleware.shibboleth.aa.arp;
52 import java.io.FileInputStream;
53 import java.io.InputStream;
54 import java.net.MalformedURLException;
56 import java.net.URISyntaxException;
58 import java.util.Properties;
60 import junit.framework.TestCase;
62 import org.apache.log4j.BasicConfigurator;
63 import org.apache.xerces.parsers.DOMParser;
64 import org.xml.sax.InputSource;
67 * Validation suite for <code>Arp</code> processing.
69 * @ author Walter Hoehn(wassa@columbia.edu)
72 public class ArpTests extends TestCase {
74 public ArpTests(String name) {
76 BasicConfigurator.configure();
79 public static void main(String[] args) {
80 junit.textui.TestRunner.run(ArpTests.class);
81 BasicConfigurator.configure();
84 public void testArpMarshalling() {
86 //Test ARP description
88 InputStream inStream = new FileInputStream("test/arp1.xml");
89 DOMParser parser = new DOMParser();
90 parser.parse(new InputSource(inStream));
92 arp1.marshall(parser.getDocument().getDocumentElement());
94 "ARP Description not marshalled properly",
95 arp1.getDescription(),
96 "Simplest possible ARP.");
98 //Test Rule description
100 "ARP Rule Description not marshalled properly",
101 arp1.getAllRules()[0].getDescription(),
102 "Example Rule Description.");
103 } catch (Exception e) {
104 fail("Failed to marshall ARP.");
107 //Test case where ARP description does not exist
109 InputStream inStream = new FileInputStream("test/arp2.xml");
110 DOMParser parser = new DOMParser();
111 parser.parse(new InputSource(inStream));
112 Arp arp2 = new Arp();
113 arp2.marshall(parser.getDocument().getDocumentElement());
114 assertNull("ARP Description not marshalled properly", arp2.getDescription());
116 //Test case where ARP Rule description does not exist
118 "ARP Rule Description not marshalled properly",
119 arp2.getAllRules()[0].getDescription());
120 } catch (Exception e) {
121 fail("Failed to marshall ARP.");
126 public void testMatchingFunctions() {
131 * Test Arp Engine function retrieval
134 //Lookup a function that doesn't exist
135 MatchFunction noFunction =
136 ArpEngine.lookupMatchFunction(new URI("urn:mace:shibboleth:arp:matchFunction:dummy"));
137 assertNull("ArpEngine did not return null on dummy function.", noFunction);
139 //Lookup some real functions
140 MatchFunction exactSharFunction =
141 ArpEngine.lookupMatchFunction(new URI("urn:mace:shibboleth:arp:matchFunction:exactShar"));
142 assertNotNull("ArpEngine did not properly load the Exact SHAR function.", exactSharFunction);
143 MatchFunction resourceTreeFunction =
144 ArpEngine.lookupMatchFunction(new URI("urn:mace:shibboleth:arp:matchFunction:resourceTree"));
146 "ArpEngine did not properly load the Resource Tree SHAR function.",
147 resourceTreeFunction);
148 MatchFunction regexFunction =
149 ArpEngine.lookupMatchFunction(new URI("urn:mace:shibboleth:arp:matchFunction:regexMatch"));
150 assertNotNull("ArpEngine did not properly load the Regex function.", regexFunction);
153 * Test the Exact SHAR function (requester)
157 "Exact SHAR function: false negative",
158 exactSharFunction.match("shar.example.edu", "shar.example.edu"));
160 "Exact SHAR function: false negative",
161 !exactSharFunction.match("shar.example.edu", "www.example.edu"));
163 "Exact SHAR function: false negative",
164 !exactSharFunction.match("example.edu", "shar.example.edu"));
166 //Make sure we properly handle bad input
168 exactSharFunction.match(null, null);
169 fail("Exact SHAR function seems to take improper input without throwing an exception.");
170 } catch (ArpException ie) {
171 //This is supposed to fail
175 * Test the Resource Tree function (resource)
178 URL requestURL1 = new URL("http://www.example.edu/test/");
179 URL requestURL2 = new URL("http://www.example.edu/test/index.html");
180 URL requestURL3 = new URL("http://www.example.edu/test2/index.html");
181 URL requestURL4 = new URL("http://www.example.edu/test2/index.html?test1=test1");
184 "Resource Tree function: false negative",
185 resourceTreeFunction.match("http://www.example.edu/", requestURL1));
187 "Resource Tree function: false positive",
188 !resourceTreeFunction.match("https://www.example.edu/", requestURL1));
190 "Resource Tree function: false negative",
191 resourceTreeFunction.match("http://www.example.edu:80/", requestURL1));
193 "Resource Tree function: false positive",
194 !resourceTreeFunction.match("http://www.example.edu:81/", requestURL1));
196 "Resource Tree function: false negative",
197 resourceTreeFunction.match("http://www.example.edu/test/", requestURL1));
199 "Resource Tree function: false negative",
200 resourceTreeFunction.match("http://www.example.edu/test/", requestURL2));
202 "Resource Tree function: false negative",
203 resourceTreeFunction.match("http://www.example.edu/", requestURL3));
205 "Resource Tree function: false positive",
206 !resourceTreeFunction.match("http://www.example.edu/test/", requestURL3));
208 "Resource Tree function: false negative",
209 resourceTreeFunction.match("http://www.example.edu/test2/index.html", requestURL3));
211 "Resource Tree function: false negative",
212 resourceTreeFunction.match("http://www.example.edu/test2/index.html", requestURL4));
214 "Resource Tree function: false negative",
215 resourceTreeFunction.match(
216 "http://www.example.edu/test2/index.html?test1=test1",
219 "Resource Tree function: false positive",
220 !resourceTreeFunction.match(
221 "http://www.example.edu/test2/index.html?test1=test1",
224 //Make sure we properly handle bad input
226 resourceTreeFunction.match(null, null);
227 fail("Resource Tree function seems to take improper input without throwing an exception.");
228 } catch (ArpException ie) {
229 //This is supposed to fail
232 resourceTreeFunction.match("Test", "Test");
233 fail("Resource Tree function seems to take improper input without throwing an exception.");
234 } catch (ArpException ie) {
235 //This is supposed to fail
239 * Test the Regex function (requester & resource)
242 //Try requester regexes
244 "Regex function: false negative",
245 regexFunction.match("^shar\\.example\\.edu$", "shar.example.edu"));
247 "Regex function: false negative",
248 regexFunction.match("^.*\\.example\\.edu$", "shar.example.edu"));
250 "Regex function: false negative",
251 regexFunction.match("^shar[1-9]?\\.example\\.edu$", "shar1.example.edu"));
252 assertTrue("Regex function: false negative", regexFunction.match(".*\\.edu", "shar.example.edu"));
254 "Regex function: false positive",
255 !regexFunction.match("^shar[1-9]\\.example\\.edu$", "shar.example.edu"));
257 "Regex function: false positive",
258 !regexFunction.match("^shar\\.example\\.edu$", "www.example.edu"));
260 "Regex function: false positive",
261 !regexFunction.match("^shar\\.example\\.edu$", "www.example.com"));
263 //Try resource regexes
265 "Regex function: false negative",
266 regexFunction.match("^http://www\\.example\\.edu/.*$", requestURL1));
268 "Regex function: false negative",
269 regexFunction.match("^http://www\\.example\\.edu/.*$", requestURL2));
271 "Regex function: false negative",
272 regexFunction.match("^http://.*\\.example\\.edu/.*$", requestURL2));
274 "Regex function: false negative",
275 regexFunction.match("^https?://.*\\.example\\.edu/.*$", requestURL2));
276 assertTrue("Regex function: false negative", regexFunction.match(".*", requestURL2));
278 "Regex function: false positive",
279 !regexFunction.match("^https?://.*\\.example\\.edu/$", requestURL2));
281 "Regex function: false positive",
282 !regexFunction.match("^https?://www\\.example\\.edu/test/$", requestURL3));
284 //Make sure we properly handle bad input
286 regexFunction.match(null, null);
287 fail("Regex function seems to take improper input without throwing an exception.");
288 } catch (ArpException ie) {
289 //This is supposed to fail
292 } catch (ArpException e) {
293 fail("Encountered a problem loading match function: " + e);
294 } catch (URISyntaxException e) {
295 fail("Unable to create URI from test string.");
296 } catch (MalformedURLException e) {
297 fail("Couldn't create test URLs: " + e);
302 public void testRepositories() {
308 //Make sure we fail if no Repository is specified
309 Properties props = new Properties();
311 ArpRepositoryFactory.getInstance(props);
312 } catch (ArpRepositoryException e) {
313 //This is supposed to fail
316 // Make sure we can create an Arp Repository
318 "edu.internet2.middleware.shibboleth.aa.arp.ArpRepository.implementation",
319 "edu.internet2.middleware.shibboleth.aa.arp.provider.MemoryArpRepository");
320 ArpRepository repository = null;
322 repository = ArpRepositoryFactory.getInstance(props);
323 } catch (ArpRepositoryException e) {
324 fail("Failed to create memory-based Arp Repository" + e);
326 assertNotNull("Failed to create memory-based Arp Repository: Factory returned null.", repository);
329 * Exercise the Memory Arp Repository
332 //Set/retrieve/remove a Site ARP
333 Arp siteArp1 = new Arp();
334 siteArp1.setDescription("Test Site Arp 1.");
336 repository.update(siteArp1);
338 "Memory Repository does not store and retrieve Site ARPs properly.",
340 repository.getSitePolicy());
341 repository.remove(repository.getSitePolicy());
342 assertNull("Memorty Repository does not properly delete Site ARPs.", repository.getSitePolicy());
343 } catch (ArpRepositoryException e) {
344 fail("Error adding Site ARP to Memory Repository.");
347 //Set/retrieve/delete some user ARPs
348 Arp userArp1 = new Arp();
349 userArp1.setDescription("Broken User Arp 1.");
351 repository.update(userArp1);
353 "Memory Repository does not store and retrieve User ARPs properly.",
354 (!userArp1.equals(repository.getUserPolicy(userArp1.getPrincipal()))));
355 } catch (ArpRepositoryException e) {
356 fail("Error adding User ARP to Memory Repository.");
359 Arp userArp2 = new Arp(new AAPrincipal("TestPrincipal"));
360 userArp2.setDescription("Test User Arp 2.");
362 repository.update(userArp2);
364 "Memory Repository does not store and retrieve User ARPs properly.",
366 repository.getUserPolicy(userArp2.getPrincipal()));
367 repository.remove(repository.getUserPolicy(userArp2.getPrincipal()));
369 "Memorty Repository does not properly delete User ARPs.",
370 repository.getUserPolicy(userArp2.getPrincipal()));
371 } catch (ArpRepositoryException e) {
372 fail("Error adding User ARP to Memory Repository.");