use the new session manager interface
[java-idp.git] / tests / edu / internet2 / middleware / shibboleth / aa / arp / ArpConstraintTests.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.StringReader;
20 import java.net.URI;
21 import java.security.Principal;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.HashSet;
25
26 import javax.xml.parsers.DocumentBuilderFactory;
27 import javax.xml.parsers.ParserConfigurationException;
28
29 import junit.framework.TestCase;
30
31 import org.apache.log4j.BasicConfigurator;
32 import org.apache.log4j.Level;
33 import org.apache.log4j.Logger;
34 import org.w3c.dom.Document;
35 import org.w3c.dom.Element;
36 import org.xml.sax.InputSource;
37
38 import edu.internet2.middleware.shibboleth.aa.AAAttribute;
39 import edu.internet2.middleware.shibboleth.common.LocalPrincipal;
40 import edu.internet2.middleware.shibboleth.idp.IdPConfig;
41
42 /**
43  * Validation suite for <code>Arp</code> Constraint processing.
44  * 
45  * @author Will Norris(wnorris@usc.edu)
46  */
47
48 public class ArpConstraintTests extends TestCase {
49
50         Logger log = Logger.getLogger(ArpConstraintTests.class);
51         private Element memoryRepositoryElement;
52         private ArpRepository repository;
53
54         public ArpConstraintTests(String name) {
55
56                 super(name);
57                 BasicConfigurator.resetConfiguration();
58                 BasicConfigurator.configure();
59                 Logger.getRootLogger().setLevel(Level.OFF);
60                 Logger.getLogger(ArpConstraintTests.class).setLevel(Level.DEBUG);
61                 Logger.getLogger(Rule.class).setLevel(Level.DEBUG);
62         }
63
64         public static void main(String[] args) {
65
66                 junit.textui.TestRunner.run(ArpConstraintTests.class);
67                 BasicConfigurator.configure();
68                 Logger.getRootLogger().setLevel(Level.OFF);
69         }
70
71         /**
72          * @see junit.framework.TestCase#setUp()
73          */
74         protected void setUp() throws Exception {
75
76                 super.setUp();
77
78                 // Setup an xml parser
79
80                 // Setup a dummy xml config for a Memory-based repository
81                 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
82                 docFactory.setNamespaceAware(true);
83                 Document placeHolder;
84                 try {
85                         placeHolder = docFactory.newDocumentBuilder().newDocument();
86
87                         memoryRepositoryElement = placeHolder.createElementNS(IdPConfig.configNameSpace, "ArpRepository");
88                         memoryRepositoryElement.setAttributeNS(IdPConfig.configNameSpace, "implementation",
89                                         "edu.internet2.middleware.shibboleth.aa.arp.provider.MemoryArpRepository");
90                 } catch (ParserConfigurationException e) {
91                         fail("Failed to create memory-based Arp Repository configuration" + e);
92                 }
93
94                 try {
95                         repository = ArpRepositoryFactory.getInstance(memoryRepositoryElement);
96                 } catch (ArpRepositoryException e) {
97                         fail("Failed to create memory-based Arp Repository" + e);
98                 }
99         }
100
101         /**
102          * test to ensure that attributes needed for constraints are included when listing possible attributes
103          */
104         public void testConstraintAttributeSetComputation() {
105
106                 try {
107                         Principal principal1 = new LocalPrincipal("TestPrincipal");
108
109                         Collection<URI> expectedAttributes = new HashSet<URI>();
110                         expectedAttributes.add(new URI("urn:mace:dir:attribute-def:foo"));
111
112                         String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
113                                         + "<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\">"
114                                         + "         <Rule>"
115                                         + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:foo\" matchFunction=\"urn:mace:shibboleth:arp:matchFunction:anyValueMatch\" />"
116                                         + "             <Target>" 
117                                         + "                 <AnyTarget/>" 
118                                         + "             </Target>"
119                                         + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
120                                         + "                 <AnyValue release=\"permit\"/>" 
121                                         + "             </Attribute>"
122                                         + "         </Rule>" 
123                                         + " </AttributeReleasePolicy>";
124
125                         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
126                         factory.setValidating(false);
127                         factory.setNamespaceAware(true);
128                         Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
129
130                         Arp arp1 = new Arp();
131                         arp1.marshall(doc.getDocumentElement());
132                         repository.update(arp1);
133                         ArpEngine engine = new ArpEngine(repository);
134                         Collection<URI> possibleAttributes = engine.listPossibleReleaseAttributes(principal1, "shar.example.edu");
135
136                         Collection<URI> constraintAttributes = engine.listRequiredConstraintAttributes(principal1,
137                                         "shar.example.edu", possibleAttributes);
138
139                         assertEquals("Incorrectly computed constraint release set.", expectedAttributes, constraintAttributes);
140
141                 } catch (Exception e) {
142                         e.printStackTrace();
143                         fail("Failed to marshall ARP: " + e);
144                 }
145
146         }
147
148         /**
149          * Use Case: must have an attribute Logical expression: P (no specific value) Example: release uid only if user has
150          * attribute "foo"
151          */
152         public void testArpConstraint1() throws Exception {
153
154                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
155                                 + "<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\">"
156                                 + "         <Rule>"
157                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:foo\" matchFunction=\"urn:mace:shibboleth:arp:matchFunction:anyValueMatch\" />"
158                                 + "             <Target>" 
159                                 + "                 <AnyTarget/>" 
160                                 + "             </Target>"
161                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
162                                 + "                 <AnyValue release=\"permit\"/>" 
163                                 + "             </Attribute>" 
164                                 + "         </Rule>"
165                                 + " </AttributeReleasePolicy>";
166
167                 // Setup the engine
168                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
169                 factory.setValidating(false);
170                 factory.setNamespaceAware(true);
171                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
172                 
173                 Arp siteArp = new Arp();
174                 siteArp.marshall(doc.getDocumentElement());
175                 repository.update(siteArp);
176                 ArpEngine engine = new ArpEngine(repository);
177
178                 Principal principal = new LocalPrincipal("TestPrincipal");
179
180                 // test user who meets constraint
181                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
182                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
183                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:foo", new Object[]{"bar"}));
184
185                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
186                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
187
188                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
189                 assertEquals("ARP application test 1a: ARP not applied as expected.", releaseSet1, inputSet1);
190
191                 // test user who does not meet constraint
192                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
193                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
194
195                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
196
197                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
198                 assertEquals("ARP application test 1b: ARP not applied as expected.", releaseSet2, inputSet2);
199
200         }
201
202         /**
203          * Use Case: must not have an attribute Logical expression: not P Example: release uid only if user does not have
204          * attribute "foo"
205          */
206         public void testArpConstraint2() throws Exception {
207
208                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
209                                 + "<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\">"
210                                 + "         <Rule>" 
211                                 + "             <Constraint"
212                                 + "                                     attributeName=\"urn:mace:dir:attribute-def:foo\""
213                                 + "                                     matchFunction=\"urn:mace:shibboleth:arp:matchFunction:anyValueMatch\""
214                                 + "                                     matches=\"none\" />" 
215                                 + "             <Target>" 
216                                 + "                 <AnyTarget/>"
217                                 + "             </Target>" 
218                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
219                                 + "                 <AnyValue release=\"permit\"/>" 
220                                 + "             </Attribute>" 
221                                 + "         </Rule>"
222                                 + " </AttributeReleasePolicy>";
223
224                 // Setup the engine
225                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
226                 factory.setValidating(false);
227                 factory.setNamespaceAware(true);
228                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
229                 
230                 Arp siteArp = new Arp();
231                 siteArp.marshall(doc.getDocumentElement());
232                 repository.update(siteArp);
233                 ArpEngine engine = new ArpEngine(repository);
234
235                 Principal principal = new LocalPrincipal("TestPrincipal");
236
237                 // test user who meets constraint
238                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
239                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
240
241                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
242                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
243
244                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
245                 assertEquals("ARP application test 2a: ARP not applied as expected.", releaseSet1, inputSet1);
246
247                 // test user who does not meet constraint
248                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
249                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
250                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:foo", new Object[]{"bar"}));
251
252                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
253
254                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
255                 assertEquals("ARP application test 2b: ARP not applied as expected.", releaseSet2, inputSet2);
256
257         }
258
259         /**
260          * Use Case: must have a specific attribute value Logical expression: Px (specific value) Example: release uid only
261          * if user has affiliation "member"
262          */
263         public void testArpConstraint3() throws Exception {
264
265                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
266                                 + "<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\">"
267                                 + "         <Rule>"
268                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">member</Constraint>"
269                                 + "             <Target>" 
270                                 + "                 <AnyTarget/>" 
271                                 + "             </Target>"
272                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
273                                 + "                 <AnyValue release=\"permit\"/>" 
274                                 + "             </Attribute>" 
275                                 + "         </Rule>"
276                                 + " </AttributeReleasePolicy>";
277
278                 // Setup the engine
279                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
280                 factory.setValidating(false);
281                 factory.setNamespaceAware(true);
282                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
283                 
284                 Arp siteArp = new Arp();
285                 siteArp.marshall(doc.getDocumentElement());
286                 repository.update(siteArp);
287                 ArpEngine engine = new ArpEngine(repository);
288
289                 Principal principal = new LocalPrincipal("TestPrincipal");
290
291                 // test user who meets constraint
292                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
293                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
294                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"member"}));
295
296                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
297                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
298
299                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
300                 assertEquals("ARP application test 3a: ARP not applied as expected.", releaseSet1, inputSet1);
301
302                 // test user who does not meet constraint
303                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
304                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
305                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"student"}));
306
307                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
308
309                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
310                 assertEquals("ARP application test 3b: ARP not applied as expected.", releaseSet2, inputSet2);
311
312         }
313
314         /**
315          * Use Case: must have an attribute value that matches a regular expression Logical expression: Pe (regular
316          * expression) Example: release uid only if user has scoped affiliation matching the regular expression
317          * ".*\@example\.edu"
318          */
319         public void testArpConstraint4() throws Exception {
320
321                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
322                                 + "<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\">"
323                                 + "         <Rule>" + "             <Constraint"
324                                 + "                                     attributeName=\"urn:mace:dir:attribute-def:eduPersonScopedAffiliation\""
325                                 + "                                     matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\""
326                                 + "                                     matches=\"any\">.*@example\\.edu</Constraint>" 
327                                 + "             <Target>"
328                                 + "                 <AnyTarget/>" 
329                                 + "             </Target>"
330                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
331                                 + "                 <AnyValue release=\"permit\"/>" 
332                                 + "             </Attribute>" 
333                                 + "         </Rule>"
334                                 + " </AttributeReleasePolicy>";
335
336                 // Setup the engine
337                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
338                 factory.setValidating(false);
339                 factory.setNamespaceAware(true);
340                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
341                 
342                 Arp siteArp = new Arp();
343                 siteArp.marshall(doc.getDocumentElement());
344                 repository.update(siteArp);
345                 ArpEngine engine = new ArpEngine(repository);
346
347                 Principal principal = new LocalPrincipal("TestPrincipal");
348
349                 // test user who meets constraint
350                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
351                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
352                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonScopedAffiliation",
353                                 new Object[]{"member@example.edu"}));
354
355                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
356                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
357
358                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
359                 assertEquals("ARP application test 4a: ARP not applied as expected.", releaseSet1, inputSet1);
360
361                 // test user who does not meet constraint
362                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
363                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
364                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonScopedAffiliation",
365                                 new Object[]{"member@testshib.org"}));
366
367                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
368
369                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
370                 assertEquals("ARP application test 4b: ARP not applied as expected.", releaseSet2, inputSet2);
371
372         }
373
374         /**
375          * Use Case: must not have a specific attribute value Logical expression: not Px Example: release uid only if user
376          * does not have affiliation "student" (lack of attribute is permitted)
377          */
378         public void testArpConstraint5() throws Exception {
379
380                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
381                                 + "<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\">"
382                                 + "         <Rule>" 
383                                 + "             <Constraint"
384                                 + "                                     attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\""
385                                 + "                                     matches=\"none\">student</Constraint>" 
386                                 + "             <Target>"
387                                 + "                 <AnyTarget/>" 
388                                 + "             </Target>"
389                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
390                                 + "                 <AnyValue release=\"permit\"/>" 
391                                 + "             </Attribute>" 
392                                 + "         </Rule>"
393                                 + " </AttributeReleasePolicy>";
394
395                 // Setup the engine
396                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
397                 factory.setValidating(false);
398                 factory.setNamespaceAware(true);
399                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
400                 
401                 Arp siteArp = new Arp();
402                 siteArp.marshall(doc.getDocumentElement());
403                 repository.update(siteArp);
404                 ArpEngine engine = new ArpEngine(repository);
405
406                 Principal principal = new LocalPrincipal("TestPrincipal");
407
408                 // test user who meets constraint
409                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
410                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
411                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff"}));
412
413                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
414                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
415
416                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
417                 assertEquals("ARP application test 5a: ARP not applied as expected.", releaseSet1, inputSet1);
418
419                 // test another user who meets constraint
420                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
421                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
422
423                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
424                 releaseSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
425
426                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
427                 assertEquals("ARP application test 5b: ARP not applied as expected.", releaseSet2, inputSet2);
428
429                 // test user who does not meet constraint
430                 Collection<AAAttribute> inputSet3 = new ArrayList<AAAttribute>();
431                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
432                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff",
433                                 "student"}));
434
435                 Collection<AAAttribute> releaseSet3 = new ArrayList<AAAttribute>();
436
437                 engine.filterAttributes(inputSet3, principal, "shar.example.edu");
438                 assertEquals("ARP application test 5c: ARP not applied as expected.", releaseSet3, inputSet3);
439
440         }
441
442         /**
443          * Use case: must have at least one of multiple attribute values Logical expression: Px or Py Example: release uid
444          * only if user has affiliation of "faculty" or "staff"
445          */
446         public void testArpConstraint6() throws Exception {
447
448                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
449                                 + "<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\">"
450                                 + "         <Rule>" 
451                                 + "             <Constraint"
452                                 + "                                     attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\""
453                                 + "                                     matchFunction=\"urn:mace:shibboleth:arp:matchFunction:regexMatch\""
454                                 + "                                     matches=\"any\">(faculty|staff)</Constraint>" 
455                                 + "             <Target>"
456                                 + "                 <AnyTarget/>" 
457                                 + "             </Target>"
458                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
459                                 + "                 <AnyValue release=\"permit\"/>" 
460                                 + "             </Attribute>" 
461                                 + "         </Rule>"
462                                 + " </AttributeReleasePolicy>";
463
464                 // Setup the engine
465                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
466                 factory.setValidating(false);
467                 factory.setNamespaceAware(true);
468                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
469                 
470                 Arp siteArp = new Arp();
471                 siteArp.marshall(doc.getDocumentElement());
472                 repository.update(siteArp);
473                 ArpEngine engine = new ArpEngine(repository);
474
475                 Principal principal = new LocalPrincipal("TestPrincipal");
476
477                 // test user who meets constraint
478                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
479                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
480                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"faculty"}));
481
482                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
483                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
484
485                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
486                 assertEquals("ARP application test 6a: ARP not applied as expected.", releaseSet1, inputSet1);
487
488                 // test user who does not meet constraint
489                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
490                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
491                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"student"}));
492
493                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
494
495                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
496                 assertEquals("ARP application test 6b: ARP not applied as expected.", releaseSet2, inputSet2);
497
498         }
499
500         /**
501          * Use case: must have multiple specific values for the same attribute Logical expression: Px and Py Example:
502          * release uid only if user has entitlements "urn:x:foo" and "urn:x:bar"
503          */
504         public void testArpConstraint7() throws Exception {
505
506                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
507                                 + "<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\">"
508                                 + "         <Rule>"
509                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">urn:x:foo</Constraint>"
510                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">urn:x:bar</Constraint>"
511                                 + "             <Target>" 
512                                 + "                 <AnyTarget/>" 
513                                 + "             </Target>"
514                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
515                                 + "                 <AnyValue release=\"permit\"/>" 
516                                 + "             </Attribute>" 
517                                 + "         </Rule>"
518                                 + " </AttributeReleasePolicy>";
519
520                 // Setup the engine
521                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
522                 factory.setValidating(false);
523                 factory.setNamespaceAware(true);
524                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
525                 
526                 Arp siteArp = new Arp();
527                 siteArp.marshall(doc.getDocumentElement());
528                 repository.update(siteArp);
529                 ArpEngine engine = new ArpEngine(repository);
530
531                 Principal principal = new LocalPrincipal("TestPrincipal");
532
533                 // test user who meets constraint
534                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
535                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
536                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:foo",
537                                 "urn:x:bar"}));
538
539                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
540                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
541
542                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
543                 assertEquals("ARP application test 7a: ARP not applied as expected.", releaseSet1, inputSet1);
544
545                 // test user who does not meet constraint
546                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
547                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
548                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:foo"}));
549
550                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
551
552                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
553                 assertEquals("ARP application test 7b: ARP not applied as expected.", releaseSet2, inputSet2);
554
555         }
556
557         /**
558          * Use case: must have one specific attribute value, but cannot have another Logical expression: Px and not Py
559          * Example: release uid for all users who have an affilation of "staff" AND do not have an affiliation of "student"
560          */
561         public void testArpConstraint8() throws Exception {
562
563                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
564                                 + "<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\">"
565                                 + "         <Rule>"
566                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\" matches=\"any\">staff</Constraint>"
567                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\" matches=\"none\">student</Constraint>"
568                                 + "             <Target>" 
569                                 + "                 <AnyTarget/>" 
570                                 + "             </Target>"
571                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
572                                 + "                 <AnyValue release=\"permit\"/>" 
573                                 + "             </Attribute>" 
574                                 + "         </Rule>"
575                                 + " </AttributeReleasePolicy>";
576
577                 // Setup the engine
578                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
579                 factory.setValidating(false);
580                 factory.setNamespaceAware(true);
581                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
582                 
583                 Arp siteArp = new Arp();
584                 siteArp.marshall(doc.getDocumentElement());
585                 repository.update(siteArp);
586                 ArpEngine engine = new ArpEngine(repository);
587
588                 Principal principal = new LocalPrincipal("TestPrincipal");
589
590                 // test user who meets constraint
591                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
592                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
593                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff",
594                                 "faculty"}));
595
596                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
597                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
598
599                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
600                 assertEquals("ARP application test 8a: ARP not applied as expected.", releaseSet1, inputSet1);
601
602                 // test user who does not meet constraint
603                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
604                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
605                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff",
606                                 "student"}));
607
608                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
609
610                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
611                 assertEquals("ARP application test 8b: ARP not applied as expected.", releaseSet2, inputSet2);
612
613         }
614
615         /**
616          * Use case: must have an attribute value, but deny a specific one Logical expression: P and not Px Example: release
617          * uid for all users who have an affiliation (any value), but not for those that have an affiliation of "student"
618          * (lack of attribute is denied)
619          */
620         public void testArpConstraint9() throws Exception {
621
622                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
623                                 + "<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\">"
624                                 + "         <Rule>" 
625                                 + "             <Constraint"
626                                 + "                                     attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\""
627                                 + "                                     matchFunction=\"urn:mace:shibboleth:arp:matchFunction:anyValueMatch\" />"
628                                 + "             <Constraint" 
629                                 + "                                     attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\""
630                                 + "                                     matches=\"none\">student</Constraint>" 
631                                 + "             <Target>"
632                                 + "                 <AnyTarget/>" 
633                                 + "             </Target>"
634                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
635                                 + "                 <AnyValue release=\"permit\"/>" 
636                                 + "             </Attribute>" 
637                                 + "         </Rule>"
638                                 + " </AttributeReleasePolicy>";
639
640                 // Setup the engine
641                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
642                 factory.setValidating(false);
643                 factory.setNamespaceAware(true);
644                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
645                 
646                 Arp siteArp = new Arp();
647                 siteArp.marshall(doc.getDocumentElement());
648                 repository.update(siteArp);
649                 ArpEngine engine = new ArpEngine(repository);
650
651                 Principal principal = new LocalPrincipal("TestPrincipal");
652
653                 // test user who meets constraint
654                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
655                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
656                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff"}));
657
658                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
659                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
660
661                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
662                 assertEquals("ARP application test 9a: ARP not applied as expected.", releaseSet1, inputSet1);
663
664                 // test user who does not meet constraint
665                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
666                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
667                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff",
668                                 "student"}));
669
670                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
671
672                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
673                 assertEquals("ARP application test 9b: ARP not applied as expected.", releaseSet2, inputSet2);
674
675                 // test another user who does not meet constraint
676                 Collection<AAAttribute> inputSet3 = new ArrayList<AAAttribute>();
677                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
678
679                 Collection<AAAttribute> releaseSet3 = new ArrayList<AAAttribute>();
680
681                 engine.filterAttributes(inputSet3, principal, "shar.example.edu");
682                 assertEquals("ARP application test 9c: ARP not applied as expected.", releaseSet3, inputSet3);
683
684         }
685
686         /**
687          * Use case: must have specific values for two separate attributes Logical expression: Px and Qy Example: release
688          * uid only if user has entitlement "urn:x:foo" and has affiliation of "faculty"
689          */
690         public void testArpConstraint10() throws Exception {
691
692                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
693                                 + "<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\">"
694                                 + "         <Rule>"
695                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">urn:x:foo</Constraint>"
696                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">faculty</Constraint>"
697                                 + "             <Target>" 
698                                 + "                 <AnyTarget/>" 
699                                 + "             </Target>"
700                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
701                                 + "                 <AnyValue release=\"permit\"/>" 
702                                 + "             </Attribute>" 
703                                 + "         </Rule>"
704                                 + " </AttributeReleasePolicy>";
705
706                 // Setup the engine
707                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
708                 factory.setValidating(false);
709                 factory.setNamespaceAware(true);
710                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
711                 
712                 Arp siteArp = new Arp();
713                 siteArp.marshall(doc.getDocumentElement());
714                 repository.update(siteArp);
715                 ArpEngine engine = new ArpEngine(repository);
716
717                 Principal principal = new LocalPrincipal("TestPrincipal");
718
719                 // test user who meets constraint
720                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
721                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
722                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:foo"}));
723                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff",
724                                 "faculty"}));
725
726                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
727                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
728
729                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
730                 assertEquals("ARP application test 10a: ARP not applied as expected.", releaseSet1, inputSet1);
731
732                 // test user who does not meet constraint
733                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
734                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
735                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:foo"}));
736                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff",
737                                 "student"}));
738
739                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
740
741                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
742                 assertEquals("ARP application test 10b: ARP not applied as expected.", releaseSet2, inputSet2);
743
744         }
745
746         /**
747          * Use case: must have one attribute value or not a value for another attribute Logical expression: Px or not Qy
748          * Example: release uid only if user has an affiliation of "staff" or if the user does not have isPrivate equal to
749          * "Y"
750          */
751         public void testArpConstraint11() throws Exception {
752
753                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
754                                 + "<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\">"
755                                 + "         <Rule>"
756                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonAffiliation\">staff</Constraint>"
757                                 + "             <Target>"
758                                 + "                 <AnyTarget/>"
759                                 + "             </Target>"
760                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
761                                 + "                 <AnyValue release=\"permit\"/>"
762                                 + "             </Attribute>"
763                                 + "         </Rule>"
764                                 + "         <Rule>"
765                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:isPrivate\" matches=\"none\">Y</Constraint>"
766                                 + "             <Target>" 
767                                 + "                 <AnyTarget/>" 
768                                 + "             </Target>"
769                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
770                                 + "                 <AnyValue release=\"permit\"/>" 
771                                 + "             </Attribute>" 
772                                 + "         </Rule>"
773                                 + " </AttributeReleasePolicy>";
774
775                 // Setup the engine
776                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
777                 factory.setValidating(false);
778                 factory.setNamespaceAware(true);
779                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
780                 
781                 Arp siteArp = new Arp();
782                 siteArp.marshall(doc.getDocumentElement());
783                 repository.update(siteArp);
784                 ArpEngine engine = new ArpEngine(repository);
785
786                 Principal principal = new LocalPrincipal("TestPrincipal");
787
788                 // test user who meets constraint
789                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
790                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
791                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:isPrivate", new Object[]{"Y"}));
792                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"staff"}));
793
794                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
795                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
796
797                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
798                 assertEquals("ARP application test 11a: ARP not applied as expected.", releaseSet1, inputSet1);
799
800                 // test another user who meets constraint
801                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
802                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
803                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:isPrivate", new Object[]{"N"}));
804                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"student"}));
805
806                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
807                 releaseSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
808
809                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
810                 assertEquals("ARP application test 11a: ARP not applied as expected.", releaseSet2, inputSet2);
811
812                 // test user who does not meet constraint
813                 Collection<AAAttribute> inputSet3 = new ArrayList<AAAttribute>();
814                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
815                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:isPrivate", new Object[]{"Y"}));
816                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonAffiliation", new Object[]{"student"}));
817
818                 Collection<AAAttribute> releaseSet3 = new ArrayList<AAAttribute>();
819
820                 engine.filterAttributes(inputSet3, principal, "shar.example.edu");
821                 assertEquals("ARP application test 11c: ARP not applied as expected.", releaseSet3, inputSet3);
822
823         }
824
825         /**
826          * Use case: release additional attributes for a subset of users Example: release targetedId for all users with
827          * entitlement "urn:x:foo". also release uid for users without ferpaSuppression
828          */
829         public void testArpConstraint12() throws Exception {
830
831                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
832                                 + "<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\">"
833                                 + "         <Rule>"
834                                 + "             <Constraint attributeName=\"urn:mace:dir:attribute-def:eduPersonEntitlement\">urn:x:foo</Constraint>"
835                                 + "             <Target>" 
836                                 + "                 <AnyTarget/>" 
837                                 + "             </Target>"
838                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:eduPersonTargetedID\">"
839                                 + "                 <AnyValue release=\"permit\"/>" 
840                                 + "             </Attribute>" 
841                                 + "         </Rule>"
842                                 + "         <Rule>" 
843                                 + "             <Constraint"
844                                 + "                                     attributeName=\"urn:mace:dir:attribute-def:ferpaSuppression\""
845                                 + "                                     matchFunction=\"urn:mace:shibboleth:arp:matchFunction:anyValueMatch\""
846                                 + "                                     matches=\"none\" />" 
847                                 + "             <Target>" 
848                                 + "                 <AnyTarget/>"
849                                 + "             </Target>" 
850                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
851                                 + "                 <AnyValue release=\"permit\"/>" 
852                                 + "             </Attribute>" 
853                                 + "         </Rule>"
854                                 + " </AttributeReleasePolicy>";
855
856                 // Setup the engine
857                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
858                 factory.setValidating(false);
859                 factory.setNamespaceAware(true);
860                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
861                 
862                 Arp siteArp = new Arp();
863                 siteArp.marshall(doc.getDocumentElement());
864                 repository.update(siteArp);
865                 ArpEngine engine = new ArpEngine(repository);
866
867                 Principal principal = new LocalPrincipal("TestPrincipal");
868
869                 // test user who meets constraint
870                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
871                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
872                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonTargetedID",
873                                 new Object[]{"2b00042f7481c7b056c4b410d28f33cf"}));
874                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:foo"}));
875
876                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
877                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
878                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonTargetedID",
879                                 new Object[]{"2b00042f7481c7b056c4b410d28f33cf"}));
880
881                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
882                 assertEquals("ARP application test 12a: ARP not applied as expected.", releaseSet1, inputSet1);
883
884                 // test user who does not meet constraint
885                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
886                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
887                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonTargetedID",
888                                 new Object[]{"2b00042f7481c7b056c4b410d28f33cf"}));
889                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonEntitlement", new Object[]{"urn:x:foo"}));
890                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:ferpaSuppression", new Object[]{"2006-01-01"}));
891
892                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
893                 releaseSet2.add(new AAAttribute("urn:mace:dir:attribute-def:eduPersonTargetedID",
894                                 new Object[]{"2b00042f7481c7b056c4b410d28f33cf"}));
895
896                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
897                 assertEquals("ARP application test 12b: ARP not applied as expected.", releaseSet2, inputSet2);
898
899         }
900
901         /**
902          * Use Case: must have only a specific attribute value Example: release uid only if user has a specific value for
903          * attribute "foo", but not if it has other values
904          */
905         public void testArpConstraint13() throws Exception {
906
907                 String rawArp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
908                                 + "<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\">"
909                                 + "         <Rule>" 
910                                 + "             <Constraint"
911                                 + "                                     attributeName=\"urn:mace:dir:attribute-def:foo\""
912                                 + "                                     matchFunction=\"urn:mace:shibboleth:arp:matchFunction:stringMatch\""
913                                 + "                                     matches=\"all\">bar</Constraint>" 
914                                 + "             <Target>" 
915                                 + "                 <AnyTarget/>"
916                                 + "             </Target>" 
917                                 + "             <Attribute name=\"urn:mace:dir:attribute-def:uid\">"
918                                 + "                 <AnyValue release=\"permit\"/>" 
919                                 + "             </Attribute>" 
920                                 + "         </Rule>"
921                                 + " </AttributeReleasePolicy>";
922
923                 // Setup the engine
924                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
925                 factory.setValidating(false);
926                 factory.setNamespaceAware(true);
927                 Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(rawArp)));
928                 
929                 Arp siteArp = new Arp();
930                 siteArp.marshall(doc.getDocumentElement());
931                 repository.update(siteArp);
932                 ArpEngine engine = new ArpEngine(repository);
933
934                 Principal principal = new LocalPrincipal("TestPrincipal");
935
936                 // test user who meets constraint
937                 Collection<AAAttribute> inputSet1 = new ArrayList<AAAttribute>();
938                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
939                 inputSet1.add(new AAAttribute("urn:mace:dir:attribute-def:foo", new Object[]{"bar"}));
940
941                 Collection<AAAttribute> releaseSet1 = new ArrayList<AAAttribute>();
942                 releaseSet1.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
943
944                 engine.filterAttributes(inputSet1, principal, "shar.example.edu");
945                 assertEquals("ARP application test 3a: ARP not applied as expected.", releaseSet1, inputSet1);
946
947                 // test user who does not meet constraint
948                 Collection<AAAttribute> inputSet2 = new ArrayList<AAAttribute>();
949                 inputSet2.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
950
951                 Collection<AAAttribute> releaseSet2 = new ArrayList<AAAttribute>();
952
953                 engine.filterAttributes(inputSet2, principal, "shar.example.edu");
954                 assertEquals("ARP application test 3b: ARP not applied as expected.", releaseSet2, inputSet2);
955
956                 // test another user who does not meet constraint
957                 Collection<AAAttribute> inputSet3 = new ArrayList<AAAttribute>();
958                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:uid", new Object[]{"gpburdell"}));
959                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:foo", new Object[]{"bar"}));
960                 inputSet3.add(new AAAttribute("urn:mace:dir:attribute-def:foo", new Object[]{"baz"}));
961
962                 Collection<AAAttribute> releaseSet3 = new ArrayList<AAAttribute>();
963
964                 engine.filterAttributes(inputSet3, principal, "shar.example.edu");
965                 assertEquals("ARP application test 3c: ARP not applied as expected.", releaseSet3, inputSet3);
966
967         }
968 }