Added some tests for the FileSystemArpRepository.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / aa / arp / ArpTests.java
1 /* 
2  * The Shibboleth License, Version 1. 
3  * Copyright (c) 2002 
4  * University Corporation for Advanced Internet Development, Inc. 
5  * All rights reserved
6  * 
7  * 
8  * Redistribution and use in source and binary forms, with or without 
9  * modification, are permitted provided that the following conditions are met:
10  * 
11  * Redistributions of source code must retain the above copyright notice, this 
12  * list of conditions and the following disclaimer.
13  * 
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.
22  * 
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
28  * 
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.
33  * 
34  * 
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.
48  */
49
50 package edu.internet2.middleware.shibboleth.aa.arp;
51
52 import java.io.ByteArrayOutputStream;
53 import java.io.FileInputStream;
54 import java.io.FileNotFoundException;
55 import java.io.InputStream;
56 import java.io.StringReader;
57 import java.net.MalformedURLException;
58 import java.net.URI;
59 import java.net.URISyntaxException;
60 import java.net.URL;
61 import java.security.Principal;
62 import java.util.Arrays;
63 import java.util.HashSet;
64 import java.util.Properties;
65
66 import junit.framework.TestCase;
67
68 import org.apache.log4j.BasicConfigurator;
69 import org.apache.xerces.parsers.DOMParser;
70 import org.apache.xml.serialize.OutputFormat;
71 import org.apache.xml.serialize.XMLSerializer;
72 import org.xml.sax.EntityResolver;
73 import org.xml.sax.ErrorHandler;
74 import org.xml.sax.InputSource;
75 import org.xml.sax.SAXException;
76 import org.xml.sax.SAXParseException;
77
78 /**
79  * Validation suite for <code>Arp</code> processing.
80  * 
81  * @ author Walter Hoehn(wassa@columbia.edu)
82  */
83
84 public class ArpTests extends TestCase {
85
86         private DOMParser parser = new DOMParser();
87         private String[] arpExamples =
88                 {
89                         "data/example1.xml",
90                         "data/example2.xml",
91                         "data/example3.xml",
92                         "data/example4.xml",
93                         "data/example5.xml",
94                         "data/example6.xml",
95                         "data/example7.xml",
96                         "data/example8.xml",
97                         "data/example9.xml",
98                         "data/example10.xml",
99                         "data/example11.xml" };
100
101         public ArpTests(String name) {
102                 super(name);
103                 BasicConfigurator.resetConfiguration();
104                 BasicConfigurator.configure();
105         }
106
107         public static void main(String[] args) {
108                 junit.textui.TestRunner.run(ArpTests.class);
109                 BasicConfigurator.configure();
110         }
111
112         /**
113          * @see junit.framework.TestCase#setUp()
114          */
115         protected void setUp() throws Exception {
116                 super.setUp();
117                 try {
118                         parser.setFeature("http://xml.org/sax/features/validation", true);
119                         parser.setFeature("http://apache.org/xml/features/validation/schema", true);
120                         parser.setEntityResolver(new EntityResolver() {
121                                 public InputSource resolveEntity(String publicId, String systemId)
122                                         throws SAXException {
123
124                                         if (systemId.endsWith("shibboleth-arp-1.0.xsd")) {
125                                                 InputStream stream;
126                                                 try {
127                                                         stream = new FileInputStream("src/schemas/shibboleth-arp-1.0.xsd");
128                                                         if (stream != null) {
129                                                                 return new InputSource(stream);
130                                                         }
131                                                         throw new SAXException("Could not load entity: Null input stream");
132                                                 } catch (FileNotFoundException e) {
133                                                         throw new SAXException("Could not load entity: " + e);
134                                                 }
135                                         } else {
136                                                 return null;
137                                         }
138                                 }
139                         });
140
141                         parser.setErrorHandler(new ErrorHandler() {
142                                 public void error(SAXParseException arg0) throws SAXException {
143                                         throw new SAXException("Error parsing xml file: " + arg0);
144                                 }
145                                 public void fatalError(SAXParseException arg0) throws SAXException {
146                                         throw new SAXException("Error parsing xml file: " + arg0);
147                                 }
148                                 public void warning(SAXParseException arg0) throws SAXException {
149                                         throw new SAXException("Error parsing xml file: " + arg0);
150                                 }
151                         });
152                 } catch (Exception e) {
153                         fail("Failed to setup xml parser: " + e);
154                 }
155
156         }
157
158         public void testArpMarshalling() {
159
160                 //Test ARP description
161                 try {
162                         InputStream inStream = new FileInputStream("test/arp1.xml");
163                         parser.parse(new InputSource(inStream));
164                         Arp arp1 = new Arp();
165                         arp1.marshall(parser.getDocument().getDocumentElement());
166                         assertEquals(
167                                 "ARP Description not marshalled properly",
168                                 arp1.getDescription(),
169                                 "Simplest possible ARP.");
170
171                         //Test Rule description
172                         assertEquals(
173                                 "ARP Rule Description not marshalled properly",
174                                 arp1.getAllRules()[0].getDescription(),
175                                 "Example Rule Description.");
176                 } catch (Exception e) {
177                         fail("Failed to marshall ARP: " + e);
178                 }
179
180                 //Test case where ARP description does not exist
181                 try {
182                         InputStream inStream = new FileInputStream("test/arp2.xml");
183                         parser.parse(new InputSource(inStream));
184                         Arp arp2 = new Arp();
185                         arp2.marshall(parser.getDocument().getDocumentElement());
186                         assertNull("ARP Description not marshalled properly", arp2.getDescription());
187
188                         //Test case where ARP Rule description does not exist   
189                         assertNull(
190                                 "ARP Rule Description not marshalled properly",
191                                 arp2.getAllRules()[0].getDescription());
192                 } catch (Exception e) {
193                         fail("Failed to marshall ARP.");
194                 }
195
196         }
197
198         public void testMatchingFunctions() {
199
200                 try {
201
202                         /*
203                          * Test Arp Engine function retrieval
204                          */
205
206                         //Lookup a function that doesn't exist
207                         MatchFunction noFunction =
208                                 ArpEngine.lookupMatchFunction(
209                                         new URI("urn:mace:shibboleth:arp:matchFunction:dummy"));
210                         assertNull("ArpEngine did not return null on dummy function.", noFunction);
211
212                         //Lookup some real functions
213                         MatchFunction exactSharFunction =
214                                 ArpEngine.lookupMatchFunction(
215                                         new URI("urn:mace:shibboleth:arp:matchFunction:exactShar"));
216                         assertNotNull(
217                                 "ArpEngine did not properly load the Exact SHAR function.",
218                                 exactSharFunction);
219                         MatchFunction resourceTreeFunction =
220                                 ArpEngine.lookupMatchFunction(
221                                         new URI("urn:mace:shibboleth:arp:matchFunction:resourceTree"));
222                         assertNotNull(
223                                 "ArpEngine did not properly load the Resource Tree SHAR function.",
224                                 resourceTreeFunction);
225                         MatchFunction regexFunction =
226                                 ArpEngine.lookupMatchFunction(
227                                         new URI("urn:mace:shibboleth:arp:matchFunction:regexMatch"));
228                         assertNotNull("ArpEngine did not properly load the Regex function.", regexFunction);
229
230                         /* 
231                          * Test the Exact SHAR function (requester)
232                          */
233
234                         assertTrue(
235                                 "Exact SHAR function: false negative",
236                                 exactSharFunction.match("shar.example.edu", "shar.example.edu"));
237                         assertTrue(
238                                 "Exact SHAR function: false negative",
239                                 !exactSharFunction.match("shar.example.edu", "www.example.edu"));
240                         assertTrue(
241                                 "Exact SHAR function: false negative",
242                                 !exactSharFunction.match("example.edu", "shar.example.edu"));
243
244                         //Make sure we properly handle bad input
245                         try {
246                                 exactSharFunction.match(null, null);
247                                 fail("Exact SHAR function seems to take improper input without throwing an exception.");
248                         } catch (ArpException ie) {
249                                 //This is supposed to fail
250                         }
251
252                         /*
253                          * Test the Resource Tree function (resource)
254                          */
255
256                         URL requestURL1 = new URL("http://www.example.edu/test/");
257                         URL requestURL2 = new URL("http://www.example.edu/test/index.html");
258                         URL requestURL3 = new URL("http://www.example.edu/test2/index.html");
259                         URL requestURL4 = new URL("http://www.example.edu/test2/index.html?test1=test1");
260
261                         assertTrue(
262                                 "Resource Tree function: false negative",
263                                 resourceTreeFunction.match("http://www.example.edu/", requestURL1));
264                         assertTrue(
265                                 "Resource Tree function: false positive",
266                                 !resourceTreeFunction.match("https://www.example.edu/", requestURL1));
267                         assertTrue(
268                                 "Resource Tree function: false negative",
269                                 resourceTreeFunction.match("http://www.example.edu:80/", requestURL1));
270                         assertTrue(
271                                 "Resource Tree function: false positive",
272                                 !resourceTreeFunction.match("http://www.example.edu:81/", requestURL1));
273                         assertTrue(
274                                 "Resource Tree function: false negative",
275                                 resourceTreeFunction.match("http://www.example.edu/test/", requestURL1));
276                         assertTrue(
277                                 "Resource Tree function: false negative",
278                                 resourceTreeFunction.match("http://www.example.edu/test/", requestURL2));
279                         assertTrue(
280                                 "Resource Tree function: false negative",
281                                 resourceTreeFunction.match("http://www.example.edu/", requestURL3));
282                         assertTrue(
283                                 "Resource Tree function: false positive",
284                                 !resourceTreeFunction.match("http://www.example.edu/test/", requestURL3));
285                         assertTrue(
286                                 "Resource Tree function: false negative",
287                                 resourceTreeFunction.match("http://www.example.edu/test2/index.html", requestURL3));
288                         assertTrue(
289                                 "Resource Tree function: false negative",
290                                 resourceTreeFunction.match("http://www.example.edu/test2/index.html", requestURL4));
291                         assertTrue(
292                                 "Resource Tree function: false negative",
293                                 resourceTreeFunction.match(
294                                         "http://www.example.edu/test2/index.html?test1=test1",
295                                         requestURL4));
296                         assertTrue(
297                                 "Resource Tree function: false positive",
298                                 !resourceTreeFunction.match(
299                                         "http://www.example.edu/test2/index.html?test1=test1",
300                                         requestURL3));
301
302                         //Make sure we properly handle bad input
303                         try {
304                                 resourceTreeFunction.match(null, null);
305                                 fail("Resource Tree function seems to take improper input without throwing an exception.");
306                         } catch (ArpException ie) {
307                                 //This is supposed to fail
308                         }
309                         try {
310                                 resourceTreeFunction.match("Test", "Test");
311                                 fail("Resource Tree function seems to take improper input without throwing an exception.");
312                         } catch (ArpException ie) {
313                                 //This is supposed to fail
314                         }
315
316                         /*
317                          * Test the Regex function (requester & resource)
318                          */
319
320                         //Try requester regexes
321                         assertTrue(
322                                 "Regex function: false negative",
323                                 regexFunction.match("^shar\\.example\\.edu$", "shar.example.edu"));
324                         assertTrue(
325                                 "Regex function: false negative",
326                                 regexFunction.match("^.*\\.example\\.edu$", "shar.example.edu"));
327                         assertTrue(
328                                 "Regex function: false negative",
329                                 regexFunction.match("^shar[1-9]?\\.example\\.edu$", "shar1.example.edu"));
330                         assertTrue(
331                                 "Regex function: false negative",
332                                 regexFunction.match(".*\\.edu", "shar.example.edu"));
333                         assertTrue(
334                                 "Regex function: false positive",
335                                 !regexFunction.match("^shar[1-9]\\.example\\.edu$", "shar.example.edu"));
336                         assertTrue(
337                                 "Regex function: false positive",
338                                 !regexFunction.match("^shar\\.example\\.edu$", "www.example.edu"));
339                         assertTrue(
340                                 "Regex function: false positive",
341                                 !regexFunction.match("^shar\\.example\\.edu$", "www.example.com"));
342
343                         //Try resource regexes
344                         assertTrue(
345                                 "Regex function: false negative",
346                                 regexFunction.match("^http://www\\.example\\.edu/.*$", requestURL1));
347                         assertTrue(
348                                 "Regex function: false negative",
349                                 regexFunction.match("^http://www\\.example\\.edu/.*$", requestURL2));
350                         assertTrue(
351                                 "Regex function: false negative",
352                                 regexFunction.match("^http://.*\\.example\\.edu/.*$", requestURL2));
353                         assertTrue(
354                                 "Regex function: false negative",
355                                 regexFunction.match("^https?://.*\\.example\\.edu/.*$", requestURL2));
356                         assertTrue("Regex function: false negative", regexFunction.match(".*", requestURL2));
357                         assertTrue(
358                                 "Regex function: false positive",
359                                 !regexFunction.match("^https?://.*\\.example\\.edu/$", requestURL2));
360                         assertTrue(
361                                 "Regex function: false positive",
362                                 !regexFunction.match("^https?://www\\.example\\.edu/test/$", requestURL3));
363
364                         //Make sure we properly handle bad input
365                         try {
366                                 regexFunction.match(null, null);
367                                 fail("Regex function seems to take improper input without throwing an exception.");
368                         } catch (ArpException ie) {
369                                 //This is supposed to fail
370                         }
371
372                 } catch (ArpException e) {
373                         fail("Encountered a problem loading match function: " + e);
374                 } catch (URISyntaxException e) {
375                         fail("Unable to create URI from test string.");
376                 } catch (MalformedURLException e) {
377                         fail("Couldn't create test URLs: " + e);
378                 }
379
380         }
381
382         public void testRepositories() {
383
384                 /*
385                  * Test the Factory
386                  */
387
388                 //Make sure we fail if no Repository is specified
389                 Properties props = new Properties();
390                 try {
391                         ArpRepositoryFactory.getInstance(props);
392                 } catch (ArpRepositoryException e) {
393                         //This is supposed to fail
394                 }
395
396                 // Make sure we can create an Arp Repository
397                 props.setProperty(
398                         "edu.internet2.middleware.shibboleth.aa.arp.ArpRepository.implementation",
399                         "edu.internet2.middleware.shibboleth.aa.arp.provider.MemoryArpRepository");
400                 ArpRepository repository = null;
401                 try {
402                         repository = ArpRepositoryFactory.getInstance(props);
403                 } catch (ArpRepositoryException e) {
404                         fail("Failed to create memory-based Arp Repository" + e);
405                 }
406                 assertNotNull(
407                         "Failed to create memory-based Arp Repository: Factory returned null.",
408                         repository);
409
410                 /*
411                  * Exercise the Memory Arp Repository
412                  */
413
414                 //Set/retrieve/remove a Site ARP
415                 Arp siteArp1 = new Arp();
416                 siteArp1.setDescription("Test Site Arp 1.");
417                 try {
418                         repository.update(siteArp1);
419                         assertEquals(
420                                 "Memory Repository does not store and retrieve Site ARPs properly.",
421                                 siteArp1,
422                                 repository.getSitePolicy());
423                         repository.remove(repository.getSitePolicy());
424                         assertNull(
425                                 "Memorty Repository does not properly delete Site ARPs.",
426                                 repository.getSitePolicy());
427                 } catch (ArpRepositoryException e) {
428                         fail("Error adding Site ARP to Memory Repository.");
429                 }
430
431                 //Set/retrieve/delete some user ARPs
432                 Arp userArp1 = new Arp();
433                 userArp1.setDescription("Broken User Arp 1.");
434                 try {
435                         repository.update(userArp1);
436                         assertTrue(
437                                 "Memory Repository does not store and retrieve User ARPs properly.",
438                                 (!userArp1.equals(repository.getUserPolicy(userArp1.getPrincipal()))));
439                 } catch (ArpRepositoryException e) {
440                         fail("Error adding User ARP to Memory Repository.");
441                 }
442
443                 Arp userArp2 = new Arp(new AAPrincipal("TestPrincipal"));
444                 userArp2.setDescription("Test User Arp 2.");
445                 try {
446                         repository.update(userArp2);
447                         assertEquals(
448                                 "Memory Repository does not store and retrieve User ARPs properly.",
449                                 userArp2,
450                                 repository.getUserPolicy(userArp2.getPrincipal()));
451                         repository.remove(repository.getUserPolicy(userArp2.getPrincipal()));
452                         assertNull(
453                                 "Memorty Repository does not properly delete User ARPs.",
454                                 repository.getUserPolicy(userArp2.getPrincipal()));
455                 } catch (ArpRepositoryException e) {
456                         fail("Error adding User ARP to Memory Repository.");
457                 }
458
459                 /*
460                  * Exercise the Memory Arp Repository
461                  */
462
463                 //create a repository
464                 props.setProperty(
465                         "edu.internet2.middleware.shibboleth.aa.arp.ArpRepository.implementation",
466                         "edu.internet2.middleware.shibboleth.aa.arp.provider.FileSystemArpRepository");
467                 props.setProperty(
468                         "edu.internet2.middleware.shibboleth.aa.arp.provider.FileSystemArpRepository.Path",
469                         "data");
470                 props.setProperty(
471                         "edu.internet2.middleware.shibboleth.aa.arp.BaseArpRepository.ArpTTL",
472                         "65535");
473                 repository = null;
474                 try {
475                         repository = ArpRepositoryFactory.getInstance(props);
476                 } catch (ArpRepositoryException e) {
477                         fail("Failed to create file-based Arp Repository" + e);
478                 }
479                 assertNotNull(
480                         "Failed to create file-based Arp Repository: Factory returned null.",
481                         repository);
482
483                 try {
484                         Arp siteArp = repository.getSitePolicy();
485
486                         InputStream inStream = new FileInputStream("data/arp.site.xml");
487                         parser.parse(new InputSource(inStream));
488                         ByteArrayOutputStream directXML = new ByteArrayOutputStream();
489                         new XMLSerializer(directXML, new OutputFormat()).serialize(
490                                 parser.getDocument().getDocumentElement());
491
492                         ByteArrayOutputStream processedXML = new ByteArrayOutputStream();
493                         new XMLSerializer(processedXML, new OutputFormat()).serialize(siteArp.unmarshall());
494
495                         assertTrue(
496                                 "File-based ARP Repository did not return the correct site ARP.",
497                                 directXML.toString().replaceAll(">[\t\r\n ]+<", "><").equals(
498                                         processedXML.toString().replaceAll(">[\t\r\n ]+<", "><")));
499
500                         Arp userArp = repository.getUserPolicy(new AAPrincipal("test"));
501
502                         inStream = new FileInputStream("data/arp.user.test.xml");
503                         parser.parse(new InputSource(inStream));
504                         directXML = new ByteArrayOutputStream();
505                         new XMLSerializer(directXML, new OutputFormat()).serialize(
506                                 parser.getDocument().getDocumentElement());
507
508                         processedXML = new ByteArrayOutputStream();
509                         new XMLSerializer(processedXML, new OutputFormat()).serialize(userArp.unmarshall());
510
511                         assertTrue(
512                                 "File-based ARP Repository did not return the correct user ARP.",
513                                 directXML.toString().replaceAll(">[\t\r\n ]+<", "><").equals(
514                                         processedXML.toString().replaceAll(">[\t\r\n ]+<", "><")));
515
516                         Arp[] allArps = repository.getAllPolicies(new AAPrincipal("test"));
517
518                         assertTrue("File-based ARP Repository did not return the correct number of ARPs.", (allArps.length == 2));
519                 
520                 } catch (Exception e) {
521                         fail("Error retrieving ARP from Repository: " + e);
522                 }
523
524         }
525
526         public void testPossibleReleaseSetComputation() {
527                 Properties props = new Properties();
528                 props.setProperty(
529                         "edu.internet2.middleware.shibboleth.aa.arp.ArpRepository.implementation",
530                         "edu.internet2.middleware.shibboleth.aa.arp.provider.MemoryArpRepository");
531                 ArpRepository repository = null;
532                 try {
533                         repository = ArpRepositoryFactory.getInstance(props);
534                 } catch (ArpRepositoryException e) {
535                         fail("Failed to create memory-based Arp Repository" + e);
536                 }
537
538                 try {
539                         Principal principal1 = new AAPrincipal("TestPrincipal");
540                         URL url1 = new URL("http://www.example.edu/");
541                         URI[] list1 = { new URI("urn:mace:eduPerson:1.0:eduPersonAffiliation")};
542                         URI[] list2 =
543                                 {
544                                         new URI("urn:mace:eduPerson:1.0:eduPersonAffiliation"),
545                                         new URI("urn:mace:eduPerson:1.0:eduPersonPrincipalName")};
546                         URI[] list3 = new URI[0];
547
548                         //Test with just a site ARP
549                         InputStream inStream = new FileInputStream("test/arp1.xml");
550                         parser.parse(new InputSource(inStream));
551                         Arp arp1 = new Arp();
552                         arp1.marshall(parser.getDocument().getDocumentElement());
553                         repository.update(arp1);
554                         ArpEngine engine = new ArpEngine(repository, props);
555                         URI[] possibleAttributes =
556                                 engine.listPossibleReleaseAttributes(principal1, "shar.example.edu", url1);
557                         assertEquals(
558                                 "Incorrectly computed possible release set (1).",
559                                 new HashSet(Arrays.asList(possibleAttributes)),
560                                 new HashSet(Arrays.asList(list1)));
561
562                         //Test with site and user ARPs
563                         inStream = new FileInputStream("test/arp7.xml");
564                         parser.parse(new InputSource(inStream));
565                         Arp arp7 = new Arp();
566                         arp7.setPrincipal(principal1);
567                         arp7.marshall(parser.getDocument().getDocumentElement());
568                         repository.update(arp7);
569                         possibleAttributes =
570                                 engine.listPossibleReleaseAttributes(principal1, "shar.example.edu", url1);
571                         assertEquals(
572                                 "Incorrectly computed possible release set (2).",
573                                 new HashSet(Arrays.asList(possibleAttributes)),
574                                 new HashSet(Arrays.asList(list2)));
575
576                         //Ensure that explicit denies on any value are not in the release set
577                         inStream = new FileInputStream("test/arp6.xml");
578                         parser.parse(new InputSource(inStream));
579                         Arp arp6 = new Arp();
580                         arp6.setPrincipal(principal1);
581                         arp6.marshall(parser.getDocument().getDocumentElement());
582                         repository.update(arp6);
583                         possibleAttributes =
584                                 engine.listPossibleReleaseAttributes(principal1, "shar.example.edu", url1);
585                         assertEquals(
586                                 "Incorrectly computed possible release set (3).",
587                                 new HashSet(Arrays.asList(possibleAttributes)),
588                                 new HashSet(Arrays.asList(list3)));
589
590                 } catch (Exception e) {
591                         e.printStackTrace();
592                         fail("Failed to marshall ARP: " + e);
593                 }
594
595         }
596
597         public void testArpApplication() {
598
599                 //Setup a test ARP repository
600                 Properties props = new Properties();
601                 props.setProperty(
602                         "edu.internet2.middleware.shibboleth.aa.arp.ArpRepository.implementation",
603                         "edu.internet2.middleware.shibboleth.aa.arp.provider.MemoryArpRepository");
604                 ArpRepository repository = null;
605                 try {
606                         repository = ArpRepositoryFactory.getInstance(props);
607                 } catch (ArpRepositoryException e) {
608                         fail("Failed to create memory-based Arp Repository" + e);
609                 }
610
611                 try {
612
613                         arpApplicationTest1(repository, props, parser);
614                         arpApplicationTest2(repository, props, parser);
615                         arpApplicationTest3(repository, props, parser);
616                         arpApplicationTest4(repository, props, parser);
617                         arpApplicationTest5(repository, props, parser);
618                         arpApplicationTest6(repository, props, parser);
619                         arpApplicationTest7(repository, props, parser);
620                         arpApplicationTest8(repository, props, parser);
621                         arpApplicationTest9(repository, props, parser);
622                         arpApplicationTest10(repository, props, parser);
623                         arpApplicationTest11(repository, props, parser);
624                         arpApplicationTest12(repository, props, parser);
625                         arpApplicationTest13(repository, props, parser);
626                         arpApplicationTest14(repository, props, parser);
627                         arpApplicationTest15(repository, props, parser);
628                         arpApplicationTest16(repository, props, parser);
629                         arpApplicationTest17(repository, props, parser);
630                         arpApplicationTest18(repository, props, parser);
631                         arpApplicationTest19(repository, props, parser);
632                         arpApplicationTest20(repository, props, parser);
633                         arpApplicationTest21(repository, props, parser);
634
635                 } catch (Exception e) {
636                         e.printStackTrace();
637                         fail("Failed to apply filter to ARPs: " + e);
638                 }
639         }
640
641         public void testRoundtripMarshalling() {
642
643                 try {
644                         for (int i = 0; i < arpExamples.length; i++) {
645
646                                 InputStream inStream = new FileInputStream(arpExamples[i]);
647                                 parser.parse(new InputSource(inStream));
648                                 ByteArrayOutputStream directXML = new ByteArrayOutputStream();
649                                 new XMLSerializer(directXML, new OutputFormat()).serialize(
650                                         parser.getDocument().getDocumentElement());
651
652                                 Arp arp1 = new Arp();
653                                 arp1.marshall(parser.getDocument().getDocumentElement());
654
655                                 ByteArrayOutputStream processedXML = new ByteArrayOutputStream();
656                                 new XMLSerializer(processedXML, new OutputFormat()).serialize(arp1.unmarshall());
657
658                                 assertTrue(
659                                         "Round trip marshall/unmarshall failed for file (" + arpExamples[i] + ")",
660                                         directXML.toString().replaceAll(">[\t\r\n ]+<", "><").equals(
661                                                 processedXML.toString().replaceAll(">[\t\r\n ]+<", "><")));
662                         }
663
664                 } catch (Exception e) {
665                         fail("Failed to marshall ARP: " + e);
666                 }
667
668         }
669         /**
670          * ARPs: A site ARP only
671          * Target: Any
672          * Attribute: Any value release,
673          */
674         void arpApplicationTest1(ArpRepository repository, Properties props, DOMParser parser)
675                 throws Exception {
676
677                 //Gather the Input
678                 String rawArp =
679                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
680                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
681                                 + "                     <Rule>"
682                                 + "                             <Target>"
683                                 + "                                     <AnyTarget/>"
684                                 + "                             </Target>"
685                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
686                                 + "                                     <AnyValue release=\"permit\"/>"
687                                 + "                             </Attribute>"
688                                 + "                     </Rule>"
689                                 + "     </AttributeReleasePolicy>";
690
691                 Principal principal1 = new AAPrincipal("TestPrincipal");
692                 URL url1 = new URL("http://www.example.edu/");
693                 TestAttribute testAttribute =
694                         new TestAttribute(
695                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
696                                 new Object[] { "member@example.edu", "faculty@example.edu" });
697
698                 //Setup the engine
699                 parser.parse(new InputSource(new StringReader(rawArp)));
700                 Arp siteArp = new Arp();
701                 siteArp.marshall(parser.getDocument().getDocumentElement());
702                 repository.update(siteArp);
703                 ArpEngine engine = new ArpEngine(repository, props);
704
705                 //Apply the ARP
706                 ArpAttribute[] releaseAttributes =
707                         engine.filterAttributes(
708                                 new ArpAttribute[] { testAttribute },
709                                 principal1,
710                                 "shar.example.edu",
711                                 url1);
712
713                 assertEquals(
714                         "ARP application test 1: ARP not applied as expected.",
715                         new HashSet(Arrays.asList(releaseAttributes)),
716                         new HashSet(Arrays.asList(new ArpAttribute[] { testAttribute })));
717         }
718
719         /**
720          * ARPs: A site ARP only
721          * Target: Any
722          * Attribute: Any value release, implicit deny
723          */
724         void arpApplicationTest2(ArpRepository repository, Properties props, DOMParser parser)
725                 throws Exception {
726
727                 //Gather the Input
728                 String rawArp =
729                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
730                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
731                                 + "                     <Rule>"
732                                 + "                             <Target>"
733                                 + "                                     <AnyTarget/>"
734                                 + "                             </Target>"
735                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
736                                 + "                                     <AnyValue release=\"permit\"/>"
737                                 + "                             </Attribute>"
738                                 + "                     </Rule>"
739                                 + "     </AttributeReleasePolicy>";
740
741                 Principal principal1 = new AAPrincipal("TestPrincipal");
742                 URL url1 = new URL("http://www.example.edu/");
743                 TestAttribute testAttribute1 =
744                         new TestAttribute(
745                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
746                                 new Object[] { "member@example.edu", "faculty@example.edu" });
747                 TestAttribute testAttribute2 =
748                         new TestAttribute(
749                                 "urn:mace:eduPerson:1.0:eduPersonPrincipalName",
750                                 new Object[] { "mehoehn@example.edu" });
751
752                 //Setup the engine
753                 parser.parse(new InputSource(new StringReader(rawArp)));
754                 Arp siteArp = new Arp();
755                 siteArp.marshall(parser.getDocument().getDocumentElement());
756                 repository.update(siteArp);
757                 ArpEngine engine = new ArpEngine(repository, props);
758
759                 //Apply the ARP
760                 ArpAttribute[] releaseAttributes =
761                         engine.filterAttributes(
762                                 new ArpAttribute[] { testAttribute1, testAttribute2 },
763                                 principal1,
764                                 "shar.example.edu",
765                                 url1);
766
767                 assertEquals(
768                         "ARP application test 2: ARP not applied as expected.",
769                         new HashSet(Arrays.asList(releaseAttributes)),
770                         new HashSet(Arrays.asList(new ArpAttribute[] { testAttribute1 })));
771         }
772
773         /**
774          * ARPs: A site ARP only
775          * Target: Any
776          * Attribute: One value release
777          */
778         void arpApplicationTest3(ArpRepository repository, Properties props, DOMParser parser)
779                 throws Exception {
780
781                 //Gather the Input
782                 String rawArp =
783                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
784                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
785                                 + "                     <Rule>"
786                                 + "                             <Target>"
787                                 + "                                     <AnyTarget/>"
788                                 + "                             </Target>"
789                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
790                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
791                                 + "                             </Attribute>"
792                                 + "                     </Rule>"
793                                 + "     </AttributeReleasePolicy>";
794
795                 Principal principal1 = new AAPrincipal("TestPrincipal");
796                 URL url1 = new URL("http://www.example.edu/");
797                 TestAttribute testAttribute =
798                         new TestAttribute(
799                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
800                                 new Object[] { "member@example.edu", "faculty@example.edu" });
801                 TestAttribute filteredAttribute =
802                         new TestAttribute(
803                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
804                                 new Object[] { "member@example.edu" });
805
806                 //Setup the engine
807                 parser.parse(new InputSource(new StringReader(rawArp)));
808                 Arp siteArp = new Arp();
809                 siteArp.marshall(parser.getDocument().getDocumentElement());
810                 repository.update(siteArp);
811                 ArpEngine engine = new ArpEngine(repository, props);
812
813                 //Apply the ARP
814                 ArpAttribute[] releaseAttributes =
815                         engine.filterAttributes(
816                                 new ArpAttribute[] { testAttribute },
817                                 principal1,
818                                 "shar.example.edu",
819                                 url1);
820
821                 assertEquals(
822                         "ARP application test 3: ARP not applied as expected.",
823                         new HashSet(Arrays.asList(releaseAttributes)),
824                         new HashSet(Arrays.asList(new ArpAttribute[] { filteredAttribute })));
825         }
826
827         /**
828          * ARPs: A site ARP only
829          * Target: Any
830          * Attribute: Any value except one release, canonical representation
831          */
832         void arpApplicationTest4(ArpRepository repository, Properties props, DOMParser parser)
833                 throws Exception {
834
835                 //Gather the Input
836                 String rawArp =
837                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
838                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
839                                 + "                     <Rule>"
840                                 + "                             <Target>"
841                                 + "                                     <AnyTarget/>"
842                                 + "                             </Target>"
843                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
844                                 + "                                     <AnyValue release=\"permit\"/>"
845                                 + "                                     <Value release=\"deny\">member@example.edu</Value>"
846                                 + "                             </Attribute>"
847                                 + "                     </Rule>"
848                                 + "     </AttributeReleasePolicy>";
849
850                 Principal principal1 = new AAPrincipal("TestPrincipal");
851                 URL url1 = new URL("http://www.example.edu/");
852                 TestAttribute testAttribute =
853                         new TestAttribute(
854                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
855                                 new Object[] {
856                                         "member@example.edu",
857                                         "faculty@example.edu",
858                                         "employee@example.edu" });
859                 TestAttribute filteredAttribute =
860                         new TestAttribute(
861                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
862                                 new Object[] { "faculty@example.edu", "employee@example.edu" });
863
864                 //Setup the engine
865                 parser.parse(new InputSource(new StringReader(rawArp)));
866                 Arp siteArp = new Arp();
867                 siteArp.marshall(parser.getDocument().getDocumentElement());
868                 repository.update(siteArp);
869                 ArpEngine engine = new ArpEngine(repository, props);
870
871                 //Apply the ARP
872                 ArpAttribute[] releaseAttributes =
873                         engine.filterAttributes(
874                                 new ArpAttribute[] { testAttribute },
875                                 principal1,
876                                 "shar.example.edu",
877                                 url1);
878
879                 assertEquals(
880                         "ARP application test 4: ARP not applied as expected.",
881                         new HashSet(Arrays.asList(releaseAttributes)),
882                         new HashSet(Arrays.asList(new ArpAttribute[] { filteredAttribute })));
883         }
884
885         /**
886          * ARPs: A site ARP only
887          * Target: Any
888          * Attribute: Any value except one release, expanded representation
889          */
890         void arpApplicationTest5(ArpRepository repository, Properties props, DOMParser parser)
891                 throws Exception {
892
893                 //Gather the Input
894                 String rawArp =
895                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
896                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
897                                 + "                     <Rule>"
898                                 + "                             <Target>"
899                                 + "                                     <AnyTarget/>"
900                                 + "                             </Target>"
901                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
902                                 + "                                     <AnyValue release=\"permit\"/>"
903                                 + "                             </Attribute>"
904                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
905                                 + "                                     <Value release=\"deny\">member@example.edu</Value>"
906                                 + "                             </Attribute>"
907                                 + "                     </Rule>"
908                                 + "     </AttributeReleasePolicy>";
909
910                 Principal principal1 = new AAPrincipal("TestPrincipal");
911                 URL url1 = new URL("http://www.example.edu/");
912                 TestAttribute testAttribute =
913                         new TestAttribute(
914                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
915                                 new Object[] {
916                                         "member@example.edu",
917                                         "faculty@example.edu",
918                                         "employee@example.edu" });
919                 TestAttribute filteredAttribute =
920                         new TestAttribute(
921                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
922                                 new Object[] { "faculty@example.edu", "employee@example.edu" });
923
924                 //Setup the engine
925                 parser.parse(new InputSource(new StringReader(rawArp)));
926                 Arp siteArp = new Arp();
927                 siteArp.marshall(parser.getDocument().getDocumentElement());
928                 repository.update(siteArp);
929                 ArpEngine engine = new ArpEngine(repository, props);
930
931                 //Apply the ARP
932                 ArpAttribute[] releaseAttributes =
933                         engine.filterAttributes(
934                                 new ArpAttribute[] { testAttribute },
935                                 principal1,
936                                 "shar.example.edu",
937                                 url1);
938
939                 assertEquals(
940                         "ARP application test 5: ARP not applied as expected.",
941                         new HashSet(Arrays.asList(releaseAttributes)),
942                         new HashSet(Arrays.asList(new ArpAttribute[] { filteredAttribute })));
943         }
944
945         /**
946          * ARPs: A site ARP only
947          * Target: Any
948          * Attribute: Any value except two release, expanded representation
949          */
950         void arpApplicationTest6(ArpRepository repository, Properties props, DOMParser parser)
951                 throws Exception {
952
953                 //Gather the Input
954                 String rawArp =
955                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
956                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
957                                 + "                     <Rule>"
958                                 + "                             <Target>"
959                                 + "                                     <AnyTarget/>"
960                                 + "                             </Target>"
961                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
962                                 + "                                     <AnyValue release=\"permit\"/>"
963                                 + "                             </Attribute>"
964                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
965                                 + "                                     <Value release=\"deny\">member@example.edu</Value>"
966                                 + "                             </Attribute>"
967                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
968                                 + "                                     <Value release=\"deny\">faculty@example.edu</Value>"
969                                 + "                             </Attribute>"
970                                 + "                     </Rule>"
971                                 + "     </AttributeReleasePolicy>";
972
973                 Principal principal1 = new AAPrincipal("TestPrincipal");
974                 URL url1 = new URL("http://www.example.edu/");
975                 TestAttribute testAttribute =
976                         new TestAttribute(
977                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
978                                 new Object[] {
979                                         "member@example.edu",
980                                         "faculty@example.edu",
981                                         "employee@example.edu" });
982                 TestAttribute filteredAttribute =
983                         new TestAttribute(
984                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
985                                 new Object[] { "employee@example.edu" });
986
987                 //Setup the engine
988                 parser.parse(new InputSource(new StringReader(rawArp)));
989                 Arp siteArp = new Arp();
990                 siteArp.marshall(parser.getDocument().getDocumentElement());
991                 repository.update(siteArp);
992                 ArpEngine engine = new ArpEngine(repository, props);
993
994                 //Apply the ARP
995                 ArpAttribute[] releaseAttributes =
996                         engine.filterAttributes(
997                                 new ArpAttribute[] { testAttribute },
998                                 principal1,
999                                 "shar.example.edu",
1000                                 url1);
1001
1002                 assertEquals(
1003                         "ARP application test 6: ARP not applied as expected.",
1004                         new HashSet(Arrays.asList(releaseAttributes)),
1005                         new HashSet(Arrays.asList(new ArpAttribute[] { filteredAttribute })));
1006         }
1007
1008         /**
1009          * ARPs: A site ARP only
1010          * Target: Any
1011          * Attribute: Two value release, canonical representation
1012          */
1013         void arpApplicationTest7(ArpRepository repository, Properties props, DOMParser parser)
1014                 throws Exception {
1015
1016                 //Gather the Input
1017                 String rawArp =
1018                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1019                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1020                                 + "                     <Rule>"
1021                                 + "                             <Target>"
1022                                 + "                                     <AnyTarget/>"
1023                                 + "                             </Target>"
1024                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1025                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
1026                                 + "                                     <Value release=\"permit\">faculty@example.edu</Value>"
1027                                 + "                             </Attribute>"
1028                                 + "                     </Rule>"
1029                                 + "     </AttributeReleasePolicy>";
1030
1031                 Principal principal1 = new AAPrincipal("TestPrincipal");
1032                 URL url1 = new URL("http://www.example.edu/");
1033                 TestAttribute testAttribute =
1034                         new TestAttribute(
1035                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1036                                 new Object[] {
1037                                         "member@example.edu",
1038                                         "faculty@example.edu",
1039                                         "employee@example.edu" });
1040                 TestAttribute filteredAttribute =
1041                         new TestAttribute(
1042                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1043                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1044
1045                 //Setup the engine
1046                 parser.parse(new InputSource(new StringReader(rawArp)));
1047                 Arp siteArp = new Arp();
1048                 siteArp.marshall(parser.getDocument().getDocumentElement());
1049                 repository.update(siteArp);
1050                 ArpEngine engine = new ArpEngine(repository, props);
1051
1052                 //Apply the ARP
1053                 ArpAttribute[] releaseAttributes =
1054                         engine.filterAttributes(
1055                                 new ArpAttribute[] { testAttribute },
1056                                 principal1,
1057                                 "shar.example.edu",
1058                                 url1);
1059
1060                 assertEquals(
1061                         "ARP application test 3: ARP not applied as expected.",
1062                         new HashSet(Arrays.asList(releaseAttributes)),
1063                         new HashSet(Arrays.asList(new ArpAttribute[] { filteredAttribute })));
1064         }
1065
1066         /**
1067          * ARPs: A site ARP only
1068          * Target: Any
1069          * Attribute: Two value release, expanded representation
1070          */
1071         void arpApplicationTest8(ArpRepository repository, Properties props, DOMParser parser)
1072                 throws Exception {
1073
1074                 //Gather the Input
1075                 String rawArp =
1076                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1077                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1078                                 + "                     <Rule>"
1079                                 + "                             <Target>"
1080                                 + "                                     <AnyTarget/>"
1081                                 + "                             </Target>"
1082                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1083                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
1084                                 + "                             </Attribute>"
1085                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1086                                 + "                                     <Value release=\"permit\">faculty@example.edu</Value>"
1087                                 + "                             </Attribute>"
1088                                 + "                     </Rule>"
1089                                 + "     </AttributeReleasePolicy>";
1090
1091                 Principal principal1 = new AAPrincipal("TestPrincipal");
1092                 URL url1 = new URL("http://www.example.edu/");
1093                 TestAttribute testAttribute =
1094                         new TestAttribute(
1095                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1096                                 new Object[] {
1097                                         "member@example.edu",
1098                                         "faculty@example.edu",
1099                                         "employee@example.edu" });
1100                 TestAttribute filteredAttribute =
1101                         new TestAttribute(
1102                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1103                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1104
1105                 //Setup the engine
1106                 parser.parse(new InputSource(new StringReader(rawArp)));
1107                 Arp siteArp = new Arp();
1108                 siteArp.marshall(parser.getDocument().getDocumentElement());
1109                 repository.update(siteArp);
1110                 ArpEngine engine = new ArpEngine(repository, props);
1111
1112                 //Apply the ARP
1113                 ArpAttribute[] releaseAttributes =
1114                         engine.filterAttributes(
1115                                 new ArpAttribute[] { testAttribute },
1116                                 principal1,
1117                                 "shar.example.edu",
1118                                 url1);
1119
1120                 assertEquals(
1121                         "ARP application test 8: ARP not applied as expected.",
1122                         new HashSet(Arrays.asList(releaseAttributes)),
1123                         new HashSet(Arrays.asList(new ArpAttribute[] { filteredAttribute })));
1124         }
1125
1126         /**
1127          * ARPs: A site ARP only
1128          * Target: Any
1129          * Attribute: Any value deny
1130          */
1131         void arpApplicationTest9(ArpRepository repository, Properties props, DOMParser parser)
1132                 throws Exception {
1133
1134                 //Gather the Input
1135                 String rawArp =
1136                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1137                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1138                                 + "                     <Rule>"
1139                                 + "                             <Target>"
1140                                 + "                                     <AnyTarget/>"
1141                                 + "                             </Target>"
1142                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1143                                 + "                                     <AnyValue release=\"deny\"/>"
1144                                 + "                             </Attribute>"
1145                                 + "                     </Rule>"
1146                                 + "     </AttributeReleasePolicy>";
1147
1148                 Principal principal1 = new AAPrincipal("TestPrincipal");
1149                 URL url1 = new URL("http://www.example.edu/");
1150                 TestAttribute testAttribute =
1151                         new TestAttribute(
1152                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1153                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1154
1155                 //Setup the engine
1156                 parser.parse(new InputSource(new StringReader(rawArp)));
1157                 Arp siteArp = new Arp();
1158                 siteArp.marshall(parser.getDocument().getDocumentElement());
1159                 repository.update(siteArp);
1160                 ArpEngine engine = new ArpEngine(repository, props);
1161
1162                 //Apply the ARP
1163                 ArpAttribute[] releaseAttributes =
1164                         engine.filterAttributes(
1165                                 new ArpAttribute[] { testAttribute },
1166                                 principal1,
1167                                 "shar.example.edu",
1168                                 url1);
1169
1170                 assertEquals(
1171                         "ARP application test 9: ARP not applied as expected.",
1172                         new HashSet(Arrays.asList(releaseAttributes)),
1173                         new HashSet(Arrays.asList(new ArpAttribute[0])));
1174         }
1175
1176         /**
1177          * ARPs: A site ARP only
1178          * Target: Any
1179          * Attribute: Any value deny trumps explicit permit expanded representation
1180          */
1181         void arpApplicationTest10(ArpRepository repository, Properties props, DOMParser parser)
1182                 throws Exception {
1183
1184                 //Gather the Input
1185                 String rawArp =
1186                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1187                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1188                                 + "                     <Rule>"
1189                                 + "                             <Target>"
1190                                 + "                                     <AnyTarget/>"
1191                                 + "                             </Target>"
1192                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1193                                 + "                                     <AnyValue release=\"deny\"/>"
1194                                 + "                             </Attribute>"
1195                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1196                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
1197                                 + "                             </Attribute>"
1198                                 + "                     </Rule>"
1199                                 + "     </AttributeReleasePolicy>";
1200
1201                 Principal principal1 = new AAPrincipal("TestPrincipal");
1202                 URL url1 = new URL("http://www.example.edu/");
1203                 TestAttribute testAttribute =
1204                         new TestAttribute(
1205                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1206                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1207
1208                 //Setup the engine
1209                 parser.parse(new InputSource(new StringReader(rawArp)));
1210                 Arp siteArp = new Arp();
1211                 siteArp.marshall(parser.getDocument().getDocumentElement());
1212                 repository.update(siteArp);
1213                 ArpEngine engine = new ArpEngine(repository, props);
1214
1215                 //Apply the ARP
1216                 ArpAttribute[] releaseAttributes =
1217                         engine.filterAttributes(
1218                                 new ArpAttribute[] { testAttribute },
1219                                 principal1,
1220                                 "shar.example.edu",
1221                                 url1);
1222
1223                 assertEquals(
1224                         "ARP application test 10: ARP not applied as expected.",
1225                         new HashSet(Arrays.asList(releaseAttributes)),
1226                         new HashSet(Arrays.asList(new ArpAttribute[0])));
1227         }
1228
1229         /**
1230          * ARPs: A site ARP only
1231          * Target: Any
1232          * Attribute: Any value deny trumps explicit permit canonical representation
1233          */
1234         void arpApplicationTest11(ArpRepository repository, Properties props, DOMParser parser)
1235                 throws Exception {
1236
1237                 //Gather the Input
1238                 String rawArp =
1239                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1240                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1241                                 + "                     <Rule>"
1242                                 + "                             <Target>"
1243                                 + "                                     <AnyTarget/>"
1244                                 + "                             </Target>"
1245                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1246                                 + "                                     <AnyValue release=\"deny\"/>"
1247                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
1248                                 + "                             </Attribute>"
1249                                 + "                     </Rule>"
1250                                 + "     </AttributeReleasePolicy>";
1251
1252                 Principal principal1 = new AAPrincipal("TestPrincipal");
1253                 URL url1 = new URL("http://www.example.edu/");
1254                 TestAttribute testAttribute =
1255                         new TestAttribute(
1256                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1257                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1258
1259                 //Setup the engine
1260                 parser.parse(new InputSource(new StringReader(rawArp)));
1261                 Arp siteArp = new Arp();
1262                 siteArp.marshall(parser.getDocument().getDocumentElement());
1263                 repository.update(siteArp);
1264                 ArpEngine engine = new ArpEngine(repository, props);
1265
1266                 //Apply the ARP
1267                 ArpAttribute[] releaseAttributes =
1268                         engine.filterAttributes(
1269                                 new ArpAttribute[] { testAttribute },
1270                                 principal1,
1271                                 "shar.example.edu",
1272                                 url1);
1273
1274                 assertEquals(
1275                         "ARP application test 11: ARP not applied as expected.",
1276                         new HashSet(Arrays.asList(releaseAttributes)),
1277                         new HashSet(Arrays.asList(new ArpAttribute[0])));
1278         }
1279
1280         /**
1281          * ARPs: A site ARP only
1282          * Target: Specific shar, Any Resource
1283          * Attribute: Any value release
1284          */
1285         void arpApplicationTest12(ArpRepository repository, Properties props, DOMParser parser)
1286                 throws Exception {
1287
1288                 //Gather the Input
1289                 String rawArp =
1290                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1291                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1292                                 + "                     <Rule>"
1293                                 + "                             <Target>"
1294                                 + "                                     <Requester>shar.example.edu</Requester>"
1295                                 + "                                     <AnyResource />"
1296                                 + "                             </Target>"
1297                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1298                                 + "                                     <AnyValue release=\"permit\"/>"
1299                                 + "                             </Attribute>"
1300                                 + "                     </Rule>"
1301                                 + "     </AttributeReleasePolicy>";
1302
1303                 Principal principal1 = new AAPrincipal("TestPrincipal");
1304                 URL url1 = new URL("http://www.example.edu/");
1305                 TestAttribute testAttribute =
1306                         new TestAttribute(
1307                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1308                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1309
1310                 //Setup the engine
1311                 parser.parse(new InputSource(new StringReader(rawArp)));
1312                 Arp siteArp = new Arp();
1313                 siteArp.marshall(parser.getDocument().getDocumentElement());
1314                 repository.update(siteArp);
1315                 ArpEngine engine = new ArpEngine(repository, props);
1316
1317                 //Apply the ARP
1318                 ArpAttribute[] releaseAttributes =
1319                         engine.filterAttributes(
1320                                 new ArpAttribute[] { testAttribute },
1321                                 principal1,
1322                                 "shar.example.edu",
1323                                 url1);
1324
1325                 assertEquals(
1326                         "ARP application test 12: ARP not applied as expected.",
1327                         new HashSet(Arrays.asList(releaseAttributes)),
1328                         new HashSet(Arrays.asList(new ArpAttribute[] { testAttribute })));
1329         }
1330
1331         /**
1332          * ARPs: A site ARP only
1333          * Target: Specific shar, Any Resource (another example)
1334          * Attribute: Any value release
1335          */
1336         void arpApplicationTest13(ArpRepository repository, Properties props, DOMParser parser)
1337                 throws Exception {
1338
1339                 //Gather the Input
1340                 String rawArp =
1341                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1342                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1343                                 + "                     <Rule>"
1344                                 + "                             <Target>"
1345                                 + "                                     <Requester>shar.example.edu</Requester>"
1346                                 + "                                     <AnyResource />"
1347                                 + "                             </Target>"
1348                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1349                                 + "                                     <AnyValue release=\"permit\"/>"
1350                                 + "                             </Attribute>"
1351                                 + "                     </Rule>"
1352                                 + "     </AttributeReleasePolicy>";
1353
1354                 Principal principal1 = new AAPrincipal("TestPrincipal");
1355                 URL url1 = new URL("https://foo.com/");
1356                 TestAttribute testAttribute =
1357                         new TestAttribute(
1358                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1359                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1360
1361                 //Setup the engine
1362                 parser.parse(new InputSource(new StringReader(rawArp)));
1363                 Arp siteArp = new Arp();
1364                 siteArp.marshall(parser.getDocument().getDocumentElement());
1365                 repository.update(siteArp);
1366                 ArpEngine engine = new ArpEngine(repository, props);
1367
1368                 //Apply the ARP
1369                 ArpAttribute[] releaseAttributes =
1370                         engine.filterAttributes(
1371                                 new ArpAttribute[] { testAttribute },
1372                                 principal1,
1373                                 "shar.example.edu",
1374                                 url1);
1375
1376                 assertEquals(
1377                         "ARP application test 13: ARP not applied as expected.",
1378                         new HashSet(Arrays.asList(releaseAttributes)),
1379                         new HashSet(Arrays.asList(new ArpAttribute[] { testAttribute })));
1380         }
1381
1382         /**
1383          * ARPs: A site ARP only
1384          * Target: Specific shar (no match), Any Resource
1385          * Attribute: Any value release
1386          */
1387         void arpApplicationTest14(ArpRepository repository, Properties props, DOMParser parser)
1388                 throws Exception {
1389
1390                 //Gather the Input
1391                 String rawArp =
1392                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1393                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1394                                 + "                     <Rule>"
1395                                 + "                             <Target>"
1396                                 + "                                     <Requester>shar.example.edu</Requester>"
1397                                 + "                                     <AnyResource />"
1398                                 + "                             </Target>"
1399                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1400                                 + "                                     <AnyValue release=\"permit\"/>"
1401                                 + "                             </Attribute>"
1402                                 + "                     </Rule>"
1403                                 + "     </AttributeReleasePolicy>";
1404
1405                 Principal principal1 = new AAPrincipal("TestPrincipal");
1406                 URL url1 = new URL("http://www.example.edu/");
1407                 TestAttribute testAttribute =
1408                         new TestAttribute(
1409                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1410                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1411
1412                 //Setup the engine
1413                 parser.parse(new InputSource(new StringReader(rawArp)));
1414                 Arp siteArp = new Arp();
1415                 siteArp.marshall(parser.getDocument().getDocumentElement());
1416                 repository.update(siteArp);
1417                 ArpEngine engine = new ArpEngine(repository, props);
1418
1419                 //Apply the ARP
1420                 ArpAttribute[] releaseAttributes =
1421                         engine.filterAttributes(
1422                                 new ArpAttribute[] { testAttribute },
1423                                 principal1,
1424                                 "www.example.edu",
1425                                 url1);
1426
1427                 assertEquals(
1428                         "ARP application test 14: ARP not applied as expected.",
1429                         new HashSet(Arrays.asList(releaseAttributes)),
1430                         new HashSet(Arrays.asList(new ArpAttribute[0])));
1431         }
1432
1433         /**
1434          * ARPs: A site ARP only
1435          * Target: Specific shar, Specific resource
1436          * Attribute: Any value release
1437          */
1438         void arpApplicationTest15(ArpRepository repository, Properties props, DOMParser parser)
1439                 throws Exception {
1440
1441                 //Gather the Input
1442                 String rawArp =
1443                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1444                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1445                                 + "                     <Rule>"
1446                                 + "                             <Target>"
1447                                 + "                                     <Requester>shar.example.edu</Requester>"
1448                                 + "                                     <Resource>http://www.example.edu/</Resource>"
1449                                 + "                             </Target>"
1450                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1451                                 + "                                     <AnyValue release=\"permit\"/>"
1452                                 + "                             </Attribute>"
1453                                 + "                     </Rule>"
1454                                 + "     </AttributeReleasePolicy>";
1455
1456                 Principal principal1 = new AAPrincipal("TestPrincipal");
1457                 URL url1 = new URL("http://www.example.edu/index.html");
1458                 TestAttribute testAttribute =
1459                         new TestAttribute(
1460                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1461                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1462
1463                 //Setup the engine
1464                 parser.parse(new InputSource(new StringReader(rawArp)));
1465                 Arp siteArp = new Arp();
1466                 siteArp.marshall(parser.getDocument().getDocumentElement());
1467                 repository.update(siteArp);
1468                 ArpEngine engine = new ArpEngine(repository, props);
1469
1470                 //Apply the ARP
1471                 ArpAttribute[] releaseAttributes =
1472                         engine.filterAttributes(
1473                                 new ArpAttribute[] { testAttribute },
1474                                 principal1,
1475                                 "shar.example.edu",
1476                                 url1);
1477
1478                 assertEquals(
1479                         "ARP application test 15: ARP not applied as expected.",
1480                         new HashSet(Arrays.asList(releaseAttributes)),
1481                         new HashSet(Arrays.asList(new ArpAttribute[] { testAttribute })));
1482         }
1483
1484         /**
1485          * ARPs: A site ARP only
1486          * Target: Specific shar, Specific resource (no match)
1487          * Attribute: Any value release
1488          */
1489         void arpApplicationTest16(ArpRepository repository, Properties props, DOMParser parser)
1490                 throws Exception {
1491
1492                 //Gather the Input
1493                 String rawArp =
1494                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1495                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1496                                 + "                     <Rule>"
1497                                 + "                             <Target>"
1498                                 + "                                     <Requester>shar.example.edu</Requester>"
1499                                 + "                                     <Resource>http://www.example.edu/</Resource>"
1500                                 + "                             </Target>"
1501                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1502                                 + "                                     <AnyValue release=\"permit\"/>"
1503                                 + "                             </Attribute>"
1504                                 + "                     </Rule>"
1505                                 + "     </AttributeReleasePolicy>";
1506
1507                 Principal principal1 = new AAPrincipal("TestPrincipal");
1508                 URL url1 = new URL("https://www.example.edu/index.html");
1509                 TestAttribute testAttribute =
1510                         new TestAttribute(
1511                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1512                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1513
1514                 //Setup the engine
1515                 parser.parse(new InputSource(new StringReader(rawArp)));
1516                 Arp siteArp = new Arp();
1517                 siteArp.marshall(parser.getDocument().getDocumentElement());
1518                 repository.update(siteArp);
1519                 ArpEngine engine = new ArpEngine(repository, props);
1520
1521                 //Apply the ARP
1522                 ArpAttribute[] releaseAttributes =
1523                         engine.filterAttributes(
1524                                 new ArpAttribute[] { testAttribute },
1525                                 principal1,
1526                                 "shar.example.edu",
1527                                 url1);
1528
1529                 assertEquals(
1530                         "ARP application test 16: ARP not applied as expected.",
1531                         new HashSet(Arrays.asList(releaseAttributes)),
1532                         new HashSet(Arrays.asList(new ArpAttribute[0])));
1533         }
1534
1535         /**
1536          * ARPs: A site ARP only
1537          * Target: Multiple matching rules
1538          * Attribute: various
1539          */
1540         void arpApplicationTest17(ArpRepository repository, Properties props, DOMParser parser)
1541                 throws Exception {
1542
1543                 //Gather the Input
1544                 String rawArp =
1545                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1546                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1547                                 + "                     <Rule>"
1548                                 + "                             <Target>"
1549                                 + "                                     <AnyTarget />"
1550                                 + "                             </Target>"
1551                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1552                                 + "                                     <AnyValue release=\"permit\"/>"
1553                                 + "                             </Attribute>"
1554                                 + "                     </Rule>"
1555                                 + "                     <Rule>"
1556                                 + "                             <Target>"
1557                                 + "                                     <Requester>shar1.example.edu</Requester>"
1558                                 + "                                     <AnyResource />"
1559                                 + "                             </Target>"
1560                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1561                                 + "                                     <Value release=\"deny\">faculty@example.edu</Value>"
1562                                 + "                             </Attribute>"
1563                                 + "                     </Rule>"
1564                                 + "                     <Rule>"
1565                                 + "                             <Target>"
1566                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">shar[1-9]\\.example\\.edu</Requester>"
1567                                 + "                                     <Resource matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">^https?://.+\\.example\\.edu/.*$</Resource>"
1568                                 + "                             </Target>"
1569                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonPrincipalName\">"
1570                                 + "                                     <AnyValue release=\"permit\"/>"
1571                                 + "                             </Attribute>"
1572                                 + "                     </Rule>"
1573                                 + "     </AttributeReleasePolicy>";
1574
1575                 Principal principal1 = new AAPrincipal("TestPrincipal");
1576                 URL url1 = new URL("https://www.example.edu/index.html");
1577                 TestAttribute testAttribute1 =
1578                         new TestAttribute(
1579                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1580                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1581                 TestAttribute testAttribute2 =
1582                         new TestAttribute(
1583                                 "urn:mace:eduPerson:1.0:eduPersonPrincipalName",
1584                                 new Object[] { "wassa@columbia.edu" });
1585                 TestAttribute filteredAttribute1 =
1586                         new TestAttribute(
1587                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1588                                 new Object[] { "member@example.edu" });
1589
1590                 //Setup the engine
1591                 parser.parse(new InputSource(new StringReader(rawArp)));
1592                 Arp siteArp = new Arp();
1593                 siteArp.marshall(parser.getDocument().getDocumentElement());
1594                 repository.update(siteArp);
1595                 ArpEngine engine = new ArpEngine(repository, props);
1596
1597                 //Apply the ARP
1598                 ArpAttribute[] releaseAttributes =
1599                         engine.filterAttributes(
1600                                 new ArpAttribute[] { testAttribute1, testAttribute2 },
1601                                 principal1,
1602                                 "shar1.example.edu",
1603                                 url1);
1604
1605                 assertEquals(
1606                         "ARP application test 17: ARP not applied as expected.",
1607                         new HashSet(Arrays.asList(releaseAttributes)),
1608                         new HashSet(Arrays.asList(new ArpAttribute[] { testAttribute2, filteredAttribute1 })));
1609         }
1610
1611         /**
1612          * ARPs: A site ARP only
1613          * Target: Any
1614          * Attribute: Any value release of two attributes in one rule
1615          */
1616         void arpApplicationTest18(ArpRepository repository, Properties props, DOMParser parser)
1617                 throws Exception {
1618
1619                 //Gather the Input
1620                 String rawArp =
1621                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1622                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1623                                 + "                     <Rule>"
1624                                 + "                             <Target>"
1625                                 + "                                     <AnyTarget/>"
1626                                 + "                             </Target>"
1627                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1628                                 + "                                     <AnyValue release=\"permit\"/>"
1629                                 + "                             </Attribute>"
1630                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonPrincipalName\">"
1631                                 + "                                     <AnyValue release=\"permit\"/>"
1632                                 + "                             </Attribute>"
1633                                 + "                     </Rule>"
1634                                 + "     </AttributeReleasePolicy>";
1635
1636                 Principal principal1 = new AAPrincipal("TestPrincipal");
1637                 URL url1 = new URL("http://www.example.edu/");
1638                 TestAttribute testAttribute1 =
1639                         new TestAttribute(
1640                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1641                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1642                 TestAttribute testAttribute2 =
1643                         new TestAttribute(
1644                                 "urn:mace:eduPerson:1.0:eduPersonPrincipalName",
1645                                 new Object[] { "mehoehn@example.edu" });
1646
1647                 //Setup the engine
1648                 parser.parse(new InputSource(new StringReader(rawArp)));
1649                 Arp siteArp = new Arp();
1650                 siteArp.marshall(parser.getDocument().getDocumentElement());
1651                 repository.update(siteArp);
1652                 ArpEngine engine = new ArpEngine(repository, props);
1653
1654                 //Apply the ARP
1655                 ArpAttribute[] releaseAttributes =
1656                         engine.filterAttributes(
1657                                 new ArpAttribute[] { testAttribute1, testAttribute2 },
1658                                 principal1,
1659                                 "shar.example.edu",
1660                                 url1);
1661
1662                 assertEquals(
1663                         "ARP application test 18: ARP not applied as expected.",
1664                         new HashSet(Arrays.asList(releaseAttributes)),
1665                         new HashSet(Arrays.asList(new ArpAttribute[] { testAttribute1, testAttribute2 })));
1666         }
1667
1668         /**
1669          * ARPs: A user ARP only
1670          * Target: Any
1671          * Attribute: Any value release,
1672          */
1673         void arpApplicationTest19(ArpRepository repository, Properties props, DOMParser parser)
1674                 throws Exception {
1675
1676                 //Gather the Input
1677                 String rawArp =
1678                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1679                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1680                                 + "                     <Rule>"
1681                                 + "                             <Target>"
1682                                 + "                                     <AnyTarget/>"
1683                                 + "                             </Target>"
1684                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1685                                 + "                                     <AnyValue release=\"permit\"/>"
1686                                 + "                             </Attribute>"
1687                                 + "                     </Rule>"
1688                                 + "     </AttributeReleasePolicy>";
1689
1690                 Principal principal1 = new AAPrincipal("TestPrincipal");
1691                 URL url1 = new URL("http://www.example.edu/");
1692                 TestAttribute testAttribute =
1693                         new TestAttribute(
1694                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1695                                 new Object[] { "member@example.edu", "faculty@example.edu" });
1696
1697                 //Setup the engine
1698                 parser.parse(new InputSource(new StringReader(rawArp)));
1699                 Arp userArp = new Arp();
1700                 userArp.setPrincipal(principal1);
1701                 userArp.marshall(parser.getDocument().getDocumentElement());
1702                 repository.update(userArp);
1703                 ArpEngine engine = new ArpEngine(repository, props);
1704
1705                 //Apply the ARP
1706                 ArpAttribute[] releaseAttributes =
1707                         engine.filterAttributes(
1708                                 new ArpAttribute[] { testAttribute },
1709                                 principal1,
1710                                 "shar.example.edu",
1711                                 url1);
1712
1713                 assertEquals(
1714                         "ARP application test 19: ARP not applied as expected.",
1715                         new HashSet(Arrays.asList(releaseAttributes)),
1716                         new HashSet(Arrays.asList(new ArpAttribute[] { testAttribute })));
1717         }
1718
1719         /**
1720          * ARPs: A site ARP and user ARP
1721          * Target: various
1722          * Attribute: various combinations
1723          */
1724         void arpApplicationTest20(ArpRepository repository, Properties props, DOMParser parser)
1725                 throws Exception {
1726
1727                 //Gather the Input
1728                 String rawSiteArp =
1729                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1730                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1731                                 + "                     <Rule>"
1732                                 + "                             <Target>"
1733                                 + "                                     <AnyTarget/>"
1734                                 + "                             </Target>"
1735                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1736                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
1737                                 + "                             </Attribute>"
1738                                 + "                             <Attribute name=\"urn:mace:inetOrgPerson:preferredLanguage\">"
1739                                 + "                                     <AnyValue release=\"permit\" />"
1740                                 + "                             </Attribute>"
1741                                 + "                     </Rule>"
1742                                 + "                     <Rule>"
1743                                 + "                             <Target>"
1744                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">.*\\.example\\.edu</Requester>"
1745                                 + "                                     <AnyResource />"
1746                                 + "                             </Target>"
1747                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonPrincipalName\">"
1748                                 + "                                     <AnyValue release=\"permit\"/>"
1749                                 + "                             </Attribute>"
1750                                 + "                     </Rule>"
1751                                 + "                     <Rule>"
1752                                 + "                             <Target>"
1753                                 + "                                     <Requester>www.example.edu</Requester>"
1754                                 + "                                     <Resource>http://www.example.edu/</Resource>"
1755                                 + "                             </Target>"
1756                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1757                                 + "                                     <AnyValue release=\"permit\"/>"
1758                                 + "                             </Attribute>"
1759                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonEntitlement\">"
1760                                 + "                                     <Value release=\"permit\">urn:example:contract:4657483</Value>"
1761                                 + "                             </Attribute>"
1762                                 + "                     </Rule>"
1763                                 + "                     <Rule>"
1764                                 + "                             <Target>"
1765                                 + "                                     <Requester>www.external.com</Requester>"
1766                                 + "                                     <Resource>http://www.external.com/</Resource>"
1767                                 + "                             </Target>"
1768                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonEntitlement\">"
1769                                 + "                                     <Value release=\"permit\">urn:example:contract:113455</Value>"
1770                                 + "                             </Attribute>"
1771                                 + "                     </Rule>"
1772                                 + "     </AttributeReleasePolicy>";
1773
1774                 String rawUserArp =
1775                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1776                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1777                                 + "                     <Rule>"
1778                                 + "                             <Target>"
1779                                 + "                                     <AnyTarget/>"
1780                                 + "                             </Target>"
1781                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonEntitlement\">"
1782                                 + "                                     <Value release=\"deny\">urn:example:poorlyDressed</Value>"
1783                                 + "                             </Attribute>"
1784                                 + "                     </Rule>"
1785                                 + "                     <Rule>"
1786                                 + "                             <Target>"
1787                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">.*\\.example\\.edu</Requester>"
1788                                 + "                                     <AnyResource />"
1789                                 + "                             </Target>"
1790                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1791                                 + "                                     <Value release=\"deny\">faculty@example.edu</Value>"
1792                                 + "                             </Attribute>"
1793                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonEntitlement\">"
1794                                 + "                                     <Value release=\"permit\">urn:example:lovesIceCream</Value>"
1795                                 + "                             </Attribute>"
1796                                 + "                     </Rule>"
1797                                 + "     </AttributeReleasePolicy>";
1798
1799                 Principal principal1 = new AAPrincipal("TestPrincipal");
1800                 URL url1 = new URL("http://www.example.edu/test/index.html");
1801
1802                 TestAttribute entitlementInput =
1803                         new TestAttribute(
1804                                 "urn:mace:eduPerson:1.0:eduPersonEntitlement",
1805                                 new Object[] {
1806                                         "urn:example:lovesIceCream",
1807                                         "urn:example:poorlyDressed",
1808                                         "urn:example:contract:113455",
1809                                         "urn:example:contract:4657483" });
1810
1811                 TestAttribute affiliationInput =
1812                         new TestAttribute(
1813                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1814                                 new Object[] {
1815                                         "member@example.edu",
1816                                         "faculty@example.edu",
1817                                         "employee@example.edu" });
1818
1819                 TestAttribute principalNameInput =
1820                         new TestAttribute(
1821                                 "urn:mace:eduPerson:1.0:eduPersonPrincipalName",
1822                                 new Object[] { "wassa@example.edu" });
1823
1824                 TestAttribute preferredLanguageInput =
1825                         new TestAttribute("urn:mace:inetOrgPerson:preferredLanguage", new Object[] { "EO" });
1826
1827                 TestAttribute entitlementOutput =
1828                         new TestAttribute(
1829                                 "urn:mace:eduPerson:1.0:eduPersonEntitlement",
1830                                 new Object[] { "urn:example:lovesIceCream", "urn:example:contract:4657483" });
1831
1832                 TestAttribute affiliationOutput =
1833                         new TestAttribute(
1834                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1835                                 new Object[] { "member@example.edu", "employee@example.edu" });
1836
1837                 //Add the site ARP
1838                 parser.parse(new InputSource(new StringReader(rawSiteArp)));
1839                 Arp siteArp = new Arp();
1840                 siteArp.marshall(parser.getDocument().getDocumentElement());
1841                 repository.update(siteArp);
1842
1843                 //Add the user ARP
1844                 parser.parse(new InputSource(new StringReader(rawUserArp)));
1845                 Arp userArp = new Arp();
1846                 userArp.setPrincipal(principal1);
1847                 userArp.marshall(parser.getDocument().getDocumentElement());
1848                 repository.update(userArp);
1849
1850                 ArpEngine engine = new ArpEngine(repository, props);
1851
1852                 //Apply the ARP
1853                 ArpAttribute[] releaseAttributes =
1854                         engine.filterAttributes(
1855                                 new ArpAttribute[] {
1856                                         entitlementInput,
1857                                         affiliationInput,
1858                                         principalNameInput,
1859                                         preferredLanguageInput },
1860                                 principal1,
1861                                 "www.example.edu",
1862                                 url1);
1863
1864                 assertEquals(
1865                         "ARP application test 20: ARP not applied as expected.",
1866                         new HashSet(Arrays.asList(releaseAttributes)),
1867                         new HashSet(
1868                                 Arrays.asList(
1869                                         new ArpAttribute[] {
1870                                                 entitlementOutput,
1871                                                 affiliationOutput,
1872                                                 principalNameInput,
1873                                                 preferredLanguageInput })));
1874         }
1875
1876         /**
1877          * ARPs: A site ARP and user ARP
1878          * Target: various
1879          * Attribute: various combinations (same ARPs as 20, different requester)
1880          */
1881         void arpApplicationTest21(ArpRepository repository, Properties props, DOMParser parser)
1882                 throws Exception {
1883
1884                 //Gather the Input
1885                 String rawSiteArp =
1886                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1887                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1888                                 + "                     <Rule>"
1889                                 + "                             <Target>"
1890                                 + "                                     <AnyTarget/>"
1891                                 + "                             </Target>"
1892                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1893                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
1894                                 + "                             </Attribute>"
1895                                 + "                             <Attribute name=\"urn:mace:inetOrgPerson:preferredLanguage\">"
1896                                 + "                                     <AnyValue release=\"permit\" />"
1897                                 + "                             </Attribute>"
1898                                 + "                     </Rule>"
1899                                 + "                     <Rule>"
1900                                 + "                             <Target>"
1901                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">.*\\.example\\.edu</Requester>"
1902                                 + "                                     <AnyResource />"
1903                                 + "                             </Target>"
1904                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonPrincipalName\">"
1905                                 + "                                     <AnyValue release=\"permit\"/>"
1906                                 + "                             </Attribute>"
1907                                 + "                     </Rule>"
1908                                 + "                     <Rule>"
1909                                 + "                             <Target>"
1910                                 + "                                     <Requester>www.example.edu</Requester>"
1911                                 + "                                     <Resource>http://www.example.edu/</Resource>"
1912                                 + "                             </Target>"
1913                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1914                                 + "                                     <AnyValue release=\"permit\"/>"
1915                                 + "                             </Attribute>"
1916                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonEntitlement\">"
1917                                 + "                                     <Value release=\"permit\">urn:example:contract:4657483</Value>"
1918                                 + "                             </Attribute>"
1919                                 + "                     </Rule>"
1920                                 + "                     <Rule>"
1921                                 + "                             <Target>"
1922                                 + "                                     <Requester>www.external.com</Requester>"
1923                                 + "                                     <Resource>http://www.external.com/</Resource>"
1924                                 + "                             </Target>"
1925                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonEntitlement\">"
1926                                 + "                                     <Value release=\"permit\">urn:example:contract:113455</Value>"
1927                                 + "                             </Attribute>"
1928                                 + "                     </Rule>"
1929                                 + "     </AttributeReleasePolicy>";
1930
1931                 String rawUserArp =
1932                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1933                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
1934                                 + "                     <Rule>"
1935                                 + "                             <Target>"
1936                                 + "                                     <AnyTarget/>"
1937                                 + "                             </Target>"
1938                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonEntitlement\">"
1939                                 + "                                     <Value release=\"deny\">urn:example:poorlyDressed</Value>"
1940                                 + "                             </Attribute>"
1941                                 + "                     </Rule>"
1942                                 + "                     <Rule>"
1943                                 + "                             <Target>"
1944                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">.*\\.example\\.edu</Requester>"
1945                                 + "                                     <AnyResource />"
1946                                 + "                             </Target>"
1947                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonAffiliation\">"
1948                                 + "                                     <Value release=\"deny\">faculty@example.edu</Value>"
1949                                 + "                             </Attribute>"
1950                                 + "                             <Attribute name=\"urn:mace:eduPerson:1.0:eduPersonEntitlement\">"
1951                                 + "                                     <Value release=\"permit\">urn:example:lovesIceCream</Value>"
1952                                 + "                             </Attribute>"
1953                                 + "                     </Rule>"
1954                                 + "     </AttributeReleasePolicy>";
1955
1956                 Principal principal1 = new AAPrincipal("TestPrincipal");
1957                 URL url1 = new URL("http://www.external.com/");
1958
1959                 TestAttribute entitlementInput =
1960                         new TestAttribute(
1961                                 "urn:mace:eduPerson:1.0:eduPersonEntitlement",
1962                                 new Object[] {
1963                                         "urn:example:lovesIceCream",
1964                                         "urn:example:poorlyDressed",
1965                                         "urn:example:contract:113455",
1966                                         "urn:example:contract:4657483" });
1967
1968                 TestAttribute affiliationInput =
1969                         new TestAttribute(
1970                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1971                                 new Object[] {
1972                                         "member@example.edu",
1973                                         "faculty@example.edu",
1974                                         "employee@example.edu" });
1975
1976                 TestAttribute principalNameInput =
1977                         new TestAttribute(
1978                                 "urn:mace:eduPerson:1.0:eduPersonPrincipalName",
1979                                 new Object[] { "wassa@example.edu" });
1980
1981                 TestAttribute preferredLanguageInput =
1982                         new TestAttribute("urn:mace:inetOrgPerson:preferredLanguage", new Object[] { "EO" });
1983
1984                 TestAttribute entitlementOutput =
1985                         new TestAttribute(
1986                                 "urn:mace:eduPerson:1.0:eduPersonEntitlement",
1987                                 new Object[] { "urn:example:contract:113455" });
1988
1989                 TestAttribute affiliationOutput =
1990                         new TestAttribute(
1991                                 "urn:mace:eduPerson:1.0:eduPersonAffiliation",
1992                                 new Object[] { "member@example.edu" });
1993
1994                 //Add the site ARP
1995                 parser.parse(new InputSource(new StringReader(rawSiteArp)));
1996                 Arp siteArp = new Arp();
1997                 siteArp.marshall(parser.getDocument().getDocumentElement());
1998                 repository.update(siteArp);
1999
2000                 //Add the user ARP
2001                 parser.parse(new InputSource(new StringReader(rawUserArp)));
2002                 Arp userArp = new Arp();
2003                 userArp.setPrincipal(principal1);
2004                 userArp.marshall(parser.getDocument().getDocumentElement());
2005                 repository.update(userArp);
2006
2007                 ArpEngine engine = new ArpEngine(repository, props);
2008
2009                 //Apply the ARP
2010                 ArpAttribute[] releaseAttributes =
2011                         engine.filterAttributes(
2012                                 new ArpAttribute[] {
2013                                         entitlementInput,
2014                                         affiliationInput,
2015                                         principalNameInput,
2016                                         preferredLanguageInput },
2017                                 principal1,
2018                                 "www.external.com",
2019                                 url1);
2020
2021                 assertEquals(
2022                         "ARP application test 21: ARP not applied as expected.",
2023                         new HashSet(Arrays.asList(releaseAttributes)),
2024                         new HashSet(
2025                                 Arrays.asList(
2026                                         new ArpAttribute[] {
2027                                                 entitlementOutput,
2028                                                 affiliationOutput,
2029                                                 preferredLanguageInput })));
2030         }
2031
2032         public class TestAttribute implements ArpAttribute {
2033                 private String name;
2034                 private Object[] values;
2035
2036                 public TestAttribute(String name, Object[] values) {
2037                         this.name = name;
2038                         this.values = values;
2039                 }
2040
2041                 /**
2042                  * @see edu.internet2.middleware.shibboleth.aa.arp.ArpAttribute#getName()
2043                  */
2044                 public String getName() {
2045                         return name;
2046                 }
2047
2048                 /**
2049                  * @see edu.internet2.middleware.shibboleth.aa.arp.ArpAttribute#getValues()
2050                  */
2051                 public Object[] getValues() {
2052                         return values;
2053                 }
2054
2055                 /**
2056                  * @see edu.internet2.middleware.shibboleth.aa.arp.ArpAttribute#setValues(Object[])
2057                  */
2058                 public void setValues(Object[] values) {
2059                         this.values = values;
2060                 }
2061
2062                 /**
2063                  * @see java.lang.Object#equals(Object)
2064                  */
2065                 public boolean equals(Object object) {
2066                         if (!(object instanceof TestAttribute)) {
2067                                 return false;
2068                         }
2069                         return (new HashSet(Arrays.asList(values))).equals(
2070                                 new HashSet(Arrays.asList(((TestAttribute) object).getValues())));
2071                 }
2072
2073                 /**
2074                 * @see java.lang.Object#hashCode()
2075                 */
2076                 public int hashCode() {
2077                         int code = 0;
2078                         for (int i = 0; i < values.length; i++) {
2079                                 code += values[i].hashCode();
2080                         }
2081                         return name.hashCode() + code;
2082                 }
2083
2084         }
2085
2086 }