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