d6becac3fcb211dd25aefe8b42f0b278ae80463b
[java-idp.git] / tests / edu / internet2 / middleware / shibboleth / aa / arp / ArpTests.java
1 /*
2  * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package edu.internet2.middleware.shibboleth.aa.arp;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.InputStream;
22 import java.io.StringReader;
23 import java.net.MalformedURLException;
24 import java.net.URI;
25 import java.net.URISyntaxException;
26 import java.net.URL;
27 import java.security.Principal;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.HashSet;
32 import java.util.Set;
33
34 import javax.xml.parsers.DocumentBuilderFactory;
35 import javax.xml.parsers.ParserConfigurationException;
36
37 import junit.framework.TestCase;
38
39 import org.apache.log4j.BasicConfigurator;
40 import org.apache.log4j.Level;
41 import org.apache.log4j.Logger;
42 import org.w3c.dom.Document;
43 import org.w3c.dom.Element;
44 import org.w3c.dom.Text;
45 import org.xml.sax.InputSource;
46
47 import edu.internet2.middleware.shibboleth.aa.AAAttribute;
48 import edu.internet2.middleware.shibboleth.common.LocalPrincipal;
49 import edu.internet2.middleware.shibboleth.idp.IdPConfig;
50 import edu.internet2.middleware.shibboleth.xml.Parser;
51
52 /**
53  * Validation suite for <code>Arp</code> processing.
54  * 
55  * @author Walter Hoehn(wassa@columbia.edu)
56  */
57
58 public class ArpTests extends TestCase {
59
60         private Parser.DOMParser parser = new Parser.DOMParser(true);
61         Element memoryRepositoryElement;
62         private String[] arpExamples = {"data/example1.xml", "data/example2.xml", "data/example3.xml", "data/example4.xml",
63                         "data/example5.xml", "data/example6.xml", "data/example7.xml", "data/example8.xml", "data/example9.xml",
64                         "data/example10.xml", "data/example11.xml", "data/example12.xml"};
65
66         public ArpTests(String name) {
67
68                 super(name);
69                 BasicConfigurator.resetConfiguration();
70                 BasicConfigurator.configure();
71                 Logger.getRootLogger().setLevel(Level.OFF);
72         }
73
74         public static void main(String[] args) {
75
76                 junit.textui.TestRunner.run(ArpTests.class);
77                 BasicConfigurator.configure();
78                 Logger.getRootLogger().setLevel(Level.OFF);
79         }
80
81         /**
82          * @see junit.framework.TestCase#setUp()
83          */
84         protected void setUp() throws Exception {
85
86                 super.setUp();
87
88                 // Setup an xml parser
89
90                 // Setup a dummy xml config for a Memory-based repository
91                 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
92                 docFactory.setNamespaceAware(true);
93                 Document placeHolder;
94                 try {
95                         placeHolder = docFactory.newDocumentBuilder().newDocument();
96
97                         memoryRepositoryElement = placeHolder.createElementNS(IdPConfig.configNameSpace, "ArpRepository");
98                         memoryRepositoryElement.setAttributeNS(IdPConfig.configNameSpace, "implementation",
99                                         "edu.internet2.middleware.shibboleth.aa.arp.provider.MemoryArpRepository");
100                 } catch (ParserConfigurationException e) {
101                         fail("Failed to create memory-based Arp Repository configuration" + e);
102                 }
103         }
104
105         public void testArpMarshalling() {
106
107                 // Test ARP description
108                 try {
109                         InputStream inStream = new FileInputStream("data/arp1.xml");
110                         parser.parse(new InputSource(inStream));
111                         Arp arp1 = new Arp();
112                         arp1.marshall(parser.getDocument().getDocumentElement());
113                         assertEquals("ARP Description not marshalled properly", arp1.getDescription(), "Simplest possible ARP.");
114
115                         // Test Rule description
116                         assertEquals("ARP Rule Description not marshalled properly", arp1.getAllRules()[0].getDescription(),
117                                         "Example Rule Description.");
118                 } catch (Exception e) {
119                         fail("Failed to marshall ARP: " + e);
120                 }
121
122                 // Test case where ARP description does not exist
123                 try {
124                         InputStream inStream = new FileInputStream("data/arp2.xml");
125                         parser.parse(new InputSource(inStream));
126                         Arp arp2 = new Arp();
127                         arp2.marshall(parser.getDocument().getDocumentElement());
128                         assertNull("ARP Description not marshalled properly", arp2.getDescription());
129
130                         // Test case where ARP Rule description does not exist
131                         assertNull("ARP Rule Description not marshalled properly", arp2.getAllRules()[0].getDescription());
132                 } catch (Exception e) {
133                         fail("Failed to marshall ARP.");
134                 }
135
136         }
137
138         public void testMatchingFunctions() {
139
140                 try {
141
142                         /*
143                          * Test Arp Engine function retrieval
144                          */
145
146                         // Lookup a function that doesn't exist
147                         MatchFunction noFunction = ArpEngine.lookupMatchFunction(new URI(
148                                         "urn:mace:shibboleth:arp:matchFunction:dummy"));
149                         assertNull("ArpEngine did not return null on dummy function.", noFunction);
150
151                         // Lookup some real functions
152                         MatchFunction stringMatch = ArpEngine.lookupMatchFunction(new URI(
153                                         "urn:mace:shibboleth:arp:matchFunction:stringMatch"));
154                         assertNotNull("ArpEngine did not properly load the String Match function.", stringMatch);
155                         MatchFunction stringValue = ArpEngine.lookupMatchFunction(new URI(
156                                         "urn:mace:shibboleth:arp:matchFunction:stringValue"));
157                         assertNotNull("ArpEngine did not properly load the String Value function.", stringValue);
158                         MatchFunction exactSharFunction = ArpEngine.lookupMatchFunction(new URI(
159                                         "urn:mace:shibboleth:arp:matchFunction:exactShar"));
160                         assertNotNull("ArpEngine did not properly load the Exact SHAR function.", exactSharFunction);
161                         MatchFunction resourceTreeFunction = ArpEngine.lookupMatchFunction(new URI(
162                                         "urn:mace:shibboleth:arp:matchFunction:resourceTree"));
163                         assertNotNull("ArpEngine did not properly load the Resource Tree SHAR function.", resourceTreeFunction);
164                         MatchFunction regexFunction = ArpEngine.lookupMatchFunction(new URI(
165                                         "urn:mace:shibboleth:arp:matchFunction:regexMatch"));
166                         assertNotNull("ArpEngine did not properly load the Regex function.", regexFunction);
167                         MatchFunction regexNotFunction = ArpEngine.lookupMatchFunction(new URI(
168                                         "urn:mace:shibboleth:arp:matchFunction:regexNotMatch"));
169                         assertNotNull("ArpEngine did not properly load the Regex Not Match function.", regexNotFunction);
170                         MatchFunction stringNotFunction = ArpEngine.lookupMatchFunction(new URI(
171                                         "urn:mace:shibboleth:arp:matchFunction:stringNotMatch"));
172                         assertNotNull("ArpEngine did not properly load the String Not Match function.", stringNotFunction);
173
174                         /*
175                          * Test the Exact SHAR function (requester)
176                          */
177
178                         assertTrue("Exact SHAR function: false negative", exactSharFunction.match("shar.example.edu",
179                                         "shar.example.edu"));
180                         assertTrue("Exact SHAR function: false positive", !exactSharFunction.match("shar.example.edu",
181                                         "www.example.edu"));
182                         assertTrue("Exact SHAR function: false positive", !exactSharFunction.match("example.edu",
183                                         "shar.example.edu"));
184
185                         // Make sure we properly handle bad input
186                         try {
187                                 exactSharFunction.match(null, null);
188                                 fail("Exact SHAR function seems to take improper input without throwing an exception.");
189                         } catch (ArpException ie) {
190                                 // This is supposed to fail
191                         }
192
193                         /*
194                          * Test the Resource Tree function (resource)
195                          */
196
197                         URL requestURL1 = new URL("http://www.example.edu/test/");
198                         URL requestURL2 = new URL("http://www.example.edu/test/index.html");
199                         URL requestURL3 = new URL("http://www.example.edu/test2/index.html");
200                         URL requestURL4 = new URL("http://www.example.edu/test2/index.html?test1=test1");
201
202                         assertTrue("Resource Tree function: false negative", resourceTreeFunction.match("http://www.example.edu/",
203                                         requestURL1));
204                         assertTrue("Resource Tree function: false positive", !resourceTreeFunction.match(
205                                         "https://www.example.edu/", requestURL1));
206                         assertTrue("Resource Tree function: false negative", resourceTreeFunction.match(
207                                         "http://www.example.edu:80/", requestURL1));
208                         assertTrue("Resource Tree function: false positive", !resourceTreeFunction.match(
209                                         "http://www.example.edu:81/", requestURL1));
210                         assertTrue("Resource Tree function: false negative", resourceTreeFunction.match(
211                                         "http://www.example.edu/test/", requestURL1));
212                         assertTrue("Resource Tree function: false negative", resourceTreeFunction.match(
213                                         "http://www.example.edu/test/", requestURL2));
214                         assertTrue("Resource Tree function: false negative", resourceTreeFunction.match("http://www.example.edu/",
215                                         requestURL3));
216                         assertTrue("Resource Tree function: false positive", !resourceTreeFunction.match(
217                                         "http://www.example.edu/test/", requestURL3));
218                         assertTrue("Resource Tree function: false negative", resourceTreeFunction.match(
219                                         "http://www.example.edu/test2/index.html", requestURL3));
220                         assertTrue("Resource Tree function: false negative", resourceTreeFunction.match(
221                                         "http://www.example.edu/test2/index.html", requestURL4));
222                         assertTrue("Resource Tree function: false negative", resourceTreeFunction.match(
223                                         "http://www.example.edu/test2/index.html?test1=test1", requestURL4));
224                         assertTrue("Resource Tree function: false positive", !resourceTreeFunction.match(
225                                         "http://www.example.edu/test2/index.html?test1=test1", requestURL3));
226
227                         // Make sure we properly handle bad input
228                         try {
229                                 resourceTreeFunction.match(null, null);
230                                 fail("Resource Tree function seems to take improper input without throwing an exception.");
231                         } catch (ArpException ie) {
232                                 // This is supposed to fail
233                         }
234                         try {
235                                 resourceTreeFunction.match("Test", "Test");
236                                 fail("Resource Tree function seems to take improper input without throwing an exception.");
237                         } catch (ArpException ie) {
238                                 // This is supposed to fail
239                         }
240
241                         /*
242                          * Test the Regex function (requester & resource)
243                          */
244
245                         // Try requester regexes
246                         assertTrue("Regex function: false negative", regexFunction.match("^shar\\.example\\.edu$",
247                                         "shar.example.edu"));
248                         assertTrue("Regex function: false negative", regexFunction
249                                         .match("^.*\\.example\\.edu$", "shar.example.edu"));
250                         assertTrue("Regex function: false negative", regexFunction.match("^shar[1-9]?\\.example\\.edu$",
251                                         "shar1.example.edu"));
252                         assertTrue("Regex function: false negative", regexFunction.match(".*\\.edu", "shar.example.edu"));
253                         assertTrue("Regex function: false positive", !regexFunction.match("^shar[1-9]\\.example\\.edu$",
254                                         "shar.example.edu"));
255                         assertTrue("Regex function: false positive", !regexFunction.match("^shar\\.example\\.edu$",
256                                         "www.example.edu"));
257                         assertTrue("Regex function: false positive", !regexFunction.match("^shar\\.example\\.edu$",
258                                         "www.example.com"));
259
260                         // Try resource regexes
261                         assertTrue("Regex function: false negative", regexFunction.match("^http://www\\.example\\.edu/.*$",
262                                         requestURL1));
263                         assertTrue("Regex function: false negative", regexFunction.match("^http://www\\.example\\.edu/.*$",
264                                         requestURL2));
265                         assertTrue("Regex function: false negative", regexFunction.match("^http://.*\\.example\\.edu/.*$",
266                                         requestURL2));
267                         assertTrue("Regex function: false negative", regexFunction.match("^https?://.*\\.example\\.edu/.*$",
268                                         requestURL2));
269                         assertTrue("Regex function: false negative", regexFunction.match(".*", requestURL2));
270                         assertTrue("Regex function: false positive", !regexFunction.match("^https?://.*\\.example\\.edu/$",
271                                         requestURL2));
272                         assertTrue("Regex function: false positive", !regexFunction.match("^https?://www\\.example\\.edu/test/$",
273                                         requestURL3));
274
275                         // Make sure we properly handle bad input
276                         try {
277                                 regexFunction.match(null, null);
278                                 fail("Regex function seems to take improper input without throwing an exception.");
279                         } catch (ArpException ie) {
280                                 // This is supposed to fail
281                         }
282
283                         // Test the StringNotMatch function
284                         assertFalse("StringNotMatch function: false positive", stringNotFunction.match("foo", "foo"));
285                         assertTrue("StringNotMatch function: false negative", stringNotFunction.match("foo", "bar"));
286                         // Make sure we properly handle bad input
287                         try {
288                                 stringNotFunction.match(null, null);
289                                 fail("StringNotMatch function seems to take improper input without throwing an exception.");
290                         } catch (ArpException ie) {
291                                 // This is supposed to fail
292                         }
293
294                         // Test the RegexNotMatch function
295
296                         assertFalse("Regex function: false positive", regexNotFunction.match("^foo$", "foo"));
297                         assertTrue("Regex function: false negative", regexNotFunction.match("foo$", "bar"));
298
299                         // Make sure we properly handle bad input
300                         try {
301                                 regexNotFunction.match(null, null);
302                                 fail("RegexNotMatch function seems to take improper input without throwing an exception.");
303                         } catch (ArpException ie) {
304                                 // This is supposed to fail
305                         }
306
307                 } catch (ArpException e) {
308                         fail("Encountered a problem loading match function: " + e);
309                 } catch (URISyntaxException e) {
310                         fail("Unable to create URI from test string.");
311                 } catch (MalformedURLException e) {
312                         fail("Couldn't create test URLs: " + e);
313                 }
314
315         }
316
317         public void testRepositories() {
318
319                 /*
320                  * Test the Factory
321                  */
322
323                 // Make sure we fail if an unavailable Repository implementation is specified
324                 ArpRepository repository = null;
325
326                 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
327                 docFactory.setNamespaceAware(true);
328                 Document placeHolder;
329                 try {
330                         placeHolder = docFactory.newDocumentBuilder().newDocument();
331
332                         Element repositoryElement = placeHolder.createElementNS(IdPConfig.configNameSpace, "ArpRepository");
333                         repositoryElement.setAttributeNS(IdPConfig.configNameSpace, "implementation",
334                                         "edu.internet2.middleware.shibboleth.aa.arp.provider.Foo");
335
336                         ArpRepositoryFactory.getInstance(repositoryElement);
337
338                 } catch (ParserConfigurationException e) {
339                         fail("Failed to create bogus Arp Repository configuration" + e);
340
341                 } catch (ArpRepositoryException e) {
342                         // This is supposed to fail
343                 }
344
345                 // Make sure we can create an Arp Repository
346                 repository = null;
347                 try {
348                         repository = ArpRepositoryFactory.getInstance(memoryRepositoryElement);
349                 } catch (ArpRepositoryException e) {
350                         fail("Failed to create memory-based Arp Repository" + e);
351                 }
352                 assertNotNull("Failed to create memory-based Arp Repository: Factory returned null.", repository);
353
354                 /*
355                  * Exercise the Memory Arp Repository
356                  */
357
358                 // Set/retrieve/remove a Site ARP
359                 Arp siteArp1 = new Arp();
360                 siteArp1.setDescription("Test Site Arp 1.");
361                 try {
362                         repository.update(siteArp1);
363                         assertEquals("Memory Repository does not store and retrieve Site ARPs properly.", siteArp1, repository
364                                         .getSitePolicy());
365                         repository.remove(repository.getSitePolicy());
366                         assertNull("Memorty Repository does not properly delete Site ARPs.", repository.getSitePolicy());
367                 } catch (ArpRepositoryException e) {
368                         fail("Error adding Site ARP to Memory Repository.");
369                 }
370
371                 // Set/retrieve/delete some user ARPs
372                 Arp userArp1 = new Arp();
373                 userArp1.setDescription("Broken User Arp 1.");
374                 try {
375                         repository.update(userArp1);
376                         assertTrue("Memory Repository does not store and retrieve User ARPs properly.", (!userArp1
377                                         .equals(repository.getUserPolicy(userArp1.getPrincipal()))));
378                 } catch (ArpRepositoryException e) {
379                         fail("Error adding User ARP to Memory Repository.");
380                 }
381
382                 Arp userArp2 = new Arp(new LocalPrincipal("TestPrincipal"));
383                 userArp2.setDescription("Test User Arp 2.");
384                 try {
385                         repository.update(userArp2);
386                         assertEquals("Memory Repository does not store and retrieve User ARPs properly.", userArp2, repository
387                                         .getUserPolicy(userArp2.getPrincipal()));
388                         repository.remove(repository.getUserPolicy(userArp2.getPrincipal()));
389                         assertNull("Memorty Repository does not properly delete User ARPs.", repository.getUserPolicy(userArp2
390                                         .getPrincipal()));
391                 } catch (ArpRepositoryException e) {
392                         fail("Error adding User ARP to Memory Repository.");
393                 }
394
395                 // create a repository
396                 repository = null;
397
398                 try {
399                         placeHolder = docFactory.newDocumentBuilder().newDocument();
400
401                         Element repositoryElement = placeHolder.createElementNS(IdPConfig.configNameSpace, "ArpRepository");
402                         repositoryElement.setAttributeNS(IdPConfig.configNameSpace, "implementation",
403                                         "edu.internet2.middleware.shibboleth.aa.arp.provider.FileSystemArpRepository");
404                         repositoryElement.setAttributeNS(IdPConfig.configNameSpace, "arpTTL", "65535");
405
406                         Element path = placeHolder.createElementNS(IdPConfig.configNameSpace, "Path");
407                         Text text = placeHolder.createTextNode(new File("data/").toURI().toString());
408                         path.appendChild(text);
409
410                         repositoryElement.appendChild(path);
411
412                         repository = ArpRepositoryFactory.getInstance(repositoryElement);
413
414                 } catch (ArpRepositoryException e) {
415                         fail("Failed to create file-based Arp Repository" + e);
416                 } catch (ParserConfigurationException e) {
417                         fail("Failed to create file-based Arp Repository configuration" + e);
418                 }
419
420                 assertNotNull("Failed to create file-based Arp Repository: Factory returned null.", repository);
421
422                 try {
423                         Arp siteArp = repository.getSitePolicy();
424
425                         InputStream inStream = new FileInputStream("data/arp.site.xml");
426                         parser.parse(new InputSource(inStream));
427                         String directXML = Parser.serialize(parser.getDocument().getDocumentElement());
428
429                         String processedXML = Parser.serialize(siteArp.unmarshall());
430
431                         assertTrue("File-based ARP Repository did not return the correct site ARP.", directXML.toString()
432                                         .replaceAll(">[\t\r\n ]+<", "><").equals(processedXML.toString().replaceAll(">[\t\r\n ]+<", "><")));
433
434                         Arp userArp = repository.getUserPolicy(new LocalPrincipal("test"));
435
436                         inStream = new FileInputStream("data/arp.user.test.xml");
437                         parser.parse(new InputSource(inStream));
438                         directXML = Parser.serialize(parser.getDocument().getDocumentElement());
439
440                         processedXML = Parser.serialize(userArp.unmarshall());
441
442                         assertTrue("File-based ARP Repository did not return the correct user ARP.", directXML.toString()
443                                         .replaceAll(">[\t\r\n ]+<", "><").equals(processedXML.toString().replaceAll(">[\t\r\n ]+<", "><")));
444
445                         Arp[] allArps = repository.getAllPolicies(new LocalPrincipal("test"));
446
447                         assertTrue("File-based ARP Repository did not return the correct number of ARPs.", (allArps.length == 2));
448
449                 } catch (Exception e) {
450                         fail("Error retrieving ARP from Repository: " + e);
451                 }
452
453         }
454
455         public void testPossibleReleaseSetComputation() {
456
457                 ArpRepository repository = null;
458                 try {
459                         repository = ArpRepositoryFactory.getInstance(memoryRepositoryElement);
460                 } catch (ArpRepositoryException e) {
461                         fail("Failed to create memory-based Arp Repository" + e);
462                 }
463
464                 try {
465                         Principal principal1 = new LocalPrincipal("TestPrincipal");
466                         URL url1 = new URL("http://www.example.edu/");
467
468                         Set<URI> list1 = new HashSet<URI>();
469                         list1.add(new URI("urn:mace:dir:attribute-def:eduPersonAffiliation"));
470
471                         Set<URI> list2 = new HashSet<URI>();
472                         list2.add(new URI("urn:mace:dir:attribute-def:eduPersonAffiliation"));
473                         list2.add(new URI("urn:mace:dir:attribute-def:eduPersonPrincipalName"));
474
475                         Set<URI> list3 = new HashSet<URI>();
476
477                         // Test with just a site ARP
478                         InputStream inStream = new FileInputStream("data/arp1.xml");
479                         parser.parse(new InputSource(inStream));
480                         Arp arp1 = new Arp();
481                         arp1.marshall(parser.getDocument().getDocumentElement());
482                         repository.update(arp1);
483                         ArpEngine engine = new ArpEngine(repository);
484                         Set<URI> possibleAttributes = engine.listPossibleReleaseAttributes(principal1, "shar.example.edu", url1);
485                         assertEquals("Incorrectly computed possible release set (1).", possibleAttributes, list1);
486
487                         // Test with site and user ARPs
488                         inStream = new FileInputStream("data/arp7.xml");
489                         parser.parse(new InputSource(inStream));
490                         Arp arp7 = new Arp();
491                         arp7.setPrincipal(principal1);
492                         arp7.marshall(parser.getDocument().getDocumentElement());
493                         repository.update(arp7);
494                         possibleAttributes = engine.listPossibleReleaseAttributes(principal1, "shar.example.edu", url1);
495                         assertEquals("Incorrectly computed possible release set (2).", possibleAttributes, list2);
496
497                         // Ensure that explicit denies on any value are not in the release set
498                         inStream = new FileInputStream("data/arp6.xml");
499                         parser.parse(new InputSource(inStream));
500                         Arp arp6 = new Arp();
501                         arp6.setPrincipal(principal1);
502                         arp6.marshall(parser.getDocument().getDocumentElement());
503                         repository.update(arp6);
504                         possibleAttributes = engine.listPossibleReleaseAttributes(principal1, "shar.example.edu", url1);
505                         assertEquals("Incorrectly computed possible release set (3).", possibleAttributes, list3);
506
507                 } catch (Exception e) {
508                         e.printStackTrace();
509                         fail("Failed to marshall ARP: " + e);
510                 }
511
512         }
513
514         public void testArpApplication() {
515
516                 // Construct an engine with a memory-based repository
517                 ArpRepository repository = null;
518                 try {
519                         repository = ArpRepositoryFactory.getInstance(memoryRepositoryElement);
520
521                 } catch (ArpRepositoryException e) {
522                         fail("Failed to create memory-based Arp Repository" + e);
523                 }
524
525                 try {
526
527                         arpApplicationTest1(repository, parser);
528                         arpApplicationTest2(repository, parser);
529                         arpApplicationTest3(repository, parser);
530                         arpApplicationTest4(repository, parser);
531                         arpApplicationTest5(repository, parser);
532                         arpApplicationTest6(repository, parser);
533                         arpApplicationTest7(repository, parser);
534                         arpApplicationTest8(repository, parser);
535                         arpApplicationTest9(repository, parser);
536                         arpApplicationTest10(repository, parser);
537                         arpApplicationTest11(repository, parser);
538                         arpApplicationTest12(repository, parser);
539                         arpApplicationTest13(repository, parser);
540                         arpApplicationTest14(repository, parser);
541                         arpApplicationTest15(repository, parser);
542                         arpApplicationTest16(repository, parser);
543                         arpApplicationTest17(repository, parser);
544                         arpApplicationTest18(repository, parser);
545                         arpApplicationTest19(repository, parser);
546                         arpApplicationTest20(repository, parser);
547                         arpApplicationTest21(repository, parser);
548                         arpApplicationTest22(repository, parser);
549                         arpApplicationTest23(repository, parser);
550                         arpApplicationTest24(repository, parser);
551
552                 } catch (Exception e) {
553                         e.printStackTrace();
554                         fail("Failed to apply filter to ARPs: " + e);
555                 }
556         }
557
558         public void testRoundtripMarshalling() {
559
560                 try {
561                         for (int i = 0; i < arpExamples.length; i++) {
562
563                                 // Get a non-validating parser so we don't fill in schema defaults
564                                 Parser.DOMParser nonValParser = new Parser.DOMParser(false);
565
566                                 InputStream inStream = new FileInputStream(arpExamples[i]);
567
568                                 nonValParser.parse(new InputSource(inStream));
569                                 String directXML = Parser.serialize(nonValParser.getDocument().getDocumentElement());
570                                 inStream.close();
571
572                                 // Use validation when marshalling into an ARP
573                                 inStream = new FileInputStream(arpExamples[i]);
574                                 parser.parse(new InputSource(inStream));
575                                 Arp arp1 = new Arp();
576                                 arp1.marshall(parser.getDocument().getDocumentElement());
577                                 String processedXML = Parser.serialize(arp1.unmarshall());
578
579                                 assertEquals("Round trip marshall/unmarshall failed for file (" + arpExamples[i] + ")", directXML
580                                                 .toString().replaceAll(">[\t\r\n ]+<", "><"), processedXML.toString().replaceAll(
581                                                 ">[\t\r\n ]+<", "><"));
582                         }
583
584                 } catch (Exception e) {
585                         e.printStackTrace();
586                         fail("Failed to marshall ARP: " + e);
587                 }
588
589         }
590
591         /**
592          * ARPs: A site ARP only Target: Any Attribute: Any value release,
593          */
594         void arpApplicationTest1(ArpRepository repository, Parser.DOMParser parser) throws Exception {
595
596                 // Gather the Input
597                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
598                                 + "<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\">"
599                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
600                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
601                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
602                                 + "     </AttributeReleasePolicy>";
603
604                 Principal principal1 = new LocalPrincipal("TestPrincipal");
605                 URL url1 = new URL("http://www.example.edu/");
606                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
607                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
608                                                 "faculty@example.edu"})));
609
610                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
611                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
612                                                 "faculty@example.edu"}));
613
614                 // Setup the engine
615                 parser.parse(new InputSource(new StringReader(rawArp)));
616                 Arp siteArp = new Arp();
617                 siteArp.marshall(parser.getDocument().getDocumentElement());
618                 repository.update(siteArp);
619                 ArpEngine engine = new ArpEngine(repository);
620
621                 // Apply the ARP
622                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
623
624                 assertEquals("ARP application test 1: ARP not applied as expected.", inputSet, releaseSet);
625         }
626
627         /**
628          * ARPs: A site ARP only Target: Any Attribute: Any value release, implicit deny
629          */
630         void arpApplicationTest2(ArpRepository repository, Parser.DOMParser parser) throws Exception {
631
632                 // Gather the Input
633                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
634                                 + "<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\">"
635                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
636                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
637                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
638                                 + "     </AttributeReleasePolicy>";
639
640                 Principal principal1 = new LocalPrincipal("TestPrincipal");
641                 URL url1 = new URL("http://www.example.edu/");
642                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute[]{
643                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
644                                                 "faculty@example.edu"}),
645                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonPrincipalName",
646                                                 new Object[]{"mehoehn@example.edu"})}));
647
648                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute[]{new AAAttribute(
649                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
650                                                 "faculty@example.edu"})});
651
652                 // Setup the engine
653                 parser.parse(new InputSource(new StringReader(rawArp)));
654                 Arp siteArp = new Arp();
655                 siteArp.marshall(parser.getDocument().getDocumentElement());
656                 repository.update(siteArp);
657                 ArpEngine engine = new ArpEngine(repository);
658
659                 // Apply the ARP
660                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
661
662                 assertEquals("ARP application test 2: ARP not applied as expected.", inputSet, releaseSet);
663         }
664
665         /**
666          * ARPs: A site ARP only Target: Any Attribute: One value release
667          */
668         void arpApplicationTest3(ArpRepository repository, Parser.DOMParser parser) throws Exception {
669
670                 // Gather the Input
671                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
672                                 + "<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\">"
673                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
674                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
675                                 + "                                     <Value release=\"permit\">member@example.edu</Value>" + "                               </Attribute>" + "                       </Rule>"
676                                 + "     </AttributeReleasePolicy>";
677
678                 Principal principal1 = new LocalPrincipal("TestPrincipal");
679                 URL url1 = new URL("http://www.example.edu/");
680                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
681                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
682                                                 "faculty@example.edu"})));
683                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
684                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu"}));
685
686                 // Setup the engine
687                 parser.parse(new InputSource(new StringReader(rawArp)));
688                 Arp siteArp = new Arp();
689                 siteArp.marshall(parser.getDocument().getDocumentElement());
690                 repository.update(siteArp);
691                 ArpEngine engine = new ArpEngine(repository);
692
693                 // Apply the ARP
694                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
695
696                 assertEquals("ARP application test 3: ARP not applied as expected.", inputSet, releaseSet);
697         }
698
699         /**
700          * ARPs: A site ARP only Target: Any Attribute: Any value except one release, canonical representation
701          */
702         void arpApplicationTest4(ArpRepository repository, Parser.DOMParser parser) throws Exception {
703
704                 // Gather the Input
705                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
706                                 + "<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\">"
707                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
708                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
709                                 + "                                     <AnyValue release=\"permit\"/>" + "                                     <Value release=\"deny\">member@example.edu</Value>"
710                                 + "                             </Attribute>" + "                       </Rule>" + "    </AttributeReleasePolicy>";
711
712                 Principal principal1 = new LocalPrincipal("TestPrincipal");
713                 URL url1 = new URL("http://www.example.edu/");
714                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
715                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
716                                                 "faculty@example.edu", "employee@example.edu"})));
717                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
718                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"faculty@example.edu",
719                                                 "employee@example.edu"}));
720
721                 // Setup the engine
722                 parser.parse(new InputSource(new StringReader(rawArp)));
723                 Arp siteArp = new Arp();
724                 siteArp.marshall(parser.getDocument().getDocumentElement());
725                 repository.update(siteArp);
726                 ArpEngine engine = new ArpEngine(repository);
727
728                 // Apply the ARP
729                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
730
731                 assertEquals("ARP application test 4: ARP not applied as expected.", inputSet, releaseSet);
732         }
733
734         /**
735          * ARPs: A site ARP only Target: Any Attribute: Any value except one release, expanded representation
736          */
737         void arpApplicationTest5(ArpRepository repository, Parser.DOMParser parser) throws Exception {
738
739                 // Gather the Input
740                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
741                                 + "<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\">"
742                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
743                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
744                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>"
745                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
746                                 + "                                     <Value release=\"deny\">member@example.edu</Value>" + "                         </Attribute>" + "                       </Rule>"
747                                 + "     </AttributeReleasePolicy>";
748
749                 Principal principal1 = new LocalPrincipal("TestPrincipal");
750                 URL url1 = new URL("http://www.example.edu/");
751                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
752                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
753                                                 "faculty@example.edu", "employee@example.edu"})));
754                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
755                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"faculty@example.edu",
756                                                 "employee@example.edu"}));
757
758                 // Setup the engine
759                 parser.parse(new InputSource(new StringReader(rawArp)));
760                 Arp siteArp = new Arp();
761                 siteArp.marshall(parser.getDocument().getDocumentElement());
762                 repository.update(siteArp);
763                 ArpEngine engine = new ArpEngine(repository);
764
765                 // Apply the ARP
766                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
767
768                 assertEquals("ARP application test 5: ARP not applied as expected.", inputSet, releaseSet);
769         }
770
771         /**
772          * ARPs: A site ARP only Target: Any Attribute: Any value except two release, expanded representation
773          */
774         void arpApplicationTest6(ArpRepository repository, Parser.DOMParser parser) throws Exception {
775
776                 // Gather the Input
777                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
778                                 + "<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\">"
779                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
780                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
781                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>"
782                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
783                                 + "                                     <Value release=\"deny\">member@example.edu</Value>" + "                         </Attribute>"
784                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
785                                 + "                                     <Value release=\"deny\">faculty@example.edu</Value>" + "                                </Attribute>" + "                       </Rule>"
786                                 + "     </AttributeReleasePolicy>";
787
788                 Principal principal1 = new LocalPrincipal("TestPrincipal");
789                 URL url1 = new URL("http://www.example.edu/");
790                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
791                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
792                                                 "faculty@example.edu", "employee@example.edu"})));
793                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
794                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"employee@example.edu"}));
795
796                 // Setup the engine
797                 parser.parse(new InputSource(new StringReader(rawArp)));
798                 Arp siteArp = new Arp();
799                 siteArp.marshall(parser.getDocument().getDocumentElement());
800                 repository.update(siteArp);
801                 ArpEngine engine = new ArpEngine(repository);
802
803                 // Apply the ARP
804                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
805
806                 assertEquals("ARP application test 6: ARP not applied as expected.", inputSet, releaseSet);
807         }
808
809         /**
810          * ARPs: A site ARP only Target: Any Attribute: Two value release, canonical representation
811          */
812         void arpApplicationTest7(ArpRepository repository, Parser.DOMParser parser) throws Exception {
813
814                 // Gather the Input
815                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
816                                 + "<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\">"
817                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
818                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
819                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
820                                 + "                                     <Value release=\"permit\">faculty@example.edu</Value>" + "                              </Attribute>" + "                       </Rule>"
821                                 + "     </AttributeReleasePolicy>";
822
823                 Principal principal1 = new LocalPrincipal("TestPrincipal");
824                 URL url1 = new URL("http://www.example.edu/");
825                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
826                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
827                                                 "faculty@example.edu", "employee@example.edu"})));
828                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
829                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
830                                                 "faculty@example.edu"}));
831
832                 // Setup the engine
833                 parser.parse(new InputSource(new StringReader(rawArp)));
834                 Arp siteArp = new Arp();
835                 siteArp.marshall(parser.getDocument().getDocumentElement());
836                 repository.update(siteArp);
837                 ArpEngine engine = new ArpEngine(repository);
838
839                 // Apply the ARP
840                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
841
842                 assertEquals("ARP application test 3: ARP not applied as expected.", inputSet, releaseSet);
843         }
844
845         /**
846          * ARPs: A site ARP only Target: Any Attribute: Two value release, expanded representation
847          */
848         void arpApplicationTest8(ArpRepository repository, Parser.DOMParser parser) throws Exception {
849
850                 // Gather the Input
851                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
852                                 + "<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\">"
853                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
854                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
855                                 + "                                     <Value release=\"permit\">member@example.edu</Value>" + "                               </Attribute>"
856                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
857                                 + "                                     <Value release=\"permit\">faculty@example.edu</Value>" + "                              </Attribute>" + "                       </Rule>"
858                                 + "     </AttributeReleasePolicy>";
859
860                 Principal principal1 = new LocalPrincipal("TestPrincipal");
861                 URL url1 = new URL("http://www.example.edu/");
862                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
863                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
864                                                 "faculty@example.edu", "employee@example.edu"})));
865                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
866                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
867                                                 "faculty@example.edu"}));
868
869                 // Setup the engine
870                 parser.parse(new InputSource(new StringReader(rawArp)));
871                 Arp siteArp = new Arp();
872                 siteArp.marshall(parser.getDocument().getDocumentElement());
873                 repository.update(siteArp);
874                 ArpEngine engine = new ArpEngine(repository);
875
876                 // Apply the ARP
877                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
878
879                 assertEquals("ARP application test 8: ARP not applied as expected.", inputSet, releaseSet);
880         }
881
882         /**
883          * ARPs: A site ARP only Target: Any Attribute: Any value deny
884          */
885         void arpApplicationTest9(ArpRepository repository, Parser.DOMParser parser) throws Exception {
886
887                 // Gather the Input
888                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
889                                 + "<AttributeReleasePolicy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mace:shibboleth:arp:1.0\" xsi:schemaLocation=\"urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd\">"
890                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
891                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
892                                 + "                                     <AnyValue release=\"deny\"/>" + "                               </Attribute>" + "                       </Rule>"
893                                 + "     </AttributeReleasePolicy>";
894
895                 Principal principal1 = new LocalPrincipal("TestPrincipal");
896                 URL url1 = new URL("http://www.example.edu/");
897                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
898                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
899                                                 "faculty@example.edu"})));
900
901                 // Setup the engine
902                 parser.parse(new InputSource(new StringReader(rawArp)));
903                 Arp siteArp = new Arp();
904                 siteArp.marshall(parser.getDocument().getDocumentElement());
905                 repository.update(siteArp);
906                 ArpEngine engine = new ArpEngine(repository);
907
908                 // Apply the ARP
909                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
910
911                 assertEquals("ARP application test 9: ARP not applied as expected.", inputSet, new ArrayList<AAAttribute>());
912         }
913
914         /**
915          * ARPs: A site ARP only Target: Any Attribute: Any value deny trumps explicit permit expanded representation
916          */
917         void arpApplicationTest10(ArpRepository repository, Parser.DOMParser parser) throws Exception {
918
919                 // Gather the Input
920                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
921                                 + "<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\">"
922                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
923                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
924                                 + "                                     <AnyValue release=\"deny\"/>" + "                               </Attribute>"
925                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
926                                 + "                                     <Value release=\"permit\">member@example.edu</Value>" + "                               </Attribute>" + "                       </Rule>"
927                                 + "     </AttributeReleasePolicy>";
928
929                 Principal principal1 = new LocalPrincipal("TestPrincipal");
930                 URL url1 = new URL("http://www.example.edu/");
931                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
932                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
933                                                 "faculty@example.edu"})));
934
935                 // Setup the engine
936                 parser.parse(new InputSource(new StringReader(rawArp)));
937                 Arp siteArp = new Arp();
938                 siteArp.marshall(parser.getDocument().getDocumentElement());
939                 repository.update(siteArp);
940                 ArpEngine engine = new ArpEngine(repository);
941
942                 // Apply the ARP
943                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
944
945                 assertEquals("ARP application test 10: ARP not applied as expected.", inputSet, new ArrayList<AAAttribute>());
946         }
947
948         /**
949          * ARPs: A site ARP only Target: Any Attribute: Any value deny trumps explicit permit canonical representation
950          */
951         void arpApplicationTest11(ArpRepository repository, Parser.DOMParser parser) throws Exception {
952
953                 // Gather the Input
954                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
955                                 + "<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\">"
956                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
957                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
958                                 + "                                     <AnyValue release=\"deny\"/>" + "                                       <Value release=\"permit\">member@example.edu</Value>"
959                                 + "                             </Attribute>" + "                       </Rule>" + "    </AttributeReleasePolicy>";
960
961                 Principal principal1 = new LocalPrincipal("TestPrincipal");
962                 URL url1 = new URL("http://www.example.edu/");
963                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
964                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
965                                                 "faculty@example.edu"})));
966
967                 // Setup the engine
968                 parser.parse(new InputSource(new StringReader(rawArp)));
969                 Arp siteArp = new Arp();
970                 siteArp.marshall(parser.getDocument().getDocumentElement());
971                 repository.update(siteArp);
972                 ArpEngine engine = new ArpEngine(repository);
973
974                 // Apply the ARP
975                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
976
977                 assertEquals("ARP application test 11: ARP not applied as expected.", inputSet, new ArrayList<AAAttribute>());
978         }
979
980         /**
981          * ARPs: A site ARP only Target: Specific shar, Any Resource Attribute: Any value release
982          */
983         void arpApplicationTest12(ArpRepository repository, Parser.DOMParser parser) throws Exception {
984
985                 // Gather the Input
986                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
987                                 + "<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\">"
988                                 + "                     <Rule>" + "                             <Target>" + "                                   <Requester>shar.example.edu</Requester>"
989                                 + "                                     <AnyResource />" + "                            </Target>"
990                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
991                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
992                                 + "     </AttributeReleasePolicy>";
993
994                 Principal principal1 = new LocalPrincipal("TestPrincipal");
995                 URL url1 = new URL("http://www.example.edu/");
996                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
997                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
998                                                 "faculty@example.edu"})));
999                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
1000                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1001                                                 "faculty@example.edu"}));
1002
1003                 // Setup the engine
1004                 parser.parse(new InputSource(new StringReader(rawArp)));
1005                 Arp siteArp = new Arp();
1006                 siteArp.marshall(parser.getDocument().getDocumentElement());
1007                 repository.update(siteArp);
1008                 ArpEngine engine = new ArpEngine(repository);
1009
1010                 // Apply the ARP
1011                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1012
1013                 assertEquals("ARP application test 12: ARP not applied as expected.", inputSet, releaseSet);
1014         }
1015
1016         /**
1017          * ARPs: A site ARP only Target: Specific shar, Any Resource (another example) Attribute: Any value release
1018          */
1019         void arpApplicationTest13(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1020
1021                 // Gather the Input
1022                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1023                                 + "<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\">"
1024                                 + "                     <Rule>" + "                             <Target>" + "                                   <Requester>shar.example.edu</Requester>"
1025                                 + "                                     <AnyResource />" + "                            </Target>"
1026                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1027                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
1028                                 + "     </AttributeReleasePolicy>";
1029
1030                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1031                 URL url1 = new URL("https://foo.com/");
1032                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
1033                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1034                                                 "faculty@example.edu"})));
1035                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
1036                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1037                                                 "faculty@example.edu"}));
1038
1039                 // Setup the engine
1040                 parser.parse(new InputSource(new StringReader(rawArp)));
1041                 Arp siteArp = new Arp();
1042                 siteArp.marshall(parser.getDocument().getDocumentElement());
1043                 repository.update(siteArp);
1044                 ArpEngine engine = new ArpEngine(repository);
1045
1046                 // Apply the ARP
1047                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1048
1049                 assertEquals("ARP application test 13: ARP not applied as expected.", inputSet, releaseSet);
1050         }
1051
1052         /**
1053          * ARPs: A site ARP only Target: Specific shar (no match), Any Resource Attribute: Any value release
1054          */
1055         void arpApplicationTest14(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1056
1057                 // Gather the Input
1058                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1059                                 + "<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\">"
1060                                 + "                     <Rule>" + "                             <Target>" + "                                   <Requester>shar.example.edu</Requester>"
1061                                 + "                                     <AnyResource />" + "                            </Target>"
1062                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1063                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
1064                                 + "     </AttributeReleasePolicy>";
1065
1066                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1067                 URL url1 = new URL("http://www.example.edu/");
1068                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
1069                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1070                                                 "faculty@example.edu"})));
1071
1072                 // Setup the engine
1073                 parser.parse(new InputSource(new StringReader(rawArp)));
1074                 Arp siteArp = new Arp();
1075                 siteArp.marshall(parser.getDocument().getDocumentElement());
1076                 repository.update(siteArp);
1077                 ArpEngine engine = new ArpEngine(repository);
1078
1079                 // Apply the ARP
1080                 engine.filterAttributes(inputSet, principal1, "www.example.edu", url1);
1081
1082                 assertEquals("ARP application test 14: ARP not applied as expected.", inputSet, new ArrayList<AAAttribute>());
1083         }
1084
1085         /**
1086          * ARPs: A site ARP only Target: Specific shar, Specific resource Attribute: Any value release
1087          */
1088         void arpApplicationTest15(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1089
1090                 // Gather the Input
1091                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1092                                 + "<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\">"
1093                                 + "                     <Rule>" + "                             <Target>" + "                                   <Requester>shar.example.edu</Requester>"
1094                                 + "                                     <Resource>http://www.example.edu/</Resource>" + "                               </Target>"
1095                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1096                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
1097                                 + "     </AttributeReleasePolicy>";
1098
1099                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1100                 URL url1 = new URL("http://www.example.edu/index.html");
1101                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
1102                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1103                                                 "faculty@example.edu"})));
1104                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
1105                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1106                                                 "faculty@example.edu"}));
1107
1108                 // Setup the engine
1109                 parser.parse(new InputSource(new StringReader(rawArp)));
1110                 Arp siteArp = new Arp();
1111                 siteArp.marshall(parser.getDocument().getDocumentElement());
1112                 repository.update(siteArp);
1113                 ArpEngine engine = new ArpEngine(repository);
1114
1115                 // Apply the ARP
1116                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1117
1118                 assertEquals("ARP application test 15: ARP not applied as expected.", inputSet, releaseSet);
1119         }
1120
1121         /**
1122          * ARPs: A site ARP only Target: Specific shar, Specific resource (no match) Attribute: Any value release
1123          */
1124         void arpApplicationTest16(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1125
1126                 // Gather the Input
1127                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1128                                 + "<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\">"
1129                                 + "                     <Rule>" + "                             <Target>" + "                                   <Requester>shar.example.edu</Requester>"
1130                                 + "                                     <Resource>http://www.example.edu/</Resource>" + "                               </Target>"
1131                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1132                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
1133                                 + "     </AttributeReleasePolicy>";
1134
1135                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1136                 URL url1 = new URL("https://www.example.edu/index.html");
1137                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
1138                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1139                                                 "faculty@example.edu"})));
1140
1141                 // Setup the engine
1142                 parser.parse(new InputSource(new StringReader(rawArp)));
1143                 Arp siteArp = new Arp();
1144                 siteArp.marshall(parser.getDocument().getDocumentElement());
1145                 repository.update(siteArp);
1146                 ArpEngine engine = new ArpEngine(repository);
1147
1148                 // Apply the ARP
1149                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1150
1151                 assertEquals("ARP application test 16: ARP not applied as expected.", inputSet, new ArrayList<AAAttribute>());
1152         }
1153
1154         /**
1155          * ARPs: A site ARP only Target: Multiple matching rules Attribute: various
1156          */
1157         void arpApplicationTest17(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1158
1159                 // Gather the Input
1160                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1161                                 + "<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\">"
1162                                 + "                     <Rule>"
1163                                 + "                             <Target>"
1164                                 + "                                     <AnyTarget />"
1165                                 + "                             </Target>"
1166                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1167                                 + "                                     <AnyValue release=\"permit\"/>"
1168                                 + "                             </Attribute>"
1169                                 + "                     </Rule>"
1170                                 + "                     <Rule>"
1171                                 + "                             <Target>"
1172                                 + "                                     <Requester>shar1.example.edu</Requester>"
1173                                 + "                                     <AnyResource />"
1174                                 + "                             </Target>"
1175                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1176                                 + "                                     <Value release=\"deny\">faculty@example.edu</Value>"
1177                                 + "                             </Attribute>"
1178                                 + "                     </Rule>"
1179                                 + "                     <Rule>"
1180                                 + "                             <Target>"
1181                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">shar[1-9]\\.example\\.edu</Requester>"
1182                                 + "                                     <Resource matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">^https?://.+\\.example\\.edu/.*$</Resource>"
1183                                 + "                             </Target>" + "                          <Attribute name=\"urn:mace:dir:attribute-def:eduPersonPrincipalName\">"
1184                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
1185                                 + "     </AttributeReleasePolicy>";
1186
1187                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1188                 URL url1 = new URL("https://www.example.edu/index.html");
1189                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays
1190                                 .asList(new AAAttribute[]{
1191                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{
1192                                                                 "member@example.edu", "faculty@example.edu"}),
1193                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonPrincipalName",
1194                                                                 new Object[]{"wassa@columbia.edu"})}));
1195
1196                 Collection<AAAttribute> releaseSet = Arrays
1197                                 .asList(new AAAttribute[]{
1198                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation",
1199                                                                 new Object[]{"member@example.edu"}),
1200                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonPrincipalName",
1201                                                                 new Object[]{"wassa@columbia.edu"})});
1202
1203                 // Setup the engine
1204                 parser.parse(new InputSource(new StringReader(rawArp)));
1205                 Arp siteArp = new Arp();
1206                 siteArp.marshall(parser.getDocument().getDocumentElement());
1207                 repository.update(siteArp);
1208                 ArpEngine engine = new ArpEngine(repository);
1209
1210                 // Apply the ARP
1211                 engine.filterAttributes(inputSet, principal1, "shar1.example.edu", url1);
1212
1213                 assertEquals("ARP application test 17: ARP not applied as expected.", inputSet, releaseSet);
1214         }
1215
1216         /**
1217          * ARPs: A site ARP only Target: Any Attribute: Any value release of two attributes in one rule
1218          */
1219         void arpApplicationTest18(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1220
1221                 // Gather the Input
1222                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1223                                 + "<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\">"
1224                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
1225                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1226                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>"
1227                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonPrincipalName\">"
1228                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
1229                                 + "     </AttributeReleasePolicy>";
1230
1231                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1232                 URL url1 = new URL("http://www.example.edu/");
1233                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute[]{
1234                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1235                                                 "faculty@example.edu"}),
1236                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonPrincipalName",
1237                                                 new Object[]{"mehoehn@example.edu"})}));
1238
1239                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute[]{
1240                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1241                                                 "faculty@example.edu"}),
1242                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonPrincipalName",
1243                                                 new Object[]{"mehoehn@example.edu"})});
1244
1245                 // Setup the engine
1246                 parser.parse(new InputSource(new StringReader(rawArp)));
1247                 Arp siteArp = new Arp();
1248                 siteArp.marshall(parser.getDocument().getDocumentElement());
1249                 repository.update(siteArp);
1250                 ArpEngine engine = new ArpEngine(repository);
1251
1252                 // Apply the ARP
1253                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1254
1255                 assertEquals("ARP application test 18: ARP not applied as expected.", inputSet, releaseSet);
1256         }
1257
1258         /**
1259          * ARPs: A user ARP only Target: Any Attribute: Any value release,
1260          */
1261         void arpApplicationTest19(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1262
1263                 // Gather the Input
1264                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1265                                 + "<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\">"
1266                                 + "                     <Rule>" + "                             <Target>" + "                                   <AnyTarget/>" + "                               </Target>"
1267                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1268                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>"
1269                                 + "     </AttributeReleasePolicy>";
1270
1271                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1272                 URL url1 = new URL("http://www.example.edu/");
1273                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
1274                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1275                                                 "faculty@example.edu"})));
1276                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
1277                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu",
1278                                                 "faculty@example.edu"}));
1279
1280                 // Setup the engine
1281                 parser.parse(new InputSource(new StringReader(rawArp)));
1282                 Arp userArp = new Arp();
1283                 userArp.setPrincipal(principal1);
1284                 userArp.marshall(parser.getDocument().getDocumentElement());
1285                 repository.update(userArp);
1286                 ArpEngine engine = new ArpEngine(repository);
1287
1288                 // Apply the ARP
1289                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1290
1291                 assertEquals("ARP application test 19: ARP not applied as expected.", inputSet, releaseSet);
1292         }
1293
1294         /**
1295          * ARPs: A site ARP and user ARP Target: various Attribute: various combinations
1296          */
1297         void arpApplicationTest20(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1298
1299                 // Gather the Input
1300                 String rawSiteArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1301                                 + "<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\">"
1302                                 + "                     <Rule>"
1303                                 + "                             <Target>"
1304                                 + "                                     <AnyTarget/>"
1305                                 + "                             </Target>"
1306                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1307                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
1308                                 + "                             </Attribute>"
1309                                 + "                             <Attribute name=\"urn:mace:inetOrgPerson:preferredLanguage\">"
1310                                 + "                                     <AnyValue release=\"permit\" />"
1311                                 + "                             </Attribute>"
1312                                 + "                     </Rule>"
1313                                 + "                     <Rule>"
1314                                 + "                             <Target>"
1315                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">.*\\.example\\.edu</Requester>"
1316                                 + "                                     <AnyResource />" + "                            </Target>"
1317                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonPrincipalName\">"
1318                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>" + "                    <Rule>"
1319                                 + "                             <Target>" + "                                   <Requester>www.example.edu</Requester>"
1320                                 + "                                     <Resource>http://www.example.edu/</Resource>" + "                               </Target>"
1321                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1322                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>"
1323                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1324                                 + "                                     <Value release=\"permit\">urn:example:contract:4657483</Value>" + "                             </Attribute>"
1325                                 + "                     </Rule>" + "                    <Rule>" + "                             <Target>" + "                                   <Requester>www.external.com</Requester>"
1326                                 + "                                     <Resource>http://www.external.com/</Resource>" + "                              </Target>"
1327                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1328                                 + "                                     <Value release=\"permit\">urn:example:contract:113455</Value>" + "                              </Attribute>"
1329                                 + "                     </Rule>" + "    </AttributeReleasePolicy>";
1330
1331                 String rawUserArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1332                                 + "<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\">"
1333                                 + "                     <Rule>"
1334                                 + "                             <Target>"
1335                                 + "                                     <AnyTarget/>"
1336                                 + "                             </Target>"
1337                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1338                                 + "                                     <Value release=\"deny\">urn:example:poorlyDressed</Value>"
1339                                 + "                             </Attribute>"
1340                                 + "                     </Rule>"
1341                                 + "                     <Rule>"
1342                                 + "                             <Target>"
1343                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">.*\\.example\\.edu</Requester>"
1344                                 + "                                     <AnyResource />" + "                            </Target>"
1345                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1346                                 + "                                     <Value release=\"deny\">faculty@example.edu</Value>" + "                                </Attribute>"
1347                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1348                                 + "                                     <Value release=\"permit\">urn:example:lovesIceCream</Value>" + "                                </Attribute>"
1349                                 + "                     </Rule>" + "    </AttributeReleasePolicy>";
1350
1351                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1352                 URL url1 = new URL("http://www.example.edu/test/index.html");
1353
1354                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays
1355                                 .asList(new AAAttribute[]{
1356                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{
1357                                                                 "urn:example:lovesIceCream", "urn:example:poorlyDressed",
1358                                                                 "urn:example:contract:113455", "urn:example:contract:4657483"}),
1359                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{
1360                                                                 "member@example.edu", "faculty@example.edu", "employee@example.edu"}),
1361                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonPrincipalName",
1362                                                                 new Object[]{"wassa@example.edu"}),
1363                                                 new AAAttribute("urn:mace:inetOrgPerson:preferredLanguage", new Object[]{"EO"})}));
1364
1365                 Collection<AAAttribute> releaseSet = Arrays
1366                                 .asList(new AAAttribute[]{
1367                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{
1368                                                                 "urn:example:lovesIceCream", "urn:example:contract:4657483"}),
1369                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{
1370                                                                 "member@example.edu", "employee@example.edu"}),
1371                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonPrincipalName",
1372                                                                 new Object[]{"wassa@example.edu"}),
1373                                                 new AAAttribute("urn:mace:inetOrgPerson:preferredLanguage", new Object[]{"EO"})});
1374
1375                 // Add the site ARP
1376                 parser.parse(new InputSource(new StringReader(rawSiteArp)));
1377                 Arp siteArp = new Arp();
1378                 siteArp.marshall(parser.getDocument().getDocumentElement());
1379                 repository.update(siteArp);
1380
1381                 // Add the user ARP
1382                 parser.parse(new InputSource(new StringReader(rawUserArp)));
1383                 Arp userArp = new Arp();
1384                 userArp.setPrincipal(principal1);
1385                 userArp.marshall(parser.getDocument().getDocumentElement());
1386                 repository.update(userArp);
1387
1388                 ArpEngine engine = new ArpEngine(repository);
1389
1390                 // Apply the ARP
1391                 engine.filterAttributes(inputSet, principal1, "www.example.edu", url1);
1392
1393                 assertEquals("ARP application test 20: ARP not applied as expected.", inputSet, releaseSet);
1394         }
1395
1396         /**
1397          * ARPs: A site ARP and user ARP Target: various Attribute: various combinations (same ARPs as 20, different
1398          * requester)
1399          */
1400         void arpApplicationTest21(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1401
1402                 // Gather the Input
1403                 String rawSiteArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1404                                 + "<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\">"
1405                                 + "                     <Rule>"
1406                                 + "                             <Target>"
1407                                 + "                                     <AnyTarget/>"
1408                                 + "                             </Target>"
1409                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1410                                 + "                                     <Value release=\"permit\">member@example.edu</Value>"
1411                                 + "                             </Attribute>"
1412                                 + "                             <Attribute name=\"urn:mace:inetOrgPerson:preferredLanguage\">"
1413                                 + "                                     <AnyValue release=\"permit\" />"
1414                                 + "                             </Attribute>"
1415                                 + "                     </Rule>"
1416                                 + "                     <Rule>"
1417                                 + "                             <Target>"
1418                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">.*\\.example\\.edu</Requester>"
1419                                 + "                                     <AnyResource />" + "                            </Target>"
1420                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonPrincipalName\">"
1421                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>" + "                       </Rule>" + "                    <Rule>"
1422                                 + "                             <Target>" + "                                   <Requester>www.example.edu</Requester>"
1423                                 + "                                     <Resource>http://www.example.edu/</Resource>" + "                               </Target>"
1424                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1425                                 + "                                     <AnyValue release=\"permit\"/>" + "                             </Attribute>"
1426                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1427                                 + "                                     <Value release=\"permit\">urn:example:contract:4657483</Value>" + "                             </Attribute>"
1428                                 + "                     </Rule>" + "                    <Rule>" + "                             <Target>" + "                                   <Requester>www.external.com</Requester>"
1429                                 + "                                     <Resource>http://www.external.com/</Resource>" + "                              </Target>"
1430                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1431                                 + "                                     <Value release=\"permit\">urn:example:contract:113455</Value>" + "                              </Attribute>"
1432                                 + "                     </Rule>" + "    </AttributeReleasePolicy>";
1433
1434                 String rawUserArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1435                                 + "<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\">"
1436                                 + "                     <Rule>"
1437                                 + "                             <Target>"
1438                                 + "                                     <AnyTarget/>"
1439                                 + "                             </Target>"
1440                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1441                                 + "                                     <Value release=\"deny\">urn:example:poorlyDressed</Value>"
1442                                 + "                             </Attribute>"
1443                                 + "                     </Rule>"
1444                                 + "                     <Rule>"
1445                                 + "                             <Target>"
1446                                 + "                                     <Requester matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">.*\\.example\\.edu</Requester>"
1447                                 + "                                     <AnyResource />" + "                            </Target>"
1448                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1449                                 + "                                     <Value release=\"deny\">faculty@example.edu</Value>" + "                                </Attribute>"
1450                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1451                                 + "                                     <Value release=\"permit\">urn:example:lovesIceCream</Value>" + "                                </Attribute>"
1452                                 + "                     </Rule>" + "    </AttributeReleasePolicy>";
1453
1454                 Principal principal1 = new LocalPrincipal("TestPrincipal");
1455                 URL url1 = new URL("http://www.external.com/");
1456
1457                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays
1458                                 .asList(new AAAttribute[]{
1459                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{
1460                                                                 "urn:example:lovesIceCream", "urn:example:poorlyDressed",
1461                                                                 "urn:example:contract:113455", "urn:example:contract:4657483"}),
1462                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{
1463                                                                 "member@example.edu", "faculty@example.edu", "employee@example.edu"}),
1464                                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonPrincipalName",
1465                                                                 new Object[]{"wassa@example.edu"}),
1466                                                 new AAAttribute("urn:mace:inetOrgPerson:preferredLanguage", new Object[]{"EO"})}));
1467
1468                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute[]{
1469                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement",
1470                                                 new Object[]{"urn:example:contract:113455"}),
1471                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member@example.edu"}),
1472                                 new AAAttribute("urn:mace:inetOrgPerson:preferredLanguage", new Object[]{"EO"})});
1473
1474                 // Add the site ARP
1475                 parser.parse(new InputSource(new StringReader(rawSiteArp)));
1476                 Arp siteArp = new Arp();
1477                 siteArp.marshall(parser.getDocument().getDocumentElement());
1478                 repository.update(siteArp);
1479
1480                 // Add the user ARP
1481                 parser.parse(new InputSource(new StringReader(rawUserArp)));
1482                 Arp userArp = new Arp();
1483                 userArp.setPrincipal(principal1);
1484                 userArp.marshall(parser.getDocument().getDocumentElement());
1485                 repository.update(userArp);
1486
1487                 ArpEngine engine = new ArpEngine(repository);
1488
1489                 // Apply the ARP
1490                 engine.filterAttributes(inputSet, principal1, "www.external.com", url1);
1491
1492                 assertEquals("ARP application test 21: ARP not applied as expected.", inputSet, releaseSet);
1493         }
1494
1495         /**
1496          * ARPs: A site ARP only Target: Specific shar, Specific resource Attribute: Release values by regex
1497          */
1498         void arpApplicationTest22(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1499
1500                 // Gather the Input
1501                 String rawArp = "<?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:dir:attribute-def:eduPersonEntitlement\">"
1509                                 + "                                     <Value release=\"permit\" matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">^urn:x:a.+$</Value>"
1510                                 + "                             </Attribute>" + "                       </Rule>" + "    </AttributeReleasePolicy>";
1511
1512                 Principal principal1 = new LocalPrincipal("Test2Principal");
1513                 URL url1 = new URL("http://www.example.edu/index.html");
1514                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
1515                                 "urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:a", "urn:x:foo", "urn:x:bar",
1516                                                 "urn:x:adagio", "urn:x:awol"})));
1517                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
1518                                 "urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:adagio", "urn:x:awol"}));
1519
1520                 // Setup the engine
1521                 parser.parse(new InputSource(new StringReader(rawArp)));
1522                 Arp siteArp = new Arp();
1523                 siteArp.marshall(parser.getDocument().getDocumentElement());
1524                 repository.update(siteArp);
1525                 ArpEngine engine = new ArpEngine(repository);
1526
1527                 // Apply the ARP
1528                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1529
1530                 assertEquals("ARP application test 22: ARP not applied as expected.", inputSet, releaseSet);
1531         }
1532
1533         /**
1534          * ARPs: A site ARP only Target: Specific shar, Specific resource Attribute: Deny specific values by regex
1535          */
1536         void arpApplicationTest23(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1537
1538                 // Gather the Input
1539                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1540                                 + "<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\">"
1541                                 + "                     <Rule>"
1542                                 + "                             <Target>"
1543                                 + "                                     <Requester>shar.example.edu</Requester>"
1544                                 + "                                     <Resource>http://www.example.edu/</Resource>"
1545                                 + "                             </Target>"
1546                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1547                                 + "                                     <AnyValue release=\"permit\" />"
1548                                 + "                                     <Value release=\"deny\" matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\">^urn:x:a.+$</Value>"
1549                                 + "                             </Attribute>" + "                       </Rule>" + "    </AttributeReleasePolicy>";
1550
1551                 Principal principal1 = new LocalPrincipal("Test2Principal");
1552                 URL url1 = new URL("http://www.example.edu/index.html");
1553                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute(
1554                                 "urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:a", "urn:x:foo", "urn:x:bar",
1555                                                 "urn:x:adagio", "urn:x:awol"})));
1556                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
1557                                 "urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:a", "urn:x:foo", "urn:x:bar"}));
1558
1559                 // Setup the engine
1560                 parser.parse(new InputSource(new StringReader(rawArp)));
1561                 Arp siteArp = new Arp();
1562                 siteArp.marshall(parser.getDocument().getDocumentElement());
1563                 repository.update(siteArp);
1564                 ArpEngine engine = new ArpEngine(repository);
1565
1566                 // Apply the ARP
1567                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1568
1569                 assertEquals("ARP application test 23: ARP not applied as expected.", inputSet, releaseSet);
1570         }
1571
1572         /**
1573          * ARPs: A site ARP only Target: Specific shar, Specific resource Attribute: No matches on specific values should
1574          * yield no attribute
1575          */
1576         void arpApplicationTest24(ArpRepository repository, Parser.DOMParser parser) throws Exception {
1577
1578                 // Gather the Input
1579                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1580                                 + "<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\">"
1581                                 + "                     <Rule>" + "                             <Target>" + "                                   <Requester>shar.example.edu</Requester>"
1582                                 + "                                     <Resource>http://www.example.edu/</Resource>" + "                               </Target>"
1583                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">"
1584                                 + "                                     <AnyValue release=\"permit\" />" + "                            </Attribute>"
1585                                 + "                             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">"
1586                                 + "                                     <Value release=\"permit\">urn:x:foo</Value>" + "                                </Attribute>" + "                       </Rule>"
1587                                 + "     </AttributeReleasePolicy>";
1588
1589                 Principal principal1 = new LocalPrincipal("Test2Principal");
1590                 URL url1 = new URL("http://www.example.edu/index.html");
1591                 Collection<AAAttribute> inputSet = new ArrayList<AAAttribute>(Arrays.asList(new AAAttribute[]{
1592                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:bar",
1593                                                 "urn:x:adagio"}),
1594                                 new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member"})}));
1595                 Collection<AAAttribute> releaseSet = Arrays.asList(new AAAttribute(
1596                                 "urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member"}));
1597
1598                 // Setup the engine
1599                 parser.parse(new InputSource(new StringReader(rawArp)));
1600                 Arp siteArp = new Arp();
1601                 siteArp.marshall(parser.getDocument().getDocumentElement());
1602                 repository.update(siteArp);
1603                 ArpEngine engine = new ArpEngine(repository);
1604
1605                 // Apply the ARP
1606                 engine.filterAttributes(inputSet, principal1, "shar.example.edu", url1);
1607
1608                 assertEquals("ARP application test 24: ARP not applied as expected.", inputSet, releaseSet);
1609         }
1610
1611 }