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