Added code to compute potential release sets. This can be used to avoid resolving...
authorwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Tue, 17 Dec 2002 21:01:02 +0000 (21:01 +0000)
committerwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Tue, 17 Dec 2002 21:01:02 +0000 (21:01 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@380 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/aa/arp/ArpEngine.java
src/edu/internet2/middleware/shibboleth/aa/arp/ArpTests.java
src/edu/internet2/middleware/shibboleth/aa/arp/Rule.java
src/edu/internet2/middleware/shibboleth/aa/arp/provider/MemoryArpRepository.java
test/arp7.xml [new file with mode: 0755]

index cced58c..f79d900 100755 (executable)
@@ -55,8 +55,10 @@ import java.net.URL;
 import java.security.Principal;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 
 import org.apache.log4j.Logger;
 
@@ -90,13 +92,17 @@ public class ArpEngine {
 
        public ArpEngine(Properties properties) throws ArpException {
                try {
-                       this.repository = ArpRepositoryFactory.getInstance(properties);
+                       repository = ArpRepositoryFactory.getInstance(properties);
                } catch (ArpRepositoryException e) {
                        log.error("Could not start Arp Engine: " + e);
                        throw new ArpException("Could not start Arp Engine.");
                }
        }
 
+       public ArpEngine(ArpRepository repository, Properties properties) throws ArpException {
+               this.repository = repository;
+       }
+
        public static MatchFunction lookupMatchFunction(URI functionIdentifier) throws ArpException {
                String className = null;
 
@@ -135,8 +141,8 @@ public class ArpEngine {
                        for (int i = 0; userPolicies.length > i; i++) {
                                Rule[] rules = userPolicies[i].getMatchingRules(requester, resource);
 
-                               for (int j = 0; rules.length > i; j++) {
-                                       effectiveArp.addRule(rules[i]);
+                               for (int j = 0; rules.length > j; j++) {
+                                       effectiveArp.addRule(rules[j]);
                                }
                        }
 
@@ -147,4 +153,27 @@ public class ArpEngine {
                }
        }
 
+       URI[] listPossibleReleaseAttributes(Principal principal, String requester, URL resource)
+               throws ArpProcessingException {
+               Set possibleReleaseSet = new HashSet();
+               Rule[] rules = createEffectiveArp(principal, requester, resource).getAllRules();
+               for (int i = 0; rules.length > i; i++) {
+                       Rule.Attribute[] attributes = rules[i].getAttributes();
+                       for (int j = 0; attributes.length > j; j++) {
+                               if (attributes[j].releaseAnyValue()) {
+                                       possibleReleaseSet.add(attributes[j].getName());
+                               } else {
+                                       Rule.AttributeValue[] values = attributes[j].getValues();
+                                       for (int k = 0; values.length > k; k++) {
+                                               if (values[k].getRelease().equals("permit")) {
+                                                       possibleReleaseSet.add(attributes[j].getName());
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return (URI[]) possibleReleaseSet.toArray(new URI[0]);
+       }
+
 }
index e83191b..dd440e1 100755 (executable)
@@ -55,6 +55,8 @@ import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.security.Principal;
+import java.util.Arrays;
 import java.util.Properties;
 
 import junit.framework.TestCase;
@@ -80,6 +82,8 @@ public class ArpTests extends TestCase {
                junit.textui.TestRunner.run(ArpTests.class);
                BasicConfigurator.configure();
        }
+       
+
 
        public void testArpMarshalling() {
 
@@ -374,4 +378,53 @@ public class ArpTests extends TestCase {
 
        }
 
+       public void testPossibleReleaseSetComputation() {
+               Properties props = new Properties();
+               props.setProperty(
+                       "edu.internet2.middleware.shibboleth.aa.arp.ArpRepository.implementation",
+                       "edu.internet2.middleware.shibboleth.aa.arp.provider.MemoryArpRepository");
+               ArpRepository repository = null;
+               try {
+                       repository = ArpRepositoryFactory.getInstance(props);
+               } catch (ArpRepositoryException e) {
+                       fail("Failed to create memory-based Arp Repository" + e);
+               }
+
+               try {
+                       Principal principal1 = new AAPrincipal("TestPrincipal");
+                       URL url1 = new URL("http://www.example.edu/");
+                       URI[] list1 = { new URI("urn:mace:eduPerson:1.0:eduPersonAffiliation")};
+                       URI[] list2 =
+                               {
+                                       new URI("urn:mace:eduPerson:1.0:eduPersonAffiliation"),
+                                       new URI("urn:mace:eduPerson:1.0:eduPersonPrincipalName")};
+                                       
+                       //Test with just a site ARP
+                       InputStream inStream = new FileInputStream("test/arp1.xml");
+                       DOMParser parser = new DOMParser();
+                       parser.parse(new InputSource(inStream));
+                       Arp arp1 = new Arp();
+                       arp1.marshall(parser.getDocument().getDocumentElement());
+                       repository.update(arp1);
+                       ArpEngine engine = new ArpEngine(repository, props);
+                       URI[] possibleAttributes =
+                               engine.listPossibleReleaseAttributes(principal1, "shar.example.edu", url1);
+                       assertTrue("Incorrectly computed possible release set.", Arrays.equals(possibleAttributes, list1));
+
+                       //Test with site and user ARPs
+                       inStream = new FileInputStream("test/arp7.xml");
+                       parser.parse(new InputSource(inStream));
+                       Arp arp7 = new Arp();
+                       arp7.setPrincipal(principal1);
+                       arp7.marshall(parser.getDocument().getDocumentElement());
+                       repository.update(arp7);
+                       possibleAttributes = engine.listPossibleReleaseAttributes(principal1, "shar.example.edu", url1);
+                       assertTrue("Incorrectly computed possible release set.", Arrays.equals(possibleAttributes, list2));
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       fail("Failed to marshall ARP: " + e);
+               }
+
+       }
+
 }
index 2f9982a..a67f37e 100755 (executable)
@@ -99,6 +99,10 @@ public class Rule {
         * Unmarshalls the <code>Rule</code> into an xml <code>Element</code>.
         * @return the xml <code>Element</code>
         */
+       
+       public Attribute[] getAttributes() {
+               return (Attribute[]) attributes.toArray(new Attribute[0]);      
+       }
 
        public Element unmarshall() {
 
@@ -339,39 +343,66 @@ public class Rule {
                private String anyValueRelease = "permit";
                private Set values = new HashSet();
 
+               boolean releaseAnyValue() {
+                       if (anyValueRelease.equals("permit")) {
+                               return anyValue;
+                       }
+                       return false;
+               }
+               
+               URI getName() {
+                       return name;    
+               }
+               AttributeValue[] getValues() {
+                       return (AttributeValue[]) values.toArray(new AttributeValue[0]);        
+               }
+
                void marshall(Element element) throws ArpMarshallingException {
                        //Make sure we are dealing with an Attribute
                        if (!element.getTagName().equals("Attribute")) {
                                log.error("Element data does not represent an ARP Rule Target.");
                                throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
                        }
-                       //Handle <AnyValue/> definitions
-                       NodeList anyValueNodeList = element.getElementsByTagName("AnyValue");
-                       if (anyValueNodeList.getLength() == 1) {
-                               anyValue = true;
-                               if (((Element) anyValueNodeList.item(0)).hasAttribute("release")) {
-                                       anyValueRelease = ((Element) anyValueNodeList.item(0)).getAttribute("release");
+
+                       //Get the attribute name
+                       try {
+                               if (element.hasAttribute("name")) {
+                                       name = new URI(element.getAttribute("name"));
+                               } else {
+                                       log.error("Attribute name not specified.");
+                                       throw new ArpMarshallingException("Attribute name not specified.");
                                }
+                       } catch (URISyntaxException e) {
+                               log.error("Attribute name not identified by a proper URI: " + e);
+                               throw new ArpMarshallingException("Attribute name not identified by a proper URI.");
                        }
 
-                       //Handle Value definitions
-                       NodeList valueNodeList = element.getElementsByTagName("Value");
-                       for (int i = 0; valueNodeList.getLength() > i; i++) {
-                               String release = null;
-                               String value = null;
-                               if (((Element) valueNodeList.item(i)).hasAttribute("release")) {
-                                       release = ((Element) valueNodeList.item(i)).getAttribute("release");
+                               //Handle <AnyValue/> definitions
+                               NodeList anyValueNodeList = element.getElementsByTagName("AnyValue");
+                               if (anyValueNodeList.getLength() == 1) {
+                                       anyValue = true;
+                                       if (((Element) anyValueNodeList.item(0)).hasAttribute("release")) {
+                                               anyValueRelease = ((Element) anyValueNodeList.item(0)).getAttribute("release");
+                                       }
                                }
-                               if (((Element) valueNodeList.item(i)).hasChildNodes()
-                                       && ((Element) valueNodeList.item(i)).getFirstChild().getNodeType() == Node.TEXT_NODE) {
-                                       value =
-                                               ((CharacterData) ((Element) valueNodeList.item(i)).getFirstChild()).getData();
+
+                               //Handle Value definitions
+                               NodeList valueNodeList = element.getElementsByTagName("Value");
+                               for (int i = 0; valueNodeList.getLength() > i; i++) {
+                                       String release = null;
+                                       String value = null;
+                                       if (((Element) valueNodeList.item(i)).hasAttribute("release")) {
+                                               release = ((Element) valueNodeList.item(i)).getAttribute("release");
+                                       }
+                                       if (((Element) valueNodeList.item(i)).hasChildNodes()
+                                               && ((Element) valueNodeList.item(i)).getFirstChild().getNodeType() == Node.TEXT_NODE) {
+                                               value = ((CharacterData) ((Element) valueNodeList.item(i)).getFirstChild()).getData();
+                                       }
+                                       AttributeValue aValue = new AttributeValue(release, value);
+                                       values.add(aValue);
                                }
-                               AttributeValue aValue = new AttributeValue(release, value);
-                               values.add(aValue);
-                       }
 
-               }
+                       }
        }
        class AttributeValue {
                private String release = "permit";
index 84e0b76..560d0aa 100755 (executable)
 package edu.internet2.middleware.shibboleth.aa.arp.provider;
 
 import java.security.Principal;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
@@ -80,8 +82,12 @@ public class MemoryArpRepository implements ArpRepository {
 
        public Arp[] getAllPolicies(Principal principal) throws ArpRepositoryException {
 
-               Set allPolicies = userPolicies.entrySet();
+               if (sitePolicy == null) {
+                       return (Arp[]) userPolicies.values().toArray(new Arp[0]);
+               }
+               Set allPolicies = new HashSet();
                allPolicies.add(sitePolicy);
+               allPolicies.addAll(userPolicies.values());
                return (Arp[]) allPolicies.toArray(new Arp[0]);
        }
 
diff --git a/test/arp7.xml b/test/arp7.xml
new file mode 100755 (executable)
index 0000000..6964f5c
--- /dev/null
@@ -0,0 +1,15 @@
+<AttributeReleasePolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ARP.xsd">
+       <Description>A specific SHAR and a regex resource.</Description>
+       <Rule>
+               <Target>
+                       <Requester>shar.example.edu</Requester>
+                       <Resource matchFunction="urn:mace:shibboleth:arp:matchFunction:regexMatch">^https?://.+\.example\.edu/.*$</Resource>
+               </Target>
+               <Attribute name="urn:mace:eduPerson:1.0:eduPersonPrincipalName">
+                       <AnyValue release="permit"/>
+               </Attribute>
+               <Attribute name="urn:mace:eduPerson:1.0:eduPersonAffiliation">
+                       <Value release="permit">member@example.edu</Value>
+               </Attribute>
+       </Rule>
+</AttributeReleasePolicy>
\ No newline at end of file