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