+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.] Licensed under the Apache License,
- * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy
- * of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in
- * writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
- * OF ANY KIND, either express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.xml.namespace.QName;
-
-import org.apache.log4j.Logger;
-import org.opensaml.SAMLAttribute;
-import org.opensaml.SAMLException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.aa.arp.ArpAttribute;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ValueHandler;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ValueHandlerException;
-
-/**
- * An attribute for which the Shibboleth Attribute Authority has been asked to provide an assertion.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class AAAttribute extends SAMLAttribute implements ResolverAttribute, ArpAttribute {
-
- private static Logger log = Logger.getLogger(AAAttribute.class.getName());
- private boolean resolved = false;
-
- /** Default lifetime, in seconds * */
- private static long defaultLifetime = 1800; // 30 minutes
- private ValueHandler valueHandler = new StringValueHandler();
-
- /**
- * Constructs a skeleton attribute with no values.
- *
- * @param name
- * the name of the attribute
- * @param legacyCompat
- * boolean indicator of whether or not the legacy namespace hack should be used (this is required for SPs
- * running old versions of xerces)
- * @throws SAMLException
- */
- public AAAttribute(String name, boolean legacyCompat) throws SAMLException {
-
- super(name, null, legacyCompat ? new QName("urn:mace:shibboleth:1.0", "AttributeValueType") : null,
- defaultLifetime, null);
- }
-
- /**
- * Constructs a skeleton attribute with no values.
- *
- * @param name
- * the name of the attribute
- * @throws SAMLException
- * if the attribute could not be created
- */
- public AAAttribute(String name) throws SAMLException {
-
- super(name, null, null, defaultLifetime, null);
- }
-
- public AAAttribute(String name, Object[] values) throws SAMLException {
-
- this(name);
- setValues(values);
- }
-
- public AAAttribute(String name, Object[] values, ValueHandler handler) throws SAMLException {
-
- this(name);
- setValues(values);
- registerValueHandler(handler);
- }
-
- public boolean hasValues() {
-
- if (values.isEmpty()) { return false; }
- return true;
- }
-
- public Iterator getValues() {
-
- return valueHandler.getValues(values);
- }
-
- public void setValues(Object[] values) {
-
- if (!this.values.isEmpty()) {
- this.values.clear();
- }
- List newList = Arrays.asList(values);
- if (newList.contains(null)) {
- newList.remove(null);
- }
- this.values.addAll(newList);
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- public int hashCode() {
-
- int code = 0;
- if (values != null) {
- Iterator iterator = values.iterator();
- while (iterator.hasNext()) {
- code += iterator.next().hashCode();
- }
- }
- return name.hashCode() + code;
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#resolved()
- */
- public boolean resolved() {
-
- return resolved;
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#setResolved()
- */
- public void setResolved() {
-
- resolved = true;
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#resolveFromCached(edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute)
- */
- public void resolveFromCached(ResolverAttribute attribute) {
-
- if (this == attribute) { return; }
-
- resolved = true;
- setLifetime(attribute.getLifetime());
-
- if (!this.values.isEmpty()) {
- this.values.clear();
- }
- for (Iterator iterator = attribute.getValues(); iterator.hasNext();) {
- values.add(iterator.next());
- }
-
- registerValueHandler(attribute.getRegisteredValueHandler());
- }
-
- public void setLifetime(long lifetime) {
-
- this.lifetime = lifetime;
-
- }
-
- public void addValue(Object value) {
-
- if (value != null) {
- values.add(value);
- }
- }
-
- /*
- * @see org.opensaml.SAMLAttribute#valueToDOM(int, org.w3c.dom.Element)
- */
- protected void valueToDOM(int index, Element e) throws SAMLException {
-
- try {
- valueHandler.toDOM(e, values.get(index), e.getOwnerDocument());
-
- } catch (ValueHandlerException ex) {
- log.error("Value Handler unable to convert value to DOM Node: " + ex);
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#registerValueHandler(edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ValueHandler)
- */
- public void registerValueHandler(ValueHandler handler) {
-
- valueHandler = handler;
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#getRegisteredValueHandler()
- */
- public ValueHandler getRegisteredValueHandler() {
-
- return valueHandler;
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals(Object object) {
-
- if (!(object instanceof AAAttribute)) { return false; }
- if (lifetime != ((AAAttribute) object).lifetime) { return false; }
- if (!name.equals(((AAAttribute) object).name)) { return false; }
- if (!valueHandler.equals(((AAAttribute) object).valueHandler)) { return false; }
-
- ArrayList localValues = new ArrayList();
- for (Iterator iterator = getValues(); iterator.hasNext();) {
- localValues.add(iterator.next());
- }
-
- ArrayList objectValues = new ArrayList();
- for (Iterator iterator = ((AAAttribute) object).getValues(); iterator.hasNext();) {
- objectValues.add(iterator.next());
- }
-
- return localValues.equals(objectValues);
- }
-
-}
-
-/**
- * Default <code>ValueHandler</code> implementation. Expects all values to be String objects.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-class StringValueHandler implements ValueHandler {
-
- public void toDOM(Element valueElement, Object value, Document document) {
-
- valueElement.appendChild(document.createTextNode(value.toString()));
- }
-
- public Iterator getValues(Collection internalValues) {
-
- return internalValues.iterator();
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals(Object object) {
-
- if (object instanceof StringValueHandler) { return true; }
- return false;
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa;
-
-/**
- * Attribute Authority & Release Policy General Exception for AA problems
- *
- * @author Parviz Dousti (dousti@cmu.edu)
- * @created June, 2002
- */
-
-public class AAException extends Exception {
-
- public AAException(String s) {
-
- super(s);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.CharacterData;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * An Attribute Release Policy.
- *
- * @author Walter Hoehn (wassa@memphis.edu)
- */
-
-public class Arp {
-
- public static final String arpNamespace = "urn:mace:shibboleth:arp:1.0";
- private Principal principal;
- private List<Rule> rules = new ArrayList<Rule>();
- private String description;
- private boolean sitePolicy = false;
- private static Logger log = Logger.getLogger(Arp.class.getName());
- private List<Node> attributes = new ArrayList<Node>();
-
- private NodeList ruleReferences;
-
- /**
- * Creates an Arp for the specified <code>Principal</code>.
- */
-
- public Arp(Principal principal) {
-
- this.principal = principal;
- }
-
- /**
- * Creates a "Site" Policy.
- */
-
- public Arp() {
-
- sitePolicy = true;
- }
-
- /**
- * Boolean indication of whether or not this Policy is a "Site" policy.
- */
-
- public boolean isSitePolicy() {
-
- return sitePolicy;
- }
-
- /**
- * Returns the <code>Principal</code> for which this policy is applicable.
- *
- * @return Principal
- */
-
- public Principal getPrincipal() {
-
- return principal;
- }
-
- /**
- * Specify the <code>Principal</code> for which this policy is applicable.
- *
- * @param principal
- * The principal
- */
-
- public void setPrincipal(Principal principal) {
-
- sitePolicy = false;
- this.principal = principal;
- }
-
- /**
- * Creates an ARP structure from an xml representation.
- *
- * @param the
- * xml <code>Element</code> containing the ARP structure.
- */
-
- public void marshall(Element xmlElement) throws ArpMarshallingException {
-
- // Make sure we are deling with an ARP
- if (!xmlElement.getTagName().equals("AttributeReleasePolicy")) { throw new ArpMarshallingException(
- "Element data does not represent an ARP."); }
-
- // Grab the description
- NodeList descriptionNodes = xmlElement.getElementsByTagNameNS(arpNamespace, "Description");
- if (descriptionNodes.getLength() > 0) {
- Element descriptionNode = (Element) descriptionNodes.item(0);
- if (descriptionNode.hasChildNodes() && descriptionNode.getFirstChild().getNodeType() == Node.TEXT_NODE) {
- description = ((CharacterData) descriptionNode.getFirstChild()).getData();
- }
- }
-
- // Grab all of the Rule Elements and marshall them
- NodeList ruleNodes = xmlElement.getElementsByTagNameNS(arpNamespace, "Rule");
- if (ruleNodes.getLength() > 0) {
- for (int i = 0; i < ruleNodes.getLength(); i++) {
- Rule rule = new Rule();
- try {
- rule.marshall((Element) ruleNodes.item(i));
- } catch (ArpMarshallingException me) {
- throw new ArpMarshallingException("Encountered a problem marshalling ARP Rules: " + me);
- }
- rules.add(rule);
- }
-
- }
-
- // Retain Rule references
- // Not enforced!
- NodeList ruleReferenceNodes = xmlElement.getElementsByTagNameNS(arpNamespace, "RuleReference");
- if (ruleReferenceNodes.getLength() > 0) {
- log.warn("Encountered a Rule Reference while marshalling an ARP. "
- + "References are currently unsupported by the ARP Engine. Ignoring...");
- ruleReferences = ruleReferenceNodes;
- }
-
- // Retain attributes declared outside the scope of a rule
- // Not enforced!
- NodeList attributeNodes = xmlElement.getElementsByTagNameNS(Arp.arpNamespace, "Attribute");
- if (attributeNodes.getLength() > 0) {
- for (int i = 0; i < attributeNodes.getLength(); i++) {
- if (attributeNodes.item(i).getParentNode() == xmlElement) {
- log.warn("Encountered an Attribute definition outside the scope of a Rule "
- + "definition while marshalling an ARP. "
- + "References are currently unsupported by the ARP Engine. Ignoring...");
- attributes.add(attributeNodes.item(i));
- }
- }
- }
- }
-
- /**
- * Unmarshalls the <code>Arp</code> into an xml <code>Element</code>.
- *
- * @return the xml <code>Element</code>
- */
-
- public Element unmarshall() throws ArpMarshallingException {
-
- try {
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- docFactory.setNamespaceAware(true);
- Document placeHolder = docFactory.newDocumentBuilder().newDocument();
-
- Element policyNode = placeHolder.createElementNS(arpNamespace, "AttributeReleasePolicy");
- policyNode.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", arpNamespace);
- policyNode.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xsi",
- "http://www.w3.org/2001/XMLSchema-instance");
- policyNode.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "xsi:schemaLocation",
- "urn:mace:shibboleth:arp:1.0 shibboleth-arp-1.0.xsd");
- if (description != null) {
- Element descriptionNode = placeHolder.createElementNS(arpNamespace, "Description");
- descriptionNode.appendChild(placeHolder.createTextNode(description));
- policyNode.appendChild(descriptionNode);
- }
-
- Collection<Rule> rules = getAllRules();
- for (Rule rule : rules) {
- policyNode.appendChild(placeHolder.importNode(rule.unmarshall(), true));
- }
-
- if (ruleReferences != null) {
- for (int i = 0; i < ruleReferences.getLength(); i++) {
- policyNode.appendChild(placeHolder.importNode(ruleReferences.item(i), true));
- }
- }
-
- Iterator attrIterator = attributes.iterator();
- while (attrIterator.hasNext()) {
- policyNode.appendChild(placeHolder.importNode((Node) attrIterator.next(), true));
- }
-
- return policyNode;
-
- } catch (ParserConfigurationException e) {
- log.error("Encountered a problem unmarshalling an ARP: " + e);
- throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP.");
- }
-
- }
-
- /**
- * Returns all of the <code>Rule</code> objects that make up this policy.
- *
- * @return the rules
- */
-
- public Collection<Rule> getAllRules() {
-
- return rules;
- }
-
- /**
- * Returns the description for this <code>Arp</code> or null if no description is set.
- *
- * @return String
- */
-
- public String getDescription() {
-
- return description;
- }
-
- /**
- * Sets the description for this <code>Arp</code>.
- *
- * @param description
- * The description to set
- */
-
- public void setDescription(String description) {
-
- this.description = description;
- }
-
- /**
- * Finds all of the rules contained in the <code>Arp</code> object that are applicable to a particular request.
- *
- * @param requester
- * the SHAR for this request
- * @param attributes
- * ARP attributes of the user
- * @return the matching <code>Rule</code> objects
- */
- public Collection<Rule> getMatchingRules(String requester, Collection<? extends ArpAttribute> attributes) {
-
- List<Rule> effectiveSet = new ArrayList<Rule>();
- Iterator iterator = rules.iterator();
- while (iterator.hasNext()) {
- Rule rule = (Rule) iterator.next();
- if (rule.matchesRequest(requester, attributes)) {
- effectiveSet.add(rule);
- }
- }
- return effectiveSet;
- }
-
- /**
- * Adds an ARP Rule to this <code>ARP</code>.
- *
- * @param rule
- * the <code>Rule</code> to add
- */
- public void addRule(Rule rule) {
-
- rules.add(rule);
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-import java.util.Iterator;
-
-/**
- * Defines an attribute whose values can be filtered by the <code>ArpEngine</code>.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public interface ArpAttribute {
-
- public String getName();
-
- public void setValues(Object[] value);
-
- public Iterator getValues();
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-import java.io.StringWriter;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Text;
-
-import edu.internet2.middleware.shibboleth.idp.IdPConfig;
-
-/**
- * Defines a processing engine for Attribute Release Policies.
- *
- * @author Walter Hoehn (wassa@memphis.edu)
- */
-
-public class ArpEngine {
-
- private static Logger log = Logger.getLogger(ArpEngine.class.getName());
- private ArpRepository repository;
- private static Map<URI, String> matchFunctions = Collections.synchronizedMap(new HashMap<URI, String>());
- static {
- // Initialize built-in match functions
- try {
-
- // Current
- matchFunctions.put(new URI("urn:mace:shibboleth:arp:matchFunction:regexMatch"),
- "edu.internet2.middleware.shibboleth.aa.arp.provider.RegexMatchFunction");
- matchFunctions.put(new URI("urn:mace:shibboleth:arp:matchFunction:regexNotMatch"),
- "edu.internet2.middleware.shibboleth.aa.arp.provider.RegexNotMatchFunction");
- matchFunctions.put(new URI("urn:mace:shibboleth:arp:matchFunction:stringMatch"),
- "edu.internet2.middleware.shibboleth.aa.arp.provider.StringValueMatchFunction");
- matchFunctions.put(new URI("urn:mace:shibboleth:arp:matchFunction:stringNotMatch"),
- "edu.internet2.middleware.shibboleth.aa.arp.provider.StringValueNotMatchFunction");
- matchFunctions.put(new URI("urn:mace:shibboleth:arp:matchFunction:anyValueMatch"),
- "edu.internet2.middleware.shibboleth.aa.arp.provider.AnyValueMatchFunction");
-
- } catch (URISyntaxException e) {
- log.error("Error mapping standard match functions: " + e);
- }
- }
-
- /**
- * Loads Arp Engine with default configuration
- *
- * @throws ArpException
- * if engine cannot be loaded
- */
- public ArpEngine(Element config) throws ArpException {
-
- if (!config.getLocalName().equals("ReleasePolicyEngine")) { throw new IllegalArgumentException(); }
-
- NodeList itemElements = config.getElementsByTagNameNS(IdPConfig.configNameSpace, "ArpRepository");
-
- if (itemElements.getLength() > 1) {
- log
- .warn("Encountered multiple <ArpRepository> configuration elements. Arp Engine currently only supports one. Using first...");
- }
-
- if (itemElements.getLength() == 0) {
- log.error("No <ArpRepsitory/> specified for this Arp Endine.");
- throw new ArpException("Could not start Arp Engine.");
- }
-
- try {
- repository = ArpRepositoryFactory.getInstance((Element) itemElements.item(0));
- } catch (ArpRepositoryException e) {
- log.error("Could not start Arp Engine: " + e);
- throw new ArpException("Could not start Arp Engine.");
- }
- }
-
- public ArpEngine(ArpRepository preLoadedRepository) throws ArpException {
-
- repository = preLoadedRepository;
- }
-
- /**
- * Loads Arp Engine based on XML configurationf
- *
- * @throws ArpException
- * if configuration is invalid or there is a problem loading the engine
- */
- public ArpEngine() throws ArpException {
-
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- docFactory.setNamespaceAware(true);
- Document placeHolder;
- try {
- placeHolder = docFactory.newDocumentBuilder().newDocument();
-
- Element defRepository = placeHolder.createElementNS(IdPConfig.configNameSpace, "ArpRepository");
- defRepository.setAttributeNS(IdPConfig.configNameSpace, "implementation",
- "edu.internet2.middleware.shibboleth.aa.arp.provider.FileSystemArpRepository");
-
- Element path = placeHolder.createElementNS(IdPConfig.configNameSpace, "Path");
- Text text = placeHolder.createTextNode("/conf/arps/");
- path.appendChild(text);
-
- defRepository.appendChild(path);
-
- repository = ArpRepositoryFactory.getInstance(defRepository);
-
- } catch (ArpRepositoryException e) {
- log.error("Could not start Arp Engine: " + e);
- throw new ArpException("Could not start Arp Engine.");
- } catch (ParserConfigurationException e) {
- log.error("Problem loading parser to create default Arp Engine configuration: " + e);
- throw new ArpException("Could not start Arp Engine.");
- }
- }
-
- public static MatchFunction lookupMatchFunction(URI functionIdentifier) throws ArpException {
-
- String className = null;
-
- synchronized (matchFunctions) {
- className = (String) matchFunctions.get(functionIdentifier);
- }
-
- if (className == null) { return null; }
- try {
- Class matchFunction = Class.forName(className);
- Object functionObject = matchFunction.newInstance();
- if (functionObject instanceof MatchFunction) {
- return (MatchFunction) functionObject;
- } else {
- log.error("Improperly specified match function, (" + className + ") is not a match function.");
- throw new ArpException("Improperly specified match function, (" + className
- + ") is not a match function.");
- }
- } catch (Exception e) {
- log.error("Could not load Match Function: (" + className + "): " + e);
- throw new ArpException("Could not load Match Function.");
- }
- }
-
- private Arp createEffectiveArp(Principal principal, String requester) throws ArpProcessingException {
-
- return createEffectiveArp(principal, requester, null);
- }
-
- private Arp createEffectiveArp(Principal principal, String requester, Collection<? extends ArpAttribute> attributes)
- throws ArpProcessingException {
-
- try {
- Arp effectiveArp = new Arp(principal);
- effectiveArp.setDescription("Effective ARP.");
-
- Arp[] userPolicies = repository.getAllPolicies(principal);
-
- if (log.isDebugEnabled()) {
- log.debug("Creating effective ARP from (" + userPolicies.length + ") polic(y|ies).");
- try {
- for (int i = 0; userPolicies.length > i; i++) {
-
- TransformerFactory factory = TransformerFactory.newInstance();
- DOMSource source = new DOMSource(userPolicies[i].unmarshall());
- Transformer transformer = factory.newTransformer();
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- StringWriter stringWriter = new StringWriter();
- StreamResult result = new StreamResult(stringWriter);
- transformer.transform(source, result);
- log.debug("Dumping ARP:" + System.getProperty("line.separator") + stringWriter.toString());
- }
-
- } catch (Exception e) {
- log.error("Encountered a strange error while writing ARP debug "
- + "messages. This should never happen.");
- }
- }
-
- for (int i = 0; userPolicies.length > i; i++) {
- Collection<Rule> rules = userPolicies[i].getMatchingRules(requester, attributes);
-
- for (Rule rule : rules) {
- effectiveArp.addRule(rule);
- }
- }
- return effectiveArp;
-
- } catch (ArpRepositoryException e) {
- log.error("Error creating effective policy: " + e);
- throw new ArpProcessingException("Error creating effective policy.");
- }
- }
-
- /**
- * Determines which attributes MIGHT be releasable for a given request. This function may be used to determine which
- * attributes to resolve when a request for all attributes is made. This is done for performance reasons only. ie:
- * The resulting attributes must still be filtered before release.
- *
- * @return an array of <code>URI</code> objects that name the possible attributes
- */
- public Set<URI> listPossibleReleaseAttributes(Principal principal, String requester) throws ArpProcessingException {
-
- Set<URI> possibleReleaseSet = new HashSet<URI>();
- Set<URI> anyValueDenies = new HashSet<URI>();
- Collection<Rule> rules = createEffectiveArp(principal, requester).getAllRules();
- for (Rule rule : rules) {
- Collection<Rule.Attribute> attributes = rule.getAttributes();
- for (Rule.Attribute attribute : attributes) {
- if (attribute.releaseAnyValue()) {
- possibleReleaseSet.add(attribute.getName());
- } else if (attribute.denyAnyValue()) {
- anyValueDenies.add(attribute.getName());
- } else {
- Collection<Rule.AttributeValue> values = attribute.getValues();
- for (Rule.AttributeValue value : values) {
- if (value.getRelease().equals("permit")) {
- possibleReleaseSet.add(attribute.getName());
- break;
- }
- }
- }
- }
- }
- possibleReleaseSet.removeAll(anyValueDenies);
- if (log.isDebugEnabled()) {
- log.debug("Computed possible attribute release set.");
- Iterator iterator = possibleReleaseSet.iterator();
- while (iterator.hasNext()) {
- log.debug("Possible attribute: " + iterator.next().toString());
- }
- }
- return possibleReleaseSet;
- }
-
- /**
- * Given an attribute request and a set of attributes that are planned to be resolved (either those specified in the
- * request or the result of listPossibleReleaseAttributes()), determine what attributes may need to be resolved in
- * order to properly evaluate any applicable constraints.
- */
- public Set<URI> listRequiredConstraintAttributes(Principal principal, String requester,
- Collection<URI> attributeNames) throws ArpProcessingException {
-
- HashSet<URI> constraintAttributes = new HashSet<URI>();
-
- Collection<Rule> rules = createEffectiveArp(principal, requester).getAllRules();
- ArpRules : for (Rule rule : rules) {
- for (Rule.Attribute attr : rule.getAttributes()) {
- if (attributeNames.contains(attr.getName())) {
- // this rule deals with an attribute we might care about, so add the constraint attributes
- for (Rule.Constraint constraint : rule.getConstraints()) {
- constraintAttributes.add(constraint.getAttributeName());
- }
-
- // we have the constraint attributes, move on to the next rule
- continue ArpRules;
- }
- }
-
- }
-
- return constraintAttributes;
- }
-
- /**
- * Applies all applicable ARPs to a set of attributes.
- *
- * @return the attributes to be released
- */
- public void filterAttributes(Collection<? extends ArpAttribute> attributes, Principal principal, String requester)
- throws ArpProcessingException {
-
- if (attributes.isEmpty()) {
- log.debug("ARP Engine was asked to apply filter to empty attribute set.");
- return;
- }
-
- log.info("Applying Attribute Release Policies.");
- if (log.isDebugEnabled()) {
- log.debug("Processing the following attributes:");
- for (Iterator<? extends ArpAttribute> attrIterator = attributes.iterator(); attrIterator.hasNext();) {
- log.debug("Attribute: (" + attrIterator.next().getName() + ")");
- }
- }
-
- // Gather all applicable ARP attribute specifiers
- Set<String> attributeNames = new HashSet<String>();
- for (Iterator<? extends ArpAttribute> nameIterator = attributes.iterator(); nameIterator.hasNext();) {
- attributeNames.add(nameIterator.next().getName());
- }
- Collection<Rule> rules = createEffectiveArp(principal, requester, attributes).getAllRules();
- Set<Rule.Attribute> applicableRuleAttributes = new HashSet<Rule.Attribute>();
- for (Rule rule : rules) {
- Collection<Rule.Attribute> ruleAttributes = rule.getAttributes();
- for (Rule.Attribute ruleAttribute : ruleAttributes) {
- if (attributeNames.contains(ruleAttribute.getName().toString())) {
- applicableRuleAttributes.add(ruleAttribute);
- }
- }
- }
-
- // Canonicalize specifiers
- Map arpAttributeSpecs = createCanonicalAttributeSpec((Rule.Attribute[]) applicableRuleAttributes
- .toArray(new Rule.Attribute[0]));
-
- // Filter
- for (Iterator<? extends ArpAttribute> returnIterator = attributes.iterator(); returnIterator.hasNext();) {
-
- ArpAttribute arpAttribute = returnIterator.next();
- Rule.Attribute attribute = (Rule.Attribute) arpAttributeSpecs.get(arpAttribute.getName());
-
- // Handle no specifier
- if (attribute == null) {
- returnIterator.remove();
- continue;
- }
-
- // Handle Deny All
- if (attribute.denyAnyValue()) {
- returnIterator.remove();
- continue;
- }
-
- // Handle Permit All
- if (attribute.releaseAnyValue() && attribute.getValues().size() == 0) {
- continue;
- }
-
- // Handle "Permit All-Except" and "Permit Specific"
- ArrayList<Object> releaseValues = new ArrayList<Object>();
- for (Iterator valueIterator = arpAttribute.getValues(); valueIterator.hasNext();) {
- Object value = valueIterator.next();
- if (attribute.isValuePermitted(value)) {
- releaseValues.add(value);
- }
- }
-
- if (!releaseValues.isEmpty()) {
- arpAttribute.setValues((Object[]) releaseValues.toArray(new Object[0]));
- } else {
- returnIterator.remove();
- }
-
- }
- }
-
- private Map<String, Rule.Attribute> createCanonicalAttributeSpec(Rule.Attribute[] attributes) {
-
- Map<String, Rule.Attribute> canonicalSpec = new HashMap<String, Rule.Attribute>();
- for (int i = 0; attributes.length > i; i++) {
- if (!canonicalSpec.containsKey(attributes[i].getName().toString())) {
- canonicalSpec.put(attributes[i].getName().toString(), attributes[i]);
- } else {
- if (((Rule.Attribute) canonicalSpec.get(attributes[i].getName().toString())).denyAnyValue()) {
- continue;
- }
- if (attributes[i].denyAnyValue()) {
- ((Rule.Attribute) canonicalSpec.get(attributes[i].getName().toString())).setAnyValueDeny(true);
- continue;
- }
- if (attributes[i].releaseAnyValue()) {
- ((Rule.Attribute) canonicalSpec.get(attributes[i].getName().toString())).setAnyValuePermit(true);
- }
- Collection<Rule.AttributeValue> values = attributes[i].getValues();
- for (Rule.AttributeValue value : values) {
- ((Rule.Attribute) canonicalSpec.get(attributes[i].getName().toString())).addValue(value);
- }
- }
- }
- return canonicalSpec;
- }
-
- /**
- * Cleanup resources that won't be released when this object is garbage-collected
- */
- public void destroy() {
-
- repository.destroy();
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-/**
- * A generic error occurred relating to Attribute Release Policies
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class ArpException extends Exception {
-
- public ArpException(String message) {
-
- super(message);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-/**
- * Indicates an error occurred while marshalling/unmarshalling an ARP construct.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public class ArpMarshallingException extends ArpException {
-
- public ArpMarshallingException(String message) {
-
- super(message);
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-/**
- * Indicates an error occurred while evaluating one or more Attribute Release Policies.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class ArpProcessingException extends ArpException {
-
- public ArpProcessingException(String message) {
-
- super(message);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-import java.security.Principal;
-
-/**
- * Defines interaction with an <code>Arp</code> storage/retrieval mechanism.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public interface ArpRepository {
-
- /**
- * Searches the repository for all Attribute Release Policies associated with the named <code>Principal</code>
- *
- * @return instances of <code>Arp</code> or null if no associated policies are found in the repository
- */
-
- public Arp[] getAllPolicies(Principal principal) throws ArpRepositoryException;
-
- /**
- * Retrieves the "User" Attribute Release Policy associated with the named <code>Principal</code>
- *
- * @return aninstance of <code>Arp</code> or null if no User policy is found in the repository for the
- * <code>Principal</code>
- */
-
- public Arp getUserPolicy(Principal principal) throws ArpRepositoryException;
-
- /**
- * Retrieves the "Site" Attribute Release Policy
- *
- * @return an instance of <code>Arp</code> or null if no Site policy is defined in the repository
- */
-
- public Arp getSitePolicy() throws ArpRepositoryException;
-
- /**
- * If a matching <code>Arp</code> is found in the repository, it is replaced with the specified <code>Arp</code>.
- * If not, the <code>Arp</code> is added to the repository.
- */
-
- public void update(Arp arp) throws ArpRepositoryException;
-
- /**
- * Removes the specified <code>Arp</code> from the repository if it exists
- */
-
- public void remove(Arp arp) throws ArpRepositoryException;
-
- /**
- * Cleanup resources that won't be released when this object is garbage-collected
- */
- public void destroy();
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-/**
- * Indicates an error occurred while manipulating an instance of <code>ArpRepository</code>
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public class ArpRepositoryException extends ArpException {
-
- public ArpRepositoryException(String message) {
-
- super(message);
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-import java.lang.reflect.Constructor;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-
-/**
- * Factory for generating instances of <code>ArpRepository</code>. Configuration is delegated to the Arp Repository.
- * Runtime options are passed to concrete constructors via an <ArpRepository/>element.
- *
- * @author Parviz Dousti (dousti@cmu.edu)
- * @created June, 2002
- */
-
-public class ArpRepositoryFactory {
-
- private static Logger log = Logger.getLogger(ArpRepositoryFactory.class.getName());
-
- public static ArpRepository getInstance(Element repositoryConfig) throws ArpRepositoryException {
-
- if (repositoryConfig.getAttribute("implementation") == null) { throw new ArpRepositoryException(
- "No ARP Repository implementaiton specified."); }
- try {
- Class implementorClass = Class.forName(repositoryConfig.getAttribute("implementation"));
- Class[] params = new Class[1];
- params[0] = Class.forName("org.w3c.dom.Element");
- Constructor implementorConstructor = implementorClass.getConstructor(params);
- Object[] args = new Object[1];
- args[0] = repositoryConfig;
- log.debug("Initializing Arp Repository of type (" + implementorClass.getName() + ").");
- return (ArpRepository) implementorConstructor.newInstance(args);
-
- } catch (NoSuchMethodException nsme) {
- log.error("Failed to instantiate an Arp Repository: ArpRepository "
- + "implementation must contain a constructor that accepts an <ArpRepository> element as "
- + "configuration data.");
- throw new ArpRepositoryException("Failed to instantiate an Arp Repository.");
- } catch (Exception e) {
- log.error("Failed to instantiate an Arp Repository: " + e);
- throw new ArpRepositoryException("Failed to instantiate an Arp Repository: " + e.getMessage());
-
- }
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-/**
- * Defines an method for determining whether an ARP Rule is applicable to a particular request
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public interface MatchFunction {
-
- /**
- * Boolean indication of whether the specified ARP component matches the specified Request component. Used to
- * determine if an ARP is applicable to a particular request.
- */
- public boolean match(Object arpComponent, Object requestComponent) throws MatchingException;
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-/**
- * Signals that an error occurred while processing an ARP match function.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class MatchingException extends ArpException {
-
- public MatchingException(String message) {
-
- super(message);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.CharacterData;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Text;
-
-/**
- * An Attribute Release Policy Rule.
- *
- * @author Walter Hoehn (wassa@memphis.edu)
- */
-
-public class Rule {
-
- private String description;
- private Target target;
- private static Logger log = Logger.getLogger(Rule.class.getName());
- private ArrayList<Attribute> attributes = new ArrayList<Attribute>();
- private ArrayList<Constraint> constraints = new ArrayList<Constraint>();
- private NodeList attributeReferences;
-
- private URI identifier;
-
- /**
- * Returns the description for this <code>Rule</code>.
- *
- * @return String
- */
-
- public String getDescription() {
-
- return description;
- }
-
- /**
- * Sets the description for this <code>Rule</code>.
- *
- * @param description
- * The description to set
- */
-
- public void setDescription(String description) {
-
- this.description = description;
- }
-
- /**
- * Returns all of the attribute specifications associated with this Rule.
- *
- * @return the attributes
- */
-
- public Collection<Attribute> getAttributes() {
-
- return attributes;
- }
-
- /**
- * Returns all of the constraint specifications associated with this Rule.
- *
- * @return the constraints
- */
-
- public Collection<Constraint> getConstraints() {
-
- return constraints;
- }
-
- /**
- * Unmarshalls the <code>Rule</code> into an xml <code>Element</code>.
- *
- * @return the xml <code>Element</code>
- */
-
- public Element unmarshall() throws ArpMarshallingException {
-
- try {
- Document placeHolder = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
- Element ruleNode = placeHolder.createElementNS(Arp.arpNamespace, "Rule");
-
- if (identifier != null) {
- ruleNode.setAttributeNS(null, "identifier", identifier.toString());
- }
-
- if (description != null) {
- Element descriptionNode = placeHolder.createElementNS(Arp.arpNamespace, "Description");
- descriptionNode.appendChild(placeHolder.createTextNode(description));
- ruleNode.appendChild(descriptionNode);
- }
-
- for (Constraint constraint : constraints) {
- ruleNode.appendChild(placeHolder.importNode(constraint.unmarshall(), true));
- }
-
- ruleNode.appendChild(placeHolder.importNode(target.unmarshall(), true));
- Iterator attrIterator = attributes.iterator();
- while (attrIterator.hasNext()) {
- ruleNode.appendChild(placeHolder.importNode(((Attribute) attrIterator.next()).unmarshall(), true));
- }
-
- if (attributeReferences != null) {
- for (int i = 0; i < attributeReferences.getLength(); i++) {
- ruleNode.appendChild(placeHolder.importNode(attributeReferences.item(i), true));
- }
- }
- return ruleNode;
- } catch (ParserConfigurationException e) {
- log.error("Encountered a problem unmarshalling an ARP Rule: " + e);
- throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule.");
- }
- }
-
- /**
- * Creates an ARP Rule from an xml representation.
- *
- * @param element
- * the xml <code>Element</code> containing the ARP Rule.
- */
-
- public void marshall(Element element) throws ArpMarshallingException {
-
- // Make sure we are dealing with a Rule
- if (!element.getTagName().equals("Rule")) {
- log.error("Element data does not represent an ARP Rule.");
- throw new ArpMarshallingException("Element data does not represent an ARP Rule.");
- }
-
- // Get the rule identifier
- try {
- if (element.hasAttribute("identifier")) {
- identifier = new URI(element.getAttribute("identifier"));
- }
- } catch (URISyntaxException e) {
- log.error("Rule not identified by a proper URI: " + e);
- throw new ArpMarshallingException("Rule not identified by a proper URI.");
- }
-
- // Grab the description
- NodeList descriptionNodes = element.getElementsByTagNameNS(Arp.arpNamespace, "Description");
- if (descriptionNodes.getLength() > 0) {
- Element descriptionNode = (Element) descriptionNodes.item(0);
- if (descriptionNode.hasChildNodes() && descriptionNode.getFirstChild().getNodeType() == Node.TEXT_NODE) {
- description = ((CharacterData) descriptionNode.getFirstChild()).getData();
- }
- }
-
- // Create the Constraints
- NodeList constraintNodes = element.getElementsByTagNameNS(Arp.arpNamespace, "Constraint");
- for (int i = 0; constraintNodes.getLength() > i; i++) {
- Constraint constraint = new Constraint();
- constraint.marshall((Element) constraintNodes.item(i));
- constraints.add(constraint);
- }
-
- // Create the Target
- NodeList targetNodes = element.getElementsByTagNameNS(Arp.arpNamespace, "Target");
- if (targetNodes.getLength() != 1) {
- log.error("Element data does not represent an ARP Rule. An ARP Rule must contain 1 and "
- + "only 1 Target definition.");
- throw new ArpMarshallingException("Element data does not represent an ARP Rule. An"
- + " ARP Rule must contain 1 and only 1 Target definition.");
- }
- target = new Target();
- target.marshall((Element) targetNodes.item(0));
-
- // Create the Attributes
- NodeList attributeNodes = element.getElementsByTagNameNS(Arp.arpNamespace, "Attribute");
- for (int i = 0; attributeNodes.getLength() > i; i++) {
- Attribute attribute = new Attribute();
- attribute.marshall((Element) attributeNodes.item(i));
- attributes.add(attribute);
- }
-
- // Retain Attribute references
- // Not enforced!
- NodeList attributeReferenceNodes = element.getElementsByTagNameNS(Arp.arpNamespace, "AttributeReference");
- if (attributeReferenceNodes.getLength() > 0) {
- log.warn("Encountered an Attribute Reference while marshalling an ARP. "
- + "References are currently unsupported by the ARP Engine. Ignoring...");
- attributeReferences = attributeReferenceNodes;
- }
- }
-
- /**
- * Returns a boolean indication of whether this rule is applicable to a given attribute request.
- *
- * @param requester
- * the SHAR making the request
- */
-
- public boolean matchesRequest(String requester, Collection<? extends ArpAttribute> attributes) {
-
- // if we have attributes for the user, then verify all constraints are met.
- // the only time we won't have attributes should be when listing possible attributes
- // to be released -- ArpEngine.listPossibleReleaseAttributes()
- if (attributes != null) {
- for (Constraint constraint : constraints) {
- if (!constraint.allowed(attributes)) { return false; }
- }
- }
-
- if (target.matchesAny()) { return true; }
-
- if (requester == null) { return false; }
-
- for (Requester arpRequester : target.getRequesters()) {
-
- try {
- MatchFunction requesterFunction = ArpEngine.lookupMatchFunction(arpRequester
- .getMatchFunctionIdentifier());
- if (requesterFunction.match(arpRequester.getValue(), requester)) { return true; }
-
- } catch (ArpException e) {
- log.warn("Encountered a problem while trying to find matching ARP rules: " + e);
- return false; // Always err on the side of caution
- }
- }
-
- return false;
- }
-
- class Target {
-
- private List<Requester> requesters = new ArrayList<Requester>();
- private boolean matchesAny = false;
-
- /**
- * Unmarshalls the <code>Rule.Target</code> into an xml <code>Element</code>.
- *
- * @return the xml <code>Element</code>
- */
-
- Element unmarshall() throws ArpMarshallingException {
-
- try {
- Document placeHolder = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
- Element targetNode = placeHolder.createElementNS(Arp.arpNamespace, "Target");
-
- if (matchesAny) {
- Element anyTargetNode = placeHolder.createElementNS(Arp.arpNamespace, "AnyTarget");
- targetNode.appendChild(anyTargetNode);
- return targetNode;
- }
- for (Requester requester : requesters) {
- targetNode.appendChild(placeHolder.importNode(requester.unmarshall(), true));
- }
- return targetNode;
- } catch (ParserConfigurationException e) {
- log.error("Encountered a problem unmarshalling an ARP Rule: " + e);
- throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule.");
- }
- }
-
- /**
- * Creates an ARP Rule Target from an xml representation.
- *
- * @param element
- * the xml <code>Element</code> containing the ARP Rule.
- */
- void marshall(Element element) throws ArpMarshallingException {
-
- // Make sure we are dealing with a Target
- if (!element.getTagName().equals("Target")) {
- log.error("Element data does not represent an ARP Rule Target.");
- throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
- }
-
- // Handle <AnyTarget/> definitions
- NodeList anyTargetNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "AnyTarget");
- if (anyTargetNodeList.getLength() == 1) {
- matchesAny = true;
- return;
- }
-
- // Create Requester
- NodeList requesterNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "Requester");
-
- if (requesterNodeList.getLength() < 1) {
- log.error("ARP Rule Target contains invalid data: no specified <Requester/>.");
- throw new ArpMarshallingException("ARP Rule Target contains invalid data: no specified <Requester/>.");
- }
-
- for (int i = 0; i < requesterNodeList.getLength(); i++) {
- Requester requester = new Requester();
- requester.marshall((Element) requesterNodeList.item(i));
- requesters.add(requester);
- }
- }
-
- boolean matchesAny() {
-
- return matchesAny;
- }
-
- Collection<Requester> getRequesters() {
-
- return requesters;
- }
- }
-
- class Requester {
-
- private String value;
- private URI matchFunctionIdentifier;
-
- URI getMatchFunctionIdentifier() {
-
- return matchFunctionIdentifier;
- }
-
- String getValue() {
-
- return value;
- }
-
- /**
- * Unmarshalls the <code>Rule.Requester</code> into an xml <code>Element</code>.
- *
- * @return the xml <code>Element</code>
- */
-
- Element unmarshall() throws ArpMarshallingException {
-
- try {
- Document placeHolder = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
- Element requesterNode = placeHolder.createElementNS(Arp.arpNamespace, "Requester");
- if (!matchFunctionIdentifier.equals(new URI("urn:mace:shibboleth:arp:matchFunction:stringMatch"))) {
- requesterNode.setAttributeNS(null, "matchFunction", matchFunctionIdentifier.toString());
- }
- Text valueNode = placeHolder.createTextNode(value);
- requesterNode.appendChild(valueNode);
- return requesterNode;
-
- } catch (URISyntaxException e) {
- log.error("Encountered a problem unmarshalling an ARP Rule Requester: " + e);
- throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Requester.");
- } catch (ParserConfigurationException e) {
- log.error("Encountered a problem unmarshalling an ARP Rule Requester: " + e);
- throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Requester.");
- }
- }
-
- /**
- * Creates an ARP Rule Target Requester from an xml representation.
- *
- * @param element
- * the xml <code>Element</code> containing the ARP Rule.
- */
- void marshall(Element element) throws ArpMarshallingException {
-
- // Make sure we are deling with a Requester
- if (!element.getTagName().equals("Requester")) {
- log.error("Element data does not represent an ARP Rule Target.");
- throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
- }
-
- // Grab the value
- if (element.hasChildNodes() && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {
- value = ((CharacterData) element.getFirstChild()).getData();
- } else {
- log.error("Element data does not represent an ARP Rule Target.");
- throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
- }
-
- // Grab the match function
- try {
- if (element.hasAttribute("matchFunction")) {
- matchFunctionIdentifier = new URI(element.getAttribute("matchFunction"));
- } else {
- matchFunctionIdentifier = new URI("urn:mace:shibboleth:arp:matchFunction:stringMatch");
- }
- } catch (URISyntaxException e) {
- log.error("ARP match function not identified by a proper URI.");
- throw new ArpMarshallingException("ARP match function not identified by a proper URI.");
- }
- }
- }
-
- class Attribute {
-
- private URI name;
- private boolean anyValue = false;
- private String anyValueRelease = "permit";
- private Set<AttributeValue> values = new HashSet<AttributeValue>();
- private URI identifier;
-
- boolean releaseAnyValue() {
-
- if (anyValueRelease.equals("permit")) { return anyValue; }
- return false;
- }
-
- boolean denyAnyValue() {
-
- if (anyValueRelease.equals("deny")) { return anyValue; }
- return false;
- }
-
- void setAnyValueDeny(boolean b) {
-
- if (b) {
- anyValue = true;
- anyValueRelease = "deny";
- values.clear();
- } else {
- if (anyValueRelease.equals("deny") && anyValue) {
- anyValue = false;
- }
- }
- }
-
- boolean isValuePermitted(Object value) {
-
- // Handle Deny All
- if (denyAnyValue()) { return false; }
-
- // Handle Permit All with no specific values
- if (releaseAnyValue() && getValues().size() == 0) { return true; }
-
- // Handle Deny Specific
- Iterator iterator = values.iterator();
- while (iterator.hasNext()) {
- AttributeValue valueSpec = (AttributeValue) iterator.next();
-
- MatchFunction resourceFunction;
- try {
- resourceFunction = ArpEngine.lookupMatchFunction(valueSpec.getMatchFunctionIdentifier());
- // For safety, err on the side of caution
- if (resourceFunction == null) {
- log.warn("Could not locate matching function for ARP value. Function: "
- + valueSpec.getMatchFunctionIdentifier().toString());
- return false;
- }
-
- } catch (ArpException e) {
- log.error("Error while attempting to find referenced matching function for ARP values: " + e);
- return false;
- }
-
- try {
- if (valueSpec.getRelease().equals("deny") && resourceFunction.match(valueSpec.getValue(), value)) { return false; }
- } catch (MatchingException e) {
- log.error("Could not apply referenced matching function to ARP value: " + e);
- return false;
- }
- }
-
- // Handle Permit All with no relevant specific denies
- if (releaseAnyValue()) { return true; }
-
- // Handle Permit Specific
- iterator = values.iterator();
- while (iterator.hasNext()) {
- AttributeValue valueSpec = (AttributeValue) iterator.next();
-
- MatchFunction resourceFunction;
- try {
- resourceFunction = ArpEngine.lookupMatchFunction(valueSpec.getMatchFunctionIdentifier());
- // Ignore non-functional permits
- if (resourceFunction == null) {
- log.warn("Could not locate matching function for ARP value. Function: "
- + valueSpec.getMatchFunctionIdentifier().toString());
- continue;
- }
-
- } catch (ArpException e) {
- log.error("Error while attempting to find referenced matching function for ARP values: " + e);
- continue;
- }
-
- try {
- if (valueSpec.getRelease().equals("permit") && resourceFunction.match(valueSpec.getValue(), value)) { return true; }
- } catch (MatchingException e) {
- log.error("Could not apply referenced matching function to ARP value: " + e);
- continue;
- }
- }
- return false;
- }
-
- void setAnyValuePermit(boolean b) {
-
- if (b) {
- anyValue = true;
- anyValueRelease = "permit";
- Iterator<AttributeValue> iterator = values.iterator();
- Set<AttributeValue> permittedValues = new HashSet<AttributeValue>();
- while (iterator.hasNext()) {
- AttributeValue value = (AttributeValue) iterator.next();
- if (value.getRelease().equals("permit")) {
- permittedValues.add(value);
- }
- }
- values.removeAll(permittedValues);
- } else {
- if (anyValueRelease.equals("permit") && anyValue) {
- anyValue = false;
- }
- }
- }
-
- URI getName() {
-
- return name;
- }
-
- Collection<AttributeValue> getValues() {
-
- return values;
- }
-
- void addValue(AttributeValue value) {
-
- if (denyAnyValue()) { return; }
- if (releaseAnyValue() && value.getRelease().equals("permit")) { return; }
- values.add(value);
- }
-
- /**
- * Unmarshalls an <code>Attribute</code> into an xml <code>Element</code>.
- *
- * @return the xml <code>Element</code>
- */
-
- Element unmarshall() throws ArpMarshallingException {
-
- try {
- Document placeHolder = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
- Element attributeNode = placeHolder.createElementNS(Arp.arpNamespace, "Attribute");
-
- attributeNode.setAttributeNS(null, "name", name.toString());
-
- if (identifier != null) {
- attributeNode.setAttributeNS(null, "identifier", identifier.toString());
- }
-
- if (anyValue) {
- Element anyValueNode = placeHolder.createElementNS(Arp.arpNamespace, "AnyValue");
- anyValueNode.setAttributeNS(null, "release", anyValueRelease);
- attributeNode.appendChild(anyValueNode);
- }
- Iterator valueIterator = values.iterator();
- while (valueIterator.hasNext()) {
- AttributeValue value = (AttributeValue) valueIterator.next();
- Element valueNode = placeHolder.createElementNS(Arp.arpNamespace, "Value");
- valueNode.setAttributeNS(null, "release", value.getRelease());
- if (!value.getMatchFunctionIdentifier().equals(
- new URI("urn:mace:shibboleth:arp:matchFunction:stringMatch"))) {
- valueNode.setAttributeNS(null, "matchFunction", value.getMatchFunctionIdentifier()
- .toString());
- }
- Text valueTextNode = placeHolder.createTextNode(value.getValue());
- valueNode.appendChild(valueTextNode);
- attributeNode.appendChild(valueNode);
- }
- return attributeNode;
-
- } catch (URISyntaxException e) {
- log.error("Encountered a problem unmarshalling an ARP Rule Resource: " + e);
- throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Resource.");
- } catch (ParserConfigurationException e) {
- log.error("Encountered a problem unmarshalling an ARP Rule: " + e);
- throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule.");
- }
- }
-
- /**
- * Creates an ARP Rule Attribute from an xml representation.
- *
- * @param element
- * the xml <code>Element</code> containing the ARP Rule.
- */
- 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.");
- }
-
- // Get the attribute identifier
- try {
- if (element.hasAttribute("identifier")) {
- identifier = new URI(element.getAttribute("identifier"));
- }
- } catch (URISyntaxException e) {
- log.error("Attribute not identified by a proper URI: " + e);
- throw new ArpMarshallingException("Attribute not identified by a proper URI.");
- }
-
- // 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 <AnyValue/> definitions
- NodeList anyValueNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "AnyValue");
- if (anyValueNodeList.getLength() == 1) {
- anyValue = true;
- if (((Element) anyValueNodeList.item(0)).hasAttribute("release")) {
- anyValueRelease = ((Element) anyValueNodeList.item(0)).getAttribute("release");
- }
- }
-
- // Handle Value definitions
- if (!denyAnyValue()) {
- NodeList valueNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "Value");
- for (int i = 0; valueNodeList.getLength() > i; i++) {
- String release = null;
- String value = null;
- URI matchFunctionIdentifier = null;
- if (((Element) valueNodeList.item(i)).hasAttribute("release")) {
- release = ((Element) valueNodeList.item(i)).getAttribute("release");
- }
-
- // Grab the match function
- try {
- if (((Element) valueNodeList.item(i)).hasAttribute("matchFunction")) {
- matchFunctionIdentifier = new URI(((Element) valueNodeList.item(i))
- .getAttribute("matchFunction"));
- }
- } catch (URISyntaxException e) {
- log.error("ARP match function not identified by a proper URI: "
- + ((Element) valueNodeList.item(i)).getAttribute("matchFunction"));
- throw new ArpMarshallingException("ARP match function not identified by a proper URI.");
- }
-
- if (((Element) valueNodeList.item(i)).hasChildNodes()
- && ((Element) valueNodeList.item(i)).getFirstChild().getNodeType() == Node.TEXT_NODE) {
- value = ((CharacterData) ((Element) valueNodeList.item(i)).getFirstChild()).getData();
- }
- if (releaseAnyValue() && release.equals("permit")) {
- continue;
- }
- AttributeValue aValue = new AttributeValue(release, matchFunctionIdentifier, value);
- values.add(aValue);
- }
- }
-
- }
- }
-
- class AttributeValue {
-
- private String release = "permit";
- private String value;
- private URI matchFunctionIdentifier;
-
- AttributeValue(String release, URI matchFunctionIdentifier, String value) throws ArpMarshallingException {
-
- setRelease(release);
- this.value = value;
- if (matchFunctionIdentifier != null) {
- this.matchFunctionIdentifier = matchFunctionIdentifier;
- } else {
- try {
- this.matchFunctionIdentifier = new URI("urn:mace:shibboleth:arp:matchFunction:stringMatch");
- } catch (URISyntaxException e) {
- throw new ArpMarshallingException(
- "ARP Engine internal error: could not set default matching function for attribute value.");
- }
- }
- }
-
- String getRelease() {
-
- return release;
- }
-
- String getValue() {
-
- return value;
- }
-
- URI getMatchFunctionIdentifier() {
-
- return matchFunctionIdentifier;
- }
-
- void setRelease(String release) {
-
- if (release == null) { return; }
- if (release.equals("permit") || release.equals("deny")) {
- this.release = release;
- }
- }
-
- void setValue(String value) {
-
- this.value = value;
- }
- }
-
- /**
- * ARP Rule Constraints define attribute-based limits on which user a given rule applies to.
- *
- * @author Will Norris (wnorris@usc.edu)
- */
- class Constraint {
-
- private URI attributeName;
- private URI matchFunctionIdentifier;
- private String matches;
- private String value;
-
- URI getAttributeName() {
-
- return attributeName;
- }
-
- /**
- * Unmarshalls a <code>Constraint</code> into an xml <code>Element</code>.
- *
- * @return the xml <code>Element</code>
- */
- Element unmarshall() throws ArpMarshallingException {
-
- try {
- Document placeHolder = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
- Element constraintNode = placeHolder.createElementNS(Arp.arpNamespace, "Constraint");
-
- constraintNode.setAttributeNS(null, "attributeName", attributeName.toString());
- constraintNode.setAttributeNS(null, "matchFunction", matchFunctionIdentifier.toString());
- constraintNode.setAttributeNS(null, "matches", matches);
-
- Text textNode = placeHolder.createTextNode(value);
- constraintNode.appendChild(textNode);
-
- return constraintNode;
-
- } catch (ParserConfigurationException e) {
- log.error("Encountered a problem unmarshalling an ARP Rule Constraint: " + e);
- throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Constraint.");
- }
- }
-
- /**
- * Creates an ARP Rule Constraint from an xml representation.
- *
- * @param element
- * the xml <code>Element</code> containing the ARP Rule Constraint.
- */
- void marshall(Element element) throws ArpMarshallingException {
-
- // Make sure we are dealing with a Constraint
- if (!element.getTagName().equals("Constraint")) {
- log.error("Element data does not represent an ARP Rule Constraint.");
- throw new ArpMarshallingException("Element data does not represent an ARP Rule Constraint.");
- }
-
- // Get the attribute name
- try {
- if (element.hasAttribute("attributeName")) {
- attributeName = new URI(element.getAttribute("attributeName"));
- } else {
- log.error("Constraint attribute name not specified.");
- throw new ArpMarshallingException("Constraint attribute name not specified.");
- }
- } catch (URISyntaxException e) {
- log.error("Constraint attribute name not identified by a proper URI: " + e);
- throw new ArpMarshallingException("Constraint attribute name not identified by a proper URI.");
- }
-
- // Get the matchFunction identifier
- try {
- if (element.hasAttribute("matchFunction")) {
- matchFunctionIdentifier = new URI(element.getAttribute("matchFunction"));
- } else {
- this.matchFunctionIdentifier = new URI("urn:mace:shibboleth:arp:matchFunction:stringMatch");
- }
- } catch (URISyntaxException e) {
- log.error("Constraint attribute name not identified by a proper URI: " + e);
- throw new ArpMarshallingException("Constraint attribute name not identified by a proper URI.");
- }
-
- // Get the matches value
- if (element.hasAttribute("matches")) {
- matches = element.getAttribute("matches");
- } else {
- matches = "any";
- }
-
- // Get the element value
- if (element.hasChildNodes() && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {
- value = ((CharacterData) element.getFirstChild()).getData();
- }
-
- }
-
- boolean allowed(Collection<? extends ArpAttribute> arpAttributes) {
-
- boolean allowed;
-
- if (matches.equalsIgnoreCase("none")) {
- allowed = true;
- } else {
- allowed = false;
- }
-
- for (ArpAttribute attribute : arpAttributes) {
- if (attribute.getName().equals(attributeName.toString())) {
-
- Iterator iterator = attribute.getValues();
- while (iterator.hasNext()) {
- Object attributeValue = iterator.next();
-
- MatchFunction resourceFunction;
- try {
- resourceFunction = ArpEngine.lookupMatchFunction(matchFunctionIdentifier);
- // For safety, err on the side of caution
- if (resourceFunction == null) {
- log.warn("Could not locate matching function for ARP constraint. Function: "
- + matchFunctionIdentifier.toString());
- return false;
- }
- } catch (ArpException e) {
- log.error("Error while attempting to find referenced matching "
- + "function for ARP constraint: " + e);
- return false;
- }
-
- // TODO this would be better as an enum switch
- try {
- if (matches.equalsIgnoreCase("any")) {
- if (resourceFunction.match(value, attributeValue)) {
- return true;
- } else {
- continue;
- }
- } else if (matches.equalsIgnoreCase("all")) {
- if (resourceFunction.match(value, attributeValue)) {
- allowed = true;
- continue;
- } else {
- return false;
- }
- } else if (matches.equalsIgnoreCase("none")) {
- if (resourceFunction.match(value, attributeValue)) {
- return false;
- } else {
- allowed = true;
- continue;
- }
- }
- } catch (MatchingException e) {
- log.error("Could not apply referenced matching function to ARP value: " + e);
- return false;
- }
- }
- }
- }
-
- return allowed;
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp.provider;
-
-import edu.internet2.middleware.shibboleth.aa.arp.MatchFunction;
-import edu.internet2.middleware.shibboleth.aa.arp.MatchingException;
-
-/**
- * Function that will match against any string value.
- *
- * @author Walter Hoehn
- */
-public class AnyValueMatchFunction implements MatchFunction {
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.MatchFunction#match(Object, Object)
- */
- public boolean match(Object arpComponent, Object requestComponent) throws MatchingException {
-
- if (requestComponent != null && requestComponent instanceof String) { return true; }
- return false;
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp.provider;
-
-import java.io.IOException;
-import java.security.Principal;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-import edu.internet2.middleware.shibboleth.aa.arp.Arp;
-import edu.internet2.middleware.shibboleth.aa.arp.ArpMarshallingException;
-import edu.internet2.middleware.shibboleth.aa.arp.ArpRepository;
-import edu.internet2.middleware.shibboleth.aa.arp.ArpRepositoryException;
-
-/**
- * Provides marshalling/unmarshalling functionality common among <code>ArpRepository</code> implementations.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public abstract class BaseArpRepository implements ArpRepository {
-
- private static Logger log = Logger.getLogger(BaseArpRepository.class.getName());
- private ArpCache arpCache;
-
- BaseArpRepository(Element config) throws ArpRepositoryException {
-
- String rawArpTTL = config.getAttribute("arpTTL");
- long arpTTL = 0;
- try {
- if (rawArpTTL != null && !rawArpTTL.equals("")) {
- arpTTL = Long.parseLong(rawArpTTL);
- log.debug("ARP TTL set to: (" + arpTTL + ").");
- }
- } catch (NumberFormatException e) {
- log.error("ARP TTL must be set to a long integer.");
- }
-
- if (arpTTL > 0) {
- arpCache = ArpCache.instance();
- arpCache.setCacheLength(arpTTL);
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getAllPolicies(Principal)
- */
-
- public Arp[] getAllPolicies(Principal principal) throws ArpRepositoryException {
-
- log.debug("Received a query for all policies applicable to principal: (" + principal.getName() + ").");
- Set<Arp> allPolicies = new HashSet<Arp>();
- Arp sitePolicy = getSitePolicy();
- if (sitePolicy != null) {
- log.debug("Returning site policy.");
- allPolicies.add(sitePolicy);
- }
-
- Arp userPolicy = getUserPolicy(principal);
- if (userPolicy != null) {
- allPolicies.add(userPolicy);
- log.debug("Returning user policy.");
- }
- if (allPolicies.isEmpty()) {
- log.debug("No policies found.");
- }
- return (Arp[]) allPolicies.toArray(new Arp[0]);
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getSitePolicy()
- */
- public Arp getSitePolicy() throws ArpRepositoryException {
-
- try {
- if (arpCache != null) {
- Arp cachedArp = arpCache.retrieveSiteArpFromCache();
- if (cachedArp != null) {
- log.debug("Using cached site ARP.");
- return cachedArp;
- }
- }
-
- Element xml = retrieveSiteArpXml();
- if (xml == null) { return null; }
-
- Arp siteArp = new Arp();
- siteArp.marshall(xml);
- if (arpCache != null) {
- arpCache.cache(siteArp);
- }
- return siteArp;
- } catch (ArpMarshallingException ame) {
- log.error("An error occurred while marshalling an ARP: " + ame);
- throw new ArpRepositoryException("An error occurred while marshalling an ARP.");
- } catch (IOException ioe) {
- log.error("An error occurred while loading an ARP: " + ioe);
- throw new ArpRepositoryException("An error occurred while loading an ARP.");
- } catch (SAXException se) {
- log.error("An error occurred while parsing an ARP: " + se);
- throw new ArpRepositoryException("An error occurred while parsing an ARP.");
- } catch (ParserConfigurationException e) {
- log.error("An error occurred while loading the XML parser: " + e);
- throw new ArpRepositoryException("An error occurred while loading the XML parser.");
- }
- }
-
- /**
- * Inheritors must return the site Arp as an xml element.
- *
- * @return Element
- */
- protected abstract Element retrieveSiteArpXml() throws IOException, SAXException, ParserConfigurationException;
-
- public void destroy() {
-
- if (arpCache != null) {
- arpCache.destroy();
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getUserPolicy(Principal)
- */
- public Arp getUserPolicy(Principal principal) throws ArpRepositoryException {
-
- if (arpCache != null) {
- Arp cachedArp = arpCache.retrieveUserArpFromCache(principal);
- if (cachedArp != null) {
- log.debug("Using cached user ARP.");
- return cachedArp;
- }
- }
-
- try {
- Element xml = retrieveUserArpXml(principal);
- if (xml == null) { return null; }
-
- Arp userArp = new Arp();
- userArp.setPrincipal(principal);
-
- userArp.marshall(xml);
- if (arpCache != null) {
- arpCache.cache(userArp);
- }
- return userArp;
- } catch (ArpMarshallingException ame) {
- log.error("An error occurred while marshalling an ARP: " + ame);
- throw new ArpRepositoryException("An error occurred while marshalling an ARP.");
- } catch (IOException ioe) {
- log.error("An error occurred while loading an ARP: " + ioe);
- throw new ArpRepositoryException("An error occurred while loading an ARP.");
- } catch (SAXException se) {
- log.error("An error occurred while parsing an ARP: " + se);
- throw new ArpRepositoryException("An error occurred while parsing an ARP.");
- } catch (ParserConfigurationException e) {
- log.error("An error occurred while loading the XML parser: " + e);
- throw new ArpRepositoryException("An error occurred while loading the XML parser.");
- }
- }
-
- /**
- * Inheritors must return the user Arp as an xml element.
- *
- * @return Element
- */
- protected abstract Element retrieveUserArpXml(Principal principal) throws IOException, SAXException,
- ParserConfigurationException;
-
-}
-
-class ArpCache {
-
- private static ArpCache instance = null;
- /** Time in seconds for which ARPs should be cached. */
- private long cacheLength;
- private Map<Principal, CachedArp> cache = new HashMap<Principal, CachedArp>();
- private static Logger log = Logger.getLogger(ArpCache.class.getName());
- private ArpCacheCleaner cleaner = new ArpCacheCleaner();
-
- protected ArpCache() {
-
- }
-
- static synchronized ArpCache instance() {
-
- if (instance == null) {
- instance = new ArpCache();
- return instance;
- }
- return instance;
- }
-
- /** Set time in seconds for which ARPs should be cached. */
- void setCacheLength(long cacheLength) {
-
- this.cacheLength = cacheLength;
- }
-
- void cache(Arp arp) {
-
- if (arp.isSitePolicy() == false) {
- synchronized (cache) {
- cache.put(arp.getPrincipal(), new CachedArp(arp, System.currentTimeMillis()));
- }
- } else {
- synchronized (cache) {
- cache.put(new SiteCachePrincipal(), new CachedArp(arp, System.currentTimeMillis()));
- }
- }
- }
-
- Arp retrieveUserArpFromCache(Principal principal) {
-
- return retrieveArpFromCache(principal);
- }
-
- Arp retrieveSiteArpFromCache() {
-
- return retrieveArpFromCache(new SiteCachePrincipal());
- }
-
- private Arp retrieveArpFromCache(Principal principal) {
-
- CachedArp cachedArp;
- synchronized (cache) {
- cachedArp = (CachedArp) cache.get(principal);
- }
-
- if (cachedArp == null) { return null; }
-
- if ((System.currentTimeMillis() - cachedArp.creationTimeMillis) < (cacheLength * 1000)) { return cachedArp.arp; }
-
- synchronized (cache) {
- cache.remove(principal);
- }
- return null;
- }
-
- /**
- * @see java.lang.Object#finalize()
- */
- protected void finalize() throws Throwable {
-
- super.finalize();
- destroy();
- }
-
- public void destroy() {
-
- synchronized (cleaner) {
- if (cleaner != null) {
- cleaner.shutdown = true;
- cleaner.interrupt();
- }
- }
- }
-
- private class CachedArp {
-
- Arp arp;
- long creationTimeMillis;
-
- CachedArp(Arp arp, long creationTimeMillis) {
-
- this.arp = arp;
- this.creationTimeMillis = creationTimeMillis;
- }
- }
-
- private class SiteCachePrincipal implements Principal {
-
- public String getName() {
-
- return "ARP admin";
- }
-
- /**
- * @see java.lang.Object#equals(Object)
- */
- public boolean equals(Object object) {
-
- if (object instanceof SiteCachePrincipal) { return true; }
- return false;
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- public int hashCode() {
-
- return "edu.internet2.middleware.shibboleth.aa.arp.provider.BaseArpRepository.SiteCachePrincipal"
- .hashCode();
- }
- }
-
- private class ArpCacheCleaner extends Thread {
-
- private boolean shutdown = false;
- private Thread master;
-
- public ArpCacheCleaner() {
-
- super("edu.internet2.middleware.shibboleth.aa.arp.provider.BaseArpRepository.ArpCache.ArpCacheCleaner");
- master = Thread.currentThread();
- setDaemon(true);
- if (getPriority() > Thread.MIN_PRIORITY) {
- setPriority(getPriority() - 1);
- }
- log.debug("Starting ArpCache Cleanup Thread.");
- start();
- }
-
- public void run() {
-
- try {
- sleep(60 * 1000); // one minute
- } catch (InterruptedException e) {
- log.debug("ArpCache Cleanup interrupted.");
- }
- while (true) {
- try {
- if (master == null) {
- log.debug("ArpCache cache cleaner is orphaned.");
- shutdown = true;
- }
- if (shutdown) {
- log.debug("Stopping ArpCache Cleanup Thread.");
- return;
- }
- log.debug("ArpCache cleanup thread searching for stale entries.");
- Set<CachedArp> needsDeleting = new HashSet<CachedArp>();
- synchronized (cache) {
- Iterator<CachedArp> iterator = cache.values().iterator();
- while (iterator.hasNext()) {
- CachedArp cachedArp = iterator.next();
- if ((System.currentTimeMillis() - cachedArp.creationTimeMillis) > (cacheLength * 1000)) {
- needsDeleting.add(cachedArp);
- }
- }
- }
- // release the lock to be friendly
- Iterator deleteIterator = needsDeleting.iterator();
- while (deleteIterator.hasNext()) {
- synchronized (cache) {
- CachedArp cachedArp = (CachedArp) deleteIterator.next();
- if (cachedArp.arp.isSitePolicy()) {
- log.debug("Expiring site ARP from the Cache.");
- cache.remove(new SiteCachePrincipal());
- } else {
- log.debug("Expiring an ARP from the Cache.");
- cache.remove(cachedArp.arp.getPrincipal());
- }
- }
- }
-
- sleep(60 * 1000); // one minute
- } catch (InterruptedException e) {
- log.debug("ArpCache Cleanup interrupted.");
- }
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp.provider;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.Principal;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import edu.internet2.middleware.shibboleth.aa.arp.Arp;
-import edu.internet2.middleware.shibboleth.aa.arp.ArpRepository;
-import edu.internet2.middleware.shibboleth.aa.arp.ArpRepositoryException;
-import edu.internet2.middleware.shibboleth.common.ShibResource;
-import edu.internet2.middleware.shibboleth.idp.IdPConfig;
-
-/**
- * Simple <code>ArpRepository</code> implementation that uses a filesystem for storage.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public class FileSystemArpRepository extends BaseArpRepository implements ArpRepository {
-
- private static Logger log = Logger.getLogger(FileSystemArpRepository.class.getName());
- private final String siteArpFileName = "arp.site.xml";
-
- private String dataStorePath;
-
- public FileSystemArpRepository(Element config) throws ArpRepositoryException {
-
- super(config);
-
- NodeList itemElements = config.getElementsByTagNameNS(IdPConfig.configNameSpace, "Path");
-
- if (itemElements.getLength() > 1) {
- log
- .warn("Encountered multiple <Path> configuration elements for the File System ARP Repository. Using first...");
- }
- Node tnode = itemElements.item(0).getFirstChild();
- String path = null;
- if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
- path = tnode.getNodeValue();
- }
- if (path == null || path.equals("")) {
- log.error("ARP repository path not specified.");
- throw new ArpRepositoryException(
- "Cannot initialize FileSystemArpRepository: <ArpRepository> element must contain a <Path> element.");
- }
-
- try {
- File realPath = new ShibResource(path, this.getClass()).getFile();
-
- if (!realPath.isDirectory()) {
- log.error("Cannot initialize FileSystemArpRepository: specified path is not a directory: ("
- + realPath.getPath() + ").");
- throw new ArpRepositoryException("Cannot initialize FileSystemArpRepository");
- }
-
- dataStorePath = path;
- if (!dataStorePath.endsWith("/")) {
- dataStorePath += "/";
- }
- log.info("Initializing File System Arp Repository with a root of (" + dataStorePath + ").");
- } catch (Exception e) {
- log.error("Cannot initialize FileSystemArpRepository: error accessing path: (" + path + "): " + e);
- throw new ArpRepositoryException("Cannot initialize FileSystemArpRepository");
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#remove(Arp)
- */
- public void remove(Arp arp) throws ArpRepositoryException {
-
- throw new ArpRepositoryException("Remove not implemented for FileSystemArpRepository.");
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#update(Arp)
- */
- public void update(Arp arp) throws ArpRepositoryException {
-
- throw new ArpRepositoryException("Update not implemented for FileSystemArpRepository.");
- }
-
- /**
- * @throws ParserConfigurationException
- * @see edu.internet2.middleware.shibboleth.aa.arp.provider.BaseArpRepository#retrieveSiteArpXml()
- */
- protected Element retrieveSiteArpXml() throws IOException, SAXException, ParserConfigurationException {
-
- String fileName = dataStorePath + siteArpFileName;
- log.debug("Attempting to load site ARP from: (" + fileName + ").");
- return retrieveArpXml(fileName);
-
- }
-
- private Element retrieveArpXml(String fileName) throws SAXException, IOException, ParserConfigurationException {
-
- try {
- ShibResource resource = new ShibResource(fileName, this.getClass());
- if (!resource.getFile().exists()) {
- log.debug("No ARP found.");
- return null;
- }
-
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setValidating(false);
- factory.setNamespaceAware(true);
- return factory.newDocumentBuilder().parse(new InputSource(resource.getInputStream())).getDocumentElement();
-
- } catch (ShibResource.ResourceNotAvailableException e) {
- log.debug("No ARP found.");
- return null;
- }
- }
-
- /**
- * @throws ParserConfigurationException
- * @see edu.internet2.middleware.shibboleth.aa.arp.provider.BaseArpRepository#retrieveUserArpXml(Principal)
- */
- protected Element retrieveUserArpXml(Principal principal) throws IOException, SAXException, ParserConfigurationException {
-
- String fileName = dataStorePath + "arp.user." + principal.getName() + ".xml";
- log.debug("Attempting to load user (" + principal.getName() + ") ARP from: (" + fileName + ").");
- return retrieveArpXml(fileName);
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp.provider;
-
-import java.security.Principal;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.aa.arp.Arp;
-import edu.internet2.middleware.shibboleth.aa.arp.ArpRepository;
-import edu.internet2.middleware.shibboleth.aa.arp.ArpRepositoryException;
-
-/**
- * A memory-based <code>ArpRepository</code> implementation. Only useful for testing.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public class MemoryArpRepository implements ArpRepository {
-
- private Map<Principal, Arp> userPolicies = Collections.synchronizedMap(new HashMap<Principal, Arp>());
- private Arp sitePolicy;
- private static Logger log = Logger.getLogger(MemoryArpRepository.class.getName());
-
- public MemoryArpRepository(Element config) {
-
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getSitePolicy()
- */
-
- public synchronized Arp getSitePolicy() throws ArpRepositoryException {
-
- return sitePolicy;
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getAllPolicies(Principal)
- */
-
- public Arp[] getAllPolicies(Principal principal) throws ArpRepositoryException {
-
- log.debug("Received a query for all policies applicable to principal: (" + principal.getName() + ").");
- Set<Arp> allPolicies = new HashSet<Arp>();
- if (getSitePolicy() != null) {
- log.debug("Returning site policy.");
- allPolicies.add(getSitePolicy());
- }
- if (getUserPolicy(principal) != null) {
- allPolicies.add(getUserPolicy(principal));
- log.debug("Returning user policy.");
- }
- if (allPolicies.isEmpty()) {
- log.debug("No policies found.");
- }
- return (Arp[]) allPolicies.toArray(new Arp[0]);
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getUserPolicy(Principal)
- */
-
- public Arp getUserPolicy(Principal principal) throws ArpRepositoryException {
-
- return (Arp) userPolicies.get(principal);
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#remove(Arp)
- */
-
- public void remove(Arp arp) throws ArpRepositoryException {
-
- if (arp.isSitePolicy()) {
- synchronized (this) {
- sitePolicy = null;
- }
- } else if (userPolicies.containsKey(arp.getPrincipal())) {
- userPolicies.remove(arp.getPrincipal());
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#update(Arp)
- */
-
- public void update(Arp arp) throws ArpRepositoryException {
-
- if (arp == null) { throw new ArpRepositoryException("Cannot add a null ARP to the repository."); }
-
- if (arp.isSitePolicy()) {
- synchronized (this) {
- sitePolicy = arp;
- }
- return;
- }
-
- if (arp.getPrincipal() == null) { throw new ArpRepositoryException(
- "Cannot add ARP to repository. Must contain a Principal or be a Site ARP."); }
-
- userPolicies.put(arp.getPrincipal(), arp);
- }
-
- public void destroy() {
-
- // do nothing
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp.provider;
-
-import java.net.URL;
-
-import edu.internet2.middleware.shibboleth.aa.arp.MatchFunction;
-import edu.internet2.middleware.shibboleth.aa.arp.MatchingException;
-
-import org.apache.log4j.Logger;
-
-/**
- * Match function implementaiton that does regular expression matching on both requesters and resources.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class RegexMatchFunction implements MatchFunction {
-
- private static Logger log = Logger.getLogger(RegexMatchFunction.class.getName());
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.MatchFunction#match(Object, Object)
- */
- public boolean match(Object arpComponent, Object requestComponent) throws MatchingException {
-
- if (!(arpComponent instanceof String)
- || !(requestComponent instanceof String || requestComponent instanceof URL)) {
- log.error("Invalid use of ARP matching function (RegexMatchFunction).");
- throw new MatchingException("Invalid use of ARP matching function (RegexMatchFunction).");
- }
- if (requestComponent instanceof URL) { return ((URL) requestComponent).toString()
- .matches((String) arpComponent); }
- return ((String) requestComponent).matches((String) arpComponent);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp.provider;
-
-import java.net.URL;
-
-import edu.internet2.middleware.shibboleth.aa.arp.MatchFunction;
-import edu.internet2.middleware.shibboleth.aa.arp.MatchingException;
-
-import org.apache.log4j.Logger;
-
-/**
- * Match function implementaiton that matches when a given regular expression does NOT match.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class RegexNotMatchFunction implements MatchFunction {
-
- private static Logger log = Logger.getLogger(RegexNotMatchFunction.class.getName());
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.MatchFunction#match(Object, Object)
- */
- public boolean match(Object arpComponent, Object requestComponent) throws MatchingException {
-
- if (!(arpComponent instanceof String)
- || !(requestComponent instanceof String || requestComponent instanceof URL)) {
- log.error("Invalid use of ARP matching function (RegexMatchFunction).");
- throw new MatchingException("Invalid use of ARP matching function (RegexMatchFunction).");
- }
- if (requestComponent instanceof URL) { return ((URL) requestComponent).toString()
- .matches((String) arpComponent); }
- return !((String) requestComponent).matches((String) arpComponent);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp.provider;
-
-import org.apache.log4j.Logger;
-
-import edu.internet2.middleware.shibboleth.aa.arp.MatchFunction;
-import edu.internet2.middleware.shibboleth.aa.arp.MatchingException;
-
-/**
- * Match function that does exact string matching.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class StringValueMatchFunction implements MatchFunction {
-
- private static Logger log = Logger.getLogger(StringValueMatchFunction.class.getName());
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.MatchFunction#match(Object, Object)
- */
- public boolean match(Object arpComponent, Object requestComponent) throws MatchingException {
-
- if (!(arpComponent instanceof String) || !(requestComponent instanceof String)) {
- log.error("Invalid use of ARP matching function (StringValueMatchFunction).");
- throw new MatchingException("Invalid use of ARP matching function (StringValueMatchFunction).");
- }
- return arpComponent.equals(requestComponent);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.arp.provider;
-
-import org.apache.log4j.Logger;
-
-import edu.internet2.middleware.shibboleth.aa.arp.MatchFunction;
-import edu.internet2.middleware.shibboleth.aa.arp.MatchingException;
-
-/**
- * Match function that matches strings that are not the same.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class StringValueNotMatchFunction implements MatchFunction {
-
- private static Logger log = Logger.getLogger(StringValueNotMatchFunction.class.getName());
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.arp.MatchFunction#match(Object, Object)
- */
- public boolean match(Object arpComponent, Object requestComponent) throws MatchingException {
-
- if (!(arpComponent instanceof String) || !(requestComponent instanceof String)) {
- log.error("Invalid use of ARP matching function (StringValueNotMatchFunction).");
- throw new MatchingException("Invalid use of ARP matching function (StringValueNotMatchFunction).");
- }
- return !arpComponent.equals(requestComponent);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-import java.security.Principal;
-
-/**
- * Defines an Attribute Definition PlugIn for the AA Attribute Resolver. Such plugins can be realized at runtime by the
- * resolver and subsequently resolved in conjunction with other dependant plugins.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public interface AttributeDefinitionPlugIn extends ResolutionPlugIn {
-
- /**
- * Resolves the values of an attribute.
- *
- * @param attribute
- * The attribute to be resolved
- * @param principal
- * The principal for which the attribute should be resolved
- * @param requester
- * The name of the entity making the resolution request
- * @param responder
- * The name of the entity responding to the resolution request
- * @param depends
- * Resolution dependencies
- * @throws ResolutionPlugInException
- */
- public void resolve(ResolverAttribute attribute, Principal principal, String requester, String responder,
- Dependencies depends) throws ResolutionPlugInException;
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-import java.io.IOException;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttributes;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ValueHandler;
-import edu.internet2.middleware.shibboleth.common.ShibResource;
-import edu.internet2.middleware.shibboleth.common.ShibResource.ResourceNotAvailableException;
-import edu.internet2.middleware.shibboleth.idp.IdPConfig;
-
-/**
- * An engine for obtaining attribute values for specified principals. Attributes values are resolved using a directed
- * graph of pluggable attribute definitions and data connectors.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public class AttributeResolver {
-
- private static Logger log = Logger.getLogger(AttributeResolver.class.getName());
- private HashMap<String, ResolutionPlugIn> plugIns = new HashMap<String, ResolutionPlugIn>();
- private ResolverCache resolverCache = new ResolverCache();
- public static final String resolverNamespace = "urn:mace:shibboleth:resolver:1.0";
-
- public AttributeResolver(IdPConfig configuration) throws AttributeResolverException {
-
- if (configuration == null || configuration.getResolverConfigLocation() == null) {
- log.error("No Attribute Resolver configuration file specified.");
- throw new AttributeResolverException("No Attribute Resolver configuration file specified.");
- }
-
- loadConfig(configuration.getResolverConfigLocation());
- }
-
- public AttributeResolver(String configFileLocation) throws AttributeResolverException {
-
- loadConfig(configFileLocation);
- }
-
- private void loadConfig(String configFile) throws AttributeResolverException {
-
- try {
- ShibResource config = new ShibResource(configFile, this.getClass());
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setValidating(false);
- factory.setNamespaceAware(true);
-
- loadConfig(factory.newDocumentBuilder().parse(new InputSource(config.getInputStream())));
-
- } catch (ResourceNotAvailableException e) {
- log.error("No Attribute Resolver configuration could be loaded from (" + configFile + "): " + e);
- throw new AttributeResolverException("No Attribute Resolver configuration found.");
- } catch (SAXException e) {
- log.error("Error parsing Attribute Resolver Configuration file: " + e);
- throw new AttributeResolverException("Error parsing Attribute Resolver Configuration file.");
- } catch (IOException e) {
- log.error("Error reading Attribute Resolver Configuration file: " + e);
- throw new AttributeResolverException("Error reading Attribute Resolver Configuration file.");
- } catch (ParserConfigurationException e) {
- log.error("Error parsing Attribute Resolver Configuration file: " + e);
- throw new AttributeResolverException("Error parsing Attribute Resolver Configuration file.");
- }
- }
-
- private void loadConfig(Document document) throws AttributeResolverException {
-
- log.info("Configuring Attribute Resolver.");
- if (!document.getDocumentElement().getTagName().equals("AttributeResolver")) {
- log.error("Configuration must include <AttributeResolver> as the root node.");
- throw new AttributeResolverException("Cannot load Attribute Resolver.");
- }
-
- NodeList plugInNodes = document.getElementsByTagNameNS(resolverNamespace, "AttributeResolver").item(0)
- .getChildNodes();
- if (plugInNodes.getLength() <= 0) {
- log.error("Configuration inclues no PlugIn definitions.");
- throw new AttributeResolverException("Cannot load Attribute Resolver.");
- }
- for (int i = 0; plugInNodes.getLength() > i; i++) {
- if (plugInNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
- try {
- log.info("Found a PlugIn. Loading...");
- ResolutionPlugIn plugIn = ResolutionPlugInFactory.createPlugIn((Element) plugInNodes.item(i));
- registerPlugIn(plugIn, plugIn.getId());
- } catch (DuplicatePlugInException dpe) {
- log.warn("Skipping PlugIn: " + dpe.getMessage());
- } catch (ClassCastException cce) {
- log.error("Problem realizing PlugIn configuration" + cce.getMessage());
- } catch (AttributeResolverException are) {
- log.warn("Skipping PlugIn: " + ((Element) plugInNodes.item(i)).getAttribute("id"));
- }
- }
- }
-
- verifyPlugIns();
- log.info("Configuration complete.");
- }
-
- private void verifyPlugIns() throws AttributeResolverException {
-
- log.info("Verifying PlugIn graph consitency.");
- Set<String> inconsistent = new HashSet<String>();
- Iterator registered = plugIns.keySet().iterator();
-
- while (registered.hasNext()) {
- ResolutionPlugIn plugIn = plugIns.get((String) registered.next());
- log.debug("Checking PlugIn (" + plugIn.getId() + ") for consistency.");
- verifyPlugIn(plugIn, new HashSet<String>(), inconsistent);
- }
-
- if (!inconsistent.isEmpty()) {
- log.info("Unloading inconsistent PlugIns.");
- Iterator inconsistentIt = inconsistent.iterator();
- while (inconsistentIt.hasNext()) {
- plugIns.remove(inconsistentIt.next());
- }
- }
-
- if (plugIns.size() < 1) {
- log.error("Failed to load any PlugIn definitions.");
- throw new AttributeResolverException("Cannot load Attribute Resolver.");
- }
-
- }
-
- private void verifyPlugIn(ResolutionPlugIn plugIn, Set<String> verifyChain, Set<String> inconsistent) {
-
- // Short-circuit if we have already found this PlugIn to be inconsistent
- if (inconsistent.contains(plugIn.getId())) { return; }
-
- // Make sure that we don't have a circular dependency
- if (verifyChain.contains(plugIn.getId())) {
- log.error("The PlugIn (" + plugIn.getId()
- + ") is inconsistent. It is involved in a circular dependency chain.");
- inconsistent.add(plugIn.getId());
- return;
- }
-
- // Recursively go through all DataConnector dependencies and make sure all are registered and consistent.
- List<String> depends = new ArrayList<String>();
- depends.addAll(Arrays.asList(plugIn.getDataConnectorDependencyIds()));
- Iterator<String> dependsIt = depends.iterator();
- while (dependsIt.hasNext()) {
- String key = dependsIt.next();
- if (!plugIns.containsKey(key)) {
- log.error("The PlugIn (" + plugIn.getId() + ") is inconsistent. It depends on a PlugIn (" + key
- + ") that is not registered.");
- inconsistent.add(plugIn.getId());
- return;
- }
-
- ResolutionPlugIn dependent = plugIns.get(key);
- if (!(dependent instanceof DataConnectorPlugIn)) {
- log.error("The PlugIn (" + plugIn.getId() + ") is inconsistent. It depends on a PlugIn (" + key
- + ") that is mislabeled as an DataConnectorPlugIn.");
- inconsistent.add(plugIn.getId());
- return;
- }
-
- verifyChain.add(plugIn.getId());
- verifyPlugIn(dependent, verifyChain, inconsistent);
-
- if (inconsistent.contains(key)) {
- log.error("The PlugIn (" + plugIn.getId() + ") is inconsistent. It depends on a PlugIn (" + key
- + ") that is inconsistent.");
- inconsistent.add(plugIn.getId());
- return;
- }
- }
- verifyChain.remove(plugIn.getId());
-
- // Recursively go through all AttributeDefinition dependencies and make sure all are registered and consistent.
- depends.clear();
- depends.addAll(Arrays.asList(plugIn.getAttributeDefinitionDependencyIds()));
- dependsIt = depends.iterator();
- while (dependsIt.hasNext()) {
- String key = (String) dependsIt.next();
-
- if (!plugIns.containsKey(key)) {
- log.error("The PlugIn (" + plugIn.getId() + ") is inconsistent. It depends on a PlugIn (" + key
- + ") that is not registered.");
- inconsistent.add(plugIn.getId());
- return;
- }
-
- ResolutionPlugIn dependent = plugIns.get(key);
- if (!(dependent instanceof AttributeDefinitionPlugIn)) {
- log.error("The PlugIn (" + plugIn.getId() + ") is inconsistent. It depends on a PlugIn (" + key
- + ") that is mislabeled as an AttributeDefinitionPlugIn.");
- inconsistent.add(plugIn.getId());
- return;
- }
-
- verifyChain.add(plugIn.getId());
- verifyPlugIn(dependent, verifyChain, inconsistent);
-
- if (inconsistent.contains(key)) {
- log.error("The PlugIn (" + plugIn.getId() + ") is inconsistent. It depends on a PlugIn (" + key
- + ") that is inconsistent.");
- inconsistent.add(plugIn.getId());
- return;
- }
- }
- verifyChain.remove(plugIn.getId());
-
- // Check the failover dependency, if there is one.
- if (plugIn instanceof DataConnectorPlugIn) {
- String key = ((DataConnectorPlugIn) plugIn).getFailoverDependencyId();
- if (key != null) {
- if (!plugIns.containsKey(key)) {
- log.error("The PlugIn (" + plugIn.getId() + ") is inconsistent. It depends on a PlugIn (" + key
- + ") that is not registered.");
- inconsistent.add(plugIn.getId());
- return;
- }
-
- ResolutionPlugIn dependent = plugIns.get(key);
- if (!(dependent instanceof DataConnectorPlugIn)) {
- log.error("The PlugIn (" + plugIn.getId()
- + ") is inconsistent. It depends on a fail-over PlugIn (" + key
- + ") that is not a DataConnectorPlugIn.");
- inconsistent.add(plugIn.getId());
- return;
- }
-
- verifyChain.add(plugIn.getId());
- verifyPlugIn(dependent, verifyChain, inconsistent);
-
- if (inconsistent.contains(key)) {
- log.error("The PlugIn (" + plugIn.getId() + ") is inconsistent. It depends on a PlugIn (" + key
- + ") that is inconsistent.");
- inconsistent.add(plugIn.getId());
- return;
- }
- }
- }
- verifyChain.remove(plugIn.getId());
- }
-
- private void registerPlugIn(ResolutionPlugIn connector, String id) throws DuplicatePlugInException {
-
- if (plugIns.containsKey(id)) {
- log.error("A PlugIn is already registered with the Id (" + id + ").");
- throw new DuplicatePlugInException("Found a duplicate PlugIn Id.");
- }
- plugIns.put(id, connector);
- log.info("Registered PlugIn: (" + id + ")");
-
- }
-
- /**
- * Resolve a set of attributes for a particular principal and requester.
- *
- * @param principal
- * the <code>Principal</code> for which the attributes should be resolved
- * @param requester
- * the name of the requesting entity
- * @param responding
- * the name of the entity responding to the request
- * @param attributes
- * the set of attributes to be resolved
- */
- public void resolveAttributes(Principal principal, String requester, String responder, Map attributes) {
-
- HashMap requestCache = new HashMap<String, ResolverAttribute>();
- Iterator<ResolverAttribute> iterator = attributes.values().iterator();
-
- while (iterator.hasNext()) {
- ResolverAttribute attribute = iterator.next();
- try {
- if (plugIns.get(attribute.getName()) == null) {
- log.warn("No PlugIn registered for attribute: (" + attribute.getName() + ")");
- iterator.remove();
- } else {
- log.info("Resolving attribute: (" + attribute.getName() + ")");
- if (attribute.resolved()) {
- log.debug("Attribute (" + attribute.getName()
- + ") already resolved for this request. No need for further resolution.");
-
- } else {
- resolveAttribute(attribute, principal, requester, responder, requestCache, attributes);
- }
-
- if (!attribute.hasValues()) {
- iterator.remove();
- }
- }
- } catch (ResolutionPlugInException rpe) {
- log.error("Problem encountered while resolving attribute: (" + attribute.getName() + "): " + rpe);
- iterator.remove();
- }
- }
- }
-
- public Collection<String> listRegisteredAttributeDefinitionPlugIns() {
-
- log.debug("Listing available Attribute Definition PlugIns.");
- Set<String> found = new HashSet<String>();
- Iterator registered = plugIns.keySet().iterator();
-
- while (registered.hasNext()) {
- ResolutionPlugIn plugIn = plugIns.get((String) registered.next());
- if (plugIn instanceof AttributeDefinitionPlugIn) {
- found.add(((AttributeDefinitionPlugIn) plugIn).getId());
- }
- }
-
- if (log.isDebugEnabled()) {
- for (Iterator iterator = found.iterator(); iterator.hasNext();) {
- log.debug("Found registered Attribute Definition: " + (String) iterator.next());
- }
- }
- return found;
- }
-
- private Attributes resolveConnector(String connector, Principal principal, String requester, String responder,
- Map requestCache, Map<String, ResolverAttribute> requestedAttributes) throws ResolutionPlugInException {
-
- DataConnectorPlugIn currentDefinition = (DataConnectorPlugIn) plugIns.get(connector);
-
- // Check to see if we have already resolved the connector during this request
- if (requestCache.containsKey(currentDefinition.getId())) {
- log.debug("Connector (" + currentDefinition.getId()
- + ") already resolved for this request, using cached version");
- return (Attributes) requestCache.get(currentDefinition.getId());
- }
-
- // Check to see if we have a cached resolution for this connector
- if (currentDefinition.getTTL() > 0) {
- Attributes cachedAttributes = resolverCache.getResolvedConnector(principal, currentDefinition.getId());
- if (cachedAttributes != null) {
- log.debug("Connector (" + currentDefinition.getId()
- + ") resolution cached from a previous request, using cached version");
- return cachedAttributes;
- }
- }
-
- // Resolve all attribute dependencies
- String[] attributeDependencies = currentDefinition.getAttributeDefinitionDependencyIds();
- Dependencies depends = new Dependencies();
-
- for (int i = 0; attributeDependencies.length > i; i++) {
- log.debug("Connector (" + currentDefinition.getId() + ") depends on attribute (" + attributeDependencies[i]
- + ").");
- ResolverAttribute dependant = requestedAttributes.get(attributeDependencies[i]);
- if (dependant == null) {
- dependant = new DependentOnlyResolutionAttribute(attributeDependencies[i]);
- }
- resolveAttribute(dependant, principal, requester, responder, requestCache, requestedAttributes);
- depends.addAttributeResolution(attributeDependencies[i], dependant);
-
- }
-
- // Resolve all connector dependencies
- String[] connectorDependencies = currentDefinition.getDataConnectorDependencyIds();
- for (int i = 0; connectorDependencies.length > i; i++) {
- log.debug("Connector (" + currentDefinition.getId() + ") depends on connector (" + connectorDependencies[i]
- + ").");
- depends.addConnectorResolution(connectorDependencies[i], resolveConnector(connectorDependencies[i],
- principal, requester, responder, requestCache, requestedAttributes));
- }
-
- // Resolve the connector
- Attributes resolvedAttributes = null;
- try {
- resolvedAttributes = currentDefinition.resolve(principal, requester, responder, depends);
-
- // Add attribute resolution to cache
- if (currentDefinition.getTTL() > 0) {
- resolverCache.cacheConnectorResolution(principal, currentDefinition.getId(),
- currentDefinition.getTTL(), resolvedAttributes);
- }
- } catch (ResolutionPlugInException e) {
- // Something went wrong, so check for a fail-over...
- if (currentDefinition.getFailoverDependencyId() != null) {
- log.warn("Connector (" + currentDefinition.getId() + ") failed, invoking failover dependency");
- resolvedAttributes = resolveConnector(currentDefinition.getFailoverDependencyId(), principal,
- requester, responder, requestCache, requestedAttributes);
- } else if (currentDefinition.getPropagateErrors()) {
- throw e;
- } else {
- log.warn("Connector (" + currentDefinition.getId()
- + ") returning empty attribute set instead of propagating error: " + e);
- resolvedAttributes = new BasicAttributes();
- }
- }
-
- // Cache for this request
- requestCache.put(currentDefinition.getId(), resolvedAttributes);
- return resolvedAttributes;
- }
-
- private void resolveAttribute(ResolverAttribute attribute, Principal principal, String requester, String responder,
- Map<String, ResolverAttribute> requestCache, Map<String, ResolverAttribute> requestedAttributes)
- throws ResolutionPlugInException {
-
- AttributeDefinitionPlugIn currentDefinition = (AttributeDefinitionPlugIn) plugIns.get(attribute.getName());
-
- // Check to see if we have already resolved the attribute during this request
- // (this checks dependency-only attributes and attributes resolved with no values
- if (requestCache.containsKey(currentDefinition.getId())) {
- log.debug("Attribute (" + currentDefinition.getId()
- + ") already resolved for this request, using cached version");
- attribute.resolveFromCached((ResolverAttribute) requestCache.get(currentDefinition.getId()));
- return;
- }
-
- // Check to see if we have already resolved the attribute during this request
- // (this checks attributes that were submitted to the AR for resolution)
- ResolverAttribute requestedAttribute = requestedAttributes.get(currentDefinition.getId());
- if (requestedAttribute != null && requestedAttribute.resolved()) {
- attribute.resolveFromCached(requestedAttribute);
- return;
- }
-
- // Check to see if we have a cached resolution for this attribute
- if (currentDefinition.getTTL() > 0) {
- ResolverAttribute cachedAttribute = resolverCache
- .getResolvedAttribute(principal, currentDefinition.getId());
- if (cachedAttribute != null) {
- log.debug("Attribute (" + currentDefinition.getId()
- + ") resolution cached from a previous request, using cached version");
- attribute.resolveFromCached(cachedAttribute);
- return;
- }
- }
-
- // Resolve all attribute dependencies
- Dependencies depends = new Dependencies();
- String[] attributeDependencies = currentDefinition.getAttributeDefinitionDependencyIds();
-
- boolean dependancyOnly = false;
- for (int i = 0; attributeDependencies.length > i; i++) {
- log.debug("Attribute (" + attribute.getName() + ") depends on attribute (" + attributeDependencies[i]
- + ").");
- ResolverAttribute dependant = requestedAttributes.get(attributeDependencies[i]);
- if (dependant == null) {
- dependancyOnly = true;
- dependant = new DependentOnlyResolutionAttribute(attributeDependencies[i]);
- }
- resolveAttribute(dependant, principal, requester, responder, requestCache, requestedAttributes);
- depends.addAttributeResolution(attributeDependencies[i], dependant);
-
- }
-
- // Resolve all connector dependencies
- String[] connectorDependencies = currentDefinition.getDataConnectorDependencyIds();
- for (int i = 0; connectorDependencies.length > i; i++) {
- log.debug("Attribute (" + attribute.getName() + ") depends on connector (" + connectorDependencies[i]
- + ").");
- depends.addConnectorResolution(connectorDependencies[i], resolveConnector(connectorDependencies[i],
- principal, requester, responder, requestCache, requestedAttributes));
- }
-
- // Resolve the attribute
- try {
- currentDefinition.resolve(attribute, principal, requester, responder, depends);
-
- // Add attribute resolution to cache
- if (currentDefinition.getTTL() > 0) {
- resolverCache.cacheAttributeResolution(principal, attribute.getName(), currentDefinition.getTTL(),
- attribute);
- }
- } catch (ResolutionPlugInException e) {
- if (currentDefinition.getPropagateErrors()) {
- throw e;
- } else {
- log.warn("Attribute (" + currentDefinition.getId()
- + ") returning no values instead of propagating error: " + e);
- }
- }
-
- // If necessary, cache for this request
- if (dependancyOnly || !attribute.hasValues()) {
- requestCache.put(currentDefinition.getId(), attribute);
- }
- }
-
- private class DuplicatePlugInException extends Exception {
-
- public DuplicatePlugInException(String message) {
-
- super(message);
- }
- }
-
- class DependentOnlyResolutionAttribute implements ResolverAttribute {
-
- String name;
- ArrayList values = new ArrayList();
- boolean resolved = false;
-
- DependentOnlyResolutionAttribute(String name) {
-
- this.name = name;
- }
-
- public String getName() {
-
- return name;
- }
-
- public boolean resolved() {
-
- return resolved;
- }
-
- public void setResolved() {
-
- resolved = true;
- }
-
- public void resolveFromCached(ResolverAttribute attribute) {
-
- }
-
- public void setLifetime(long lifetime) {
-
- }
-
- public void setNamespace(String namespace) {
-
- }
-
- public long getLifetime() {
-
- return 0;
- }
-
- public void addValue(Object value) {
-
- values.add(value);
- }
-
- public Iterator getValues() {
-
- return values.iterator();
- }
-
- public boolean hasValues() {
-
- if (values.isEmpty()) { return false; }
- return true;
- }
-
- public void registerValueHandler(ValueHandler handler) {
-
- }
-
- public ValueHandler getRegisteredValueHandler() {
-
- return null;
- }
- }
-
- /**
- * Cleanup resources that won't be released when this object is garbage-collected
- */
- public void destroy() {
-
- resolverCache.destroy();
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-/**
- * Signals that an error occurred while the <code>AttributeResolver</code> was attempting to resolve the specified
- * attributes.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class AttributeResolverException extends Exception {
-
- public AttributeResolverException(String message) {
-
- super(message);
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-import java.security.Principal;
-
-import javax.naming.directory.Attributes;
-
-/**
- * Defines a Data Connector PlugIn for the AA Attribute Resolver. Such plugins represent connection points to external
- * data sources from which attribute data is gathered.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public interface DataConnectorPlugIn extends ResolutionPlugIn {
-
- /**
- * Returns the name of a data connector to resolve if this one fails.
- *
- * @return String an Id
- */
- public String getFailoverDependencyId();
-
- /**
- * Resolves the values of a data connector.
- *
- * @param principal
- * The principal for which the connector should be resolved
- * @param requester
- * The name of the entity making the resolution request *
- * @param responder
- * The name of the entity responding to the resolution request
- * @param depends
- * Resolution dependencies
- * @throws ResolutionPlugInException
- */
- public Attributes resolve(Principal principal, String requester, String responder, Dependencies depends)
- throws ResolutionPlugInException;
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.naming.directory.Attributes;
-
-/**
- * Contains resolved <code>ResolutionPlugIn</code> objects that a particular Attribute Definition PlugIn relies upon
- * for its resolution.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class Dependencies {
-
- protected Map resolvedAttributeDependencies = new HashMap();
- protected Map resolvedConnectorDependencies = new HashMap();
-
- public Attributes getConnectorResolution(String id) {
-
- if (resolvedConnectorDependencies.containsKey(id)) {
- return (Attributes) resolvedConnectorDependencies.get(id);
- } else {
- return null;
- }
- }
-
- void addConnectorResolution(String id, Attributes attrs) {
-
- resolvedConnectorDependencies.put(id, attrs);
- }
-
- public ResolverAttribute getAttributeResolution(String id) {
-
- if (resolvedAttributeDependencies.containsKey(id)) {
- return (ResolverAttribute) resolvedAttributeDependencies.get(id);
- } else {
- return null;
- }
- }
-
- void addAttributeResolution(String id, ResolverAttribute attr) {
-
- resolvedAttributeDependencies.put(id, attr);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-/**
- * Defines a plugin for the AA Attribute Resolver. Such plugins can be realized at runtime by the resolver.
- *
- * @author Walter Hoehn
- *
- */
-public interface ResolutionPlugIn {
-
- /**
- * Returns the name of the plugin.
- *
- * @return String a plugin name
- */
- public String getId();
-
- /**
- * Returns the time in seconds to cache the results of the plugin's resolution.
- *
- * @return long time in seconds
- */
- public long getTTL();
-
- /**
- * Returns whether to trap and log resolution errors and return nothing, or propagate errors up as exceptions.
- *
- * @return boolean whether to propagate errors
- */
- public boolean getPropagateErrors();
-
- /**
- * Returns an array containing the names of the attribute definitions that this definition depends upon for
- * resolution.
- *
- * @return String[] an array of Ids
- */
- public String[] getAttributeDefinitionDependencyIds();
-
- /**
- * Returns an array containining the names of the connectors that this definition depends upon for resolution.
- *
- * @return String[] an array of Ids
- */
- public String[] getDataConnectorDependencyIds();
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-/**
- * Signals that an error occurred while constucting or resolving a <code>ResolutionPlugIn</code>.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class ResolutionPlugInException extends AttributeResolverException {
-
- public ResolutionPlugInException(String message) {
-
- super(message);
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.] Licensed under the Apache License,
- * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy
- * of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in
- * writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
- * OF ANY KIND, either express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.CompositeAttributeDefinition;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.CustomAttributeDefinition;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.CustomDataConnector;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.FormattedAttributeDefinition;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.JDBCDataConnector;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.JNDIDirectoryDataConnector;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.MappedAttributeDefinition;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.PersistentIDAttributeDefinition;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.RegExAttributeDefinition;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.SAML2PersistentID;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ScriptletAttributeDefinition;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.SimpleAttributeDefinition;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.StaticDataConnector;
-
-/**
- * Factory that instanciates Resolution PlugIns based on Resolver configuration elements.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public class ResolutionPlugInFactory {
-
- private static Logger log = Logger.getLogger(ResolutionPlugInFactory.class.getName());
-
- public static ResolutionPlugIn createPlugIn(Element e) throws AttributeResolverException {
-
- if (e.getTagName().equals("CustomDataConnector")) { return new CustomDataConnector(e); }
-
- if (e.getTagName().equals("CustomAttributeDefinition")) { return new CustomAttributeDefinition(e); }
-
- if (e.getTagName().equals("SimpleAttributeDefinition")) { return new SimpleAttributeDefinition(e); }
-
- if (e.getTagName().equals("SAML2PersistentID")) { return new SAML2PersistentID(e); }
-
- if (e.getTagName().equals("PersistentIDAttributeDefinition")) { return new PersistentIDAttributeDefinition(e); }
-
- if (e.getTagName().equals("JNDIDirectoryDataConnector")) { return new JNDIDirectoryDataConnector(e); }
-
- if (e.getTagName().equals("JDBCDataConnector")) { return new JDBCDataConnector(e); }
-
- if (e.getTagName().equals("StaticDataConnector")) { return new StaticDataConnector(e); }
-
- if (e.getTagName().equals("RegExAttributeDefinition")) { return new RegExAttributeDefinition(e); }
-
- if (e.getTagName().equals("FormattedAttributeDefinition")) { return new FormattedAttributeDefinition(e); }
-
- if (e.getTagName().equals("CompositeAttributeDefinition")) { return new CompositeAttributeDefinition(e); }
-
- if (e.getTagName().equals("MappedAttributeDefinition")) { return new MappedAttributeDefinition(e); }
-
- if (e.getTagName().equals("ScriptletAttributeDefinition")) { return new ScriptletAttributeDefinition(e); }
-
- log.error("Unrecognized PlugIn type: " + e.getTagName());
- throw new AttributeResolverException("Failed to initialize PlugIn.");
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-import java.util.Iterator;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ValueHandler;
-
-/**
- * Defines an attribute that can be resolved by the <code>AttributeResolver</code>.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public interface ResolverAttribute {
-
- /** Returns the Name of the attribute. */
- public String getName();
-
- /** Boolean indicator of whether the attribute has been resolved by the Attribute Resolver. */
- public boolean resolved();
-
- /** This method signals that the attribute has been resolved by the Attribute Resolver. */
- public void setResolved();
-
- /**
- * Resolves the attribute based on a previous resolution.
- *
- * @param attribute
- * the previously resolved attribute
- */
- public void resolveFromCached(ResolverAttribute attribute);
-
- /** Sets the time, in seconds, for which this attribute is valid. */
- public void setLifetime(long lifetime);
-
- public void setNamespace(String namespace);
-
- /** Returns the time, in seconds, for which this attribute is valid. */
- public long getLifetime();
-
- public void addValue(Object value);
-
- public Iterator getValues();
-
- public boolean hasValues();
-
- public void registerValueHandler(ValueHandler handler);
-
- public ValueHandler getRegisteredValueHandler();
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv;
-
-import java.security.Principal;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.naming.directory.Attributes;
-
-import org.apache.log4j.Logger;
-
-/**
- * Rudimentary mechanism for caching objects created by the various Resolution PlugIns.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- *
- */
-public class ResolverCache {
-
- private static Logger log = Logger.getLogger(ResolverCache.class.getName());
- // Hashtable handles synchronization for us
- private Hashtable attributeDataCache = new Hashtable();
- private Hashtable connectorDataCache = new Hashtable();
- private Cleaner cleaner = new Cleaner();
-
- ResolverCache() {
-
- log.info("Initializing the Attribute Resolver cache.");
- }
-
- void cacheConnectorResolution(Principal principal, String plugInId, long cacheLength, Attributes toCache) {
-
- if (principal != null && cacheLength > 0 && plugInId != null && !plugInId.equals("") && toCache != null) {
- log.debug("Adding resolved Connector data to Attribute Resolver cache.");
- connectorDataCache.put(new CacheKey(principal, plugInId), new CacheObject(toCache, System
- .currentTimeMillis()
- + (cacheLength * 1000)));
-
- } else {
- log.error("Attempted to add bad data to Attribute Resolver cache.");
- }
- }
-
- void cacheAttributeResolution(Principal principal, String plugInId, long cacheLength, ResolverAttribute toCache) {
-
- if (principal != null && cacheLength > 0 && plugInId != null && !plugInId.equals("") && toCache != null) {
- log.debug("Adding resolved Attribute data to Attribute Resolver cache.");
- attributeDataCache.put(new CacheKey(principal, plugInId), new CacheObject(toCache, System
- .currentTimeMillis()
- + (cacheLength * 1000)));
-
- } else {
- log.error("Attempted to add bad data to Attribute Resolver cache.");
- }
- }
-
- ResolverAttribute getResolvedAttribute(Principal principal, String plugInId) {
-
- log.debug("Searching Cache for resolved attribute.");
- Object object = attributeDataCache.get(new CacheKey(principal, plugInId));
- if (object == null) {
- log.debug("No match found.");
- return null;
- } else {
- CacheObject cacheObject = (CacheObject) object;
- if (cacheObject.isExpired()) {
- deleteAttributeResolution(new CacheKey(principal, plugInId));
- log.debug("Cached entry is expired.");
- return null;
- } else {
- log.debug("Located cached entry.");
- return (ResolverAttribute) cacheObject.getCached();
- }
- }
- }
-
- Attributes getResolvedConnector(Principal principal, String plugInId) {
-
- log.debug("Searching Cache for resolved connector.");
- Object object = connectorDataCache.get(new CacheKey(principal, plugInId));
- if (object == null) {
- log.debug("No match found.");
- return null;
- } else {
- CacheObject cacheObject = (CacheObject) object;
- if (cacheObject.isExpired()) {
- deleteConnectorResolution(new CacheKey(principal, plugInId));
- log.debug("Cached entry is expired.");
- return null;
- } else {
- log.debug("Located cached entry.");
- return (Attributes) cacheObject.getCached();
- }
- }
- }
-
- private void deleteAttributeResolution(CacheKey cacheKey) {
-
- synchronized (attributeDataCache) {
- Object object = attributeDataCache.get(cacheKey);
- if (object != null) {
- CacheObject cacheObject = (CacheObject) object;
- if (cacheObject.isExpired()) {
- attributeDataCache.remove(cacheKey);
- }
- }
-
- }
- }
-
- private void deleteConnectorResolution(CacheKey cacheKey) {
-
- synchronized (connectorDataCache) {
- Object object = connectorDataCache.get(cacheKey);
- if (object != null) {
- CacheObject cacheObject = (CacheObject) object;
- if (cacheObject.isExpired()) {
- connectorDataCache.remove(cacheKey);
- }
- }
-
- }
- }
-
- /**
- * @see java.lang.Object#finalize()
- */
- protected void finalize() throws Throwable {
-
- super.finalize();
- destroy();
- }
-
- /**
- * Cleanup resources that won't be released when this object is garbage-collected
- */
- protected void destroy() {
-
- synchronized (cleaner) {
- if (cleaner != null) {
- cleaner.shutdown = true;
- cleaner.interrupt();
- }
- }
- }
-
- private class CacheObject {
-
- Object object;
- long expiration;
-
- private CacheObject(Object object, long expiration) {
-
- this.object = object;
- this.expiration = expiration;
- }
-
- private Object getCached() {
-
- return object;
- }
-
- private boolean isExpired() {
-
- if (System.currentTimeMillis() > expiration) {
- return true;
- } else {
- return false;
- }
- }
- }
-
- private class CacheKey {
-
- private Principal principal;
- private String plugInId;
-
- private CacheKey(Principal principal, String plugInId) {
-
- if (principal == null || plugInId == null) { throw new IllegalArgumentException(
- "Cannot use null value in as cache key."); }
- this.principal = principal;
- this.plugInId = plugInId;
- }
-
- /**
- * @see java.lang.Object#equals(Object)
- */
- public boolean equals(Object object) {
-
- if (object == null || !(object instanceof CacheKey)) { return false; }
- if (!plugInId.equals(((CacheKey) object).getPlugInId())) { return false; }
- if (!principal.equals(((CacheKey) object).getPrincipal())) { return false; }
- return true;
- }
-
- /**
- * Method getPlugInId.
- *
- * @return Object
- */
- private String getPlugInId() {
-
- return plugInId;
- }
-
- /**
- * Method getPrincipal.
- *
- * @return Object
- */
- private Principal getPrincipal() {
-
- return principal;
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- public int hashCode() {
-
- return (principal.hashCode() + ":" + plugInId.hashCode()).hashCode();
- }
-
- }
-
- private class Cleaner extends Thread {
-
- private boolean shutdown = false;
- private Object master;
-
- public Cleaner() {
-
- super("edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverCacher.Cleaner");
- master = Thread.currentThread();
- setDaemon(true);
- if (getPriority() > Thread.MIN_PRIORITY) {
- setPriority(getPriority() - 1);
- }
- log.debug("Starting Resolver Cache cleanup thread.");
- start();
- }
-
- public void run() {
-
- try {
- sleep(60 * 1000); // one minute
- } catch (InterruptedException e) {
- log.debug("Resolver Cache Cleanup interrupted.");
- }
-
- while (true) {
- try {
- if (master == null) {
- log.debug("Resolver cache cleaner is orphaned.");
- shutdown = true;
- }
- if (shutdown) {
- log.debug("Stopping Resolver cache cleanup thread.");
- return;
- }
-
- log.debug("Resolver Cache cleanup thread searching cache for stale entries.");
- Hashtable[] caches = {attributeDataCache, connectorDataCache};
-
- for (int i = 0; i < caches.length; i++) {
- Set stale = new HashSet();
- synchronized (caches[i]) {
- Set keySet = caches[i].keySet();
- Iterator cachedAttributes = keySet.iterator();
- while (cachedAttributes.hasNext()) {
- CacheKey key = (CacheKey) cachedAttributes.next();
- CacheObject object = (CacheObject) caches[i].get(key);
- if (object != null && object.isExpired()) {
- log.debug("Found a stale resolution in the cache.");
- stale.add(key);
- }
- }
- }
-
- synchronized (caches[i]) {
- if (!stale.isEmpty()) {
- Iterator stales = stale.iterator();
- while (stales.hasNext()) {
- log.debug("Expiring stale Resolutions from the Cache.");
- Object removed = caches[i].remove(stales.next());
- if (removed != null) {
- log.debug("Entry expired.");
- } else {
- log.debug("Couldn't expire entry. Not found in cache.");
- }
- }
- }
- }
- }
-
- sleep(60 * 1000); // one minute
-
- } catch (InterruptedException e) {
- log.debug("Resolver Cache Cleanup interrupted.");
- }
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.bouncycastle.util.encoders.Base64;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * <code>ValueHandler</code> implementation for encoding byte array values in Base64..
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class Base64ValueHandler implements ValueHandler {
-
- public void toDOM(Element valueElement, Object value, Document document) throws ValueHandlerException {
-
- if (!(value instanceof byte[])) { throw new ValueHandlerException(
- "Base64ValueHandler could not encode a value of type: " + value.getClass().getName()); }
- valueElement.appendChild(document.createTextNode(new String(Base64.encode((byte[]) value))));
- }
-
- public Iterator getValues(Collection internalValues) {
-
- return internalValues.iterator();
- }
-
- public boolean equals(Object object) {
-
- if (object instanceof Base64ValueHandler) { return true; }
- return false;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.security.Principal;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute;
-
-/**
- * Base class for Attribute Definition PlugIns. Provides basic functionality such as dependency mapping. Subclasses must
- * provide resolution logic.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public abstract class BaseAttributeDefinition extends BaseResolutionPlugIn implements AttributeDefinitionPlugIn {
-
- public final static String SHIB_ATTRIBUTE_NAMESPACE_URI = "urn:mace:shibboleth:1.0:attributeNamespace:uri";
- protected String namespace = SHIB_ATTRIBUTE_NAMESPACE_URI;
-
- protected ValueHandler valueHandler;
- protected String connectorMapping;
- /** The time, in seconds, for which attribute created from this definition should be valid. */
- protected long lifeTime = -1;
-
- private static Logger log = Logger.getLogger(BaseAttributeDefinition.class.getName());
-
- protected BaseAttributeDefinition(Element e) throws ResolutionPlugInException {
-
- super(e);
-
- String lifeTimeSpec = e.getAttribute("lifeTime");
- if (lifeTimeSpec != null && !lifeTimeSpec.equals("")) {
- try {
- lifeTime = Long.valueOf(lifeTimeSpec).longValue();
- log.debug("Explicit lifetime set for attribute (" + getId() + "). Lifetime: (" + lifeTime + ").");
- } catch (NumberFormatException nfe) {
- log.error("Bad value for attribute (lifeTime) for Attribute Definition (" + getId() + ").");
- }
- }
-
- String namespaceSpec = e.getAttribute("namespace");
- if (namespaceSpec != null && !namespaceSpec.equals("")) {
- namespace = namespaceSpec;
- }
-
- // Parse source name
- String sourceName = e.getAttribute("sourceName");
- if (sourceName == null || sourceName.equals("")) {
- int index = getId().lastIndexOf("#");
- if (index < 0) {
- index = getId().lastIndexOf(":");
- int slashIndex = getId().lastIndexOf("/");
- if (slashIndex > index) {
- index = slashIndex;
- }
- }
- connectorMapping = getId().substring(index + 1);
- } else {
- connectorMapping = sourceName;
- }
-
- log.debug("Mapping attribute to name (" + connectorMapping + ") in connector.");
-
- // Load a value handler
- String valueHandlerSpec = e.getAttribute("valueHandler");
-
- if (valueHandlerSpec != null && !valueHandlerSpec.equals("")) {
- try {
- Class handlerClass = Class.forName(valueHandlerSpec);
- valueHandler = (ValueHandler) handlerClass.newInstance();
- } catch (ClassNotFoundException cnfe) {
- log.error("Value Handler implementation specified for attribute (" + getId() + ") cannot be found: "
- + cnfe);
- throw new ResolutionPlugInException("Value Handler implementation specified for attribute (" + getId()
- + ") cannot be found.");
- } catch (Exception oe) {
- log.error("Value Handler implementation specified for attribute (" + getId()
- + ") coudl not be loaded: " + oe);
- throw new ResolutionPlugInException("Value Handler implementation specified for attribute (" + getId()
- + ") could not be loaded.");
- }
- }
-
- if (valueHandler != null) {
- log.debug("Custom Value Handler enabled for attribute (" + getId() + ").");
- }
- }
-
- /**
- * Should be run by all sublcasses during resolution. Doesn't do resolution in and of itself.
- */
- public void resolve(ResolverAttribute attribute, Principal principal, String requester, String responder,
- Dependencies depends) throws ResolutionPlugInException {
-
- if (lifeTime != -1) {
- attribute.setLifetime(lifeTime);
- }
-
- attribute.setNamespace(namespace);
-
- if (valueHandler != null) {
- attribute.registerValueHandler(valueHandler);
- }
-
- }
-
- protected String convertToString(Object value) {
-
- /*
- * This was inspired by the fact that certain attributes (such as userPassword, when read using JNDI) are
- * returned from data connectors as byte [] rather than String, and doing a .toString() returns something like
- * B[@aabljadj, which is a reference to the array, rather than the string value.
- */
- if (value instanceof byte[]) { return new String((byte[]) value); }
- if (value instanceof String) { return (String) value; }
- return value.toString();
- }
-
- protected Collection<Object> getAllValuesFromConnectorDeps(Dependencies depends) {
-
- Set<Object> results = new LinkedHashSet<Object>();
-
- Iterator connectorDependIt = connectorDependencyIds.iterator();
- while (connectorDependIt.hasNext()) {
- Attributes attrs = depends.getConnectorResolution((String) connectorDependIt.next());
- if (attrs != null) {
- Attribute attr = attrs.get(connectorMapping);
- if (attr != null) {
- log.debug("Found value(s) for attribute (" + getId() + ").");
- try {
- NamingEnumeration valuesEnum = attr.getAll();
- while (valuesEnum.hasMore()) {
- results.add(valuesEnum.next());
- }
- } catch (NamingException e) {
- log.error("An problem was encountered resolving the dependencies of attribute (" + getId()
- + "): " + e);
- }
- }
- }
- }
-
- if (results.isEmpty()) {
- log.debug("A connector dependency of attribute (" + getId() + ") supplied no values.");
- }
- return results;
- }
-
- protected Collection<Object> getAllValuesFromAttributeDeps(Dependencies depends) {
-
- Set<Object> results = new LinkedHashSet<Object>();
-
- Iterator attrDependIt = attributeDependencyIds.iterator();
- while (attrDependIt.hasNext()) {
- ResolverAttribute attribute = depends.getAttributeResolution((String) attrDependIt.next());
- if (attribute != null) {
- log.debug("Found value(s) for attribute (" + getId() + ").");
- for (Iterator iterator = attribute.getValues(); iterator.hasNext();) {
- results.add(iterator.next());
- }
- } else {
- log.error("An attribute dependency of attribute (" + getId()
- + ") was not included in the dependency chain.");
- }
- }
-
- if (results.isEmpty()) {
- log.debug("An attribute dependency of attribute (" + getId() + ") supplied no values.");
- }
- return results;
- }
-
- protected Collection<Object> getValuesFromAllDeps(ResolverAttribute attribute, Principal principal,
- String requester, Dependencies depends) throws ResolutionPlugInException {
-
- log.debug("Resolving attribute: (" + getId() + ")");
- Set<Object> results = new LinkedHashSet<Object>();
- if (!connectorDependencyIds.isEmpty()) {
- results.addAll(getAllValuesFromConnectorDeps(depends));
- }
- if (!attributeDependencyIds.isEmpty()) {
- results.addAll(getAllValuesFromAttributeDeps(depends));
- }
- return results;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeResolver;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
-
-/**
- * Base class for Data Connector PlugIns. Provides basic functionality such as failover tracking. Subclasses must
- * provide resolution logic.
- *
- * @author Scott Cantor (cantor.2@osu.edu)
- */
-
-public abstract class BaseDataConnector extends BaseResolutionPlugIn implements DataConnectorPlugIn {
-
- /** A backup connector to use if this one fails. */
- protected String failover = null;
-
- protected BaseDataConnector(Element e) throws ResolutionPlugInException {
-
- super(e);
-
- NodeList failoverNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "FailoverDependency");
- if (failoverNodes.getLength() > 0) {
- failover = ((Element) failoverNodes.item(0)).getAttribute("requires");
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn#getFailoverDependencyId()
- */
- public String getFailoverDependencyId() {
-
- return failover;
- }
-
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeResolver;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
-
-/**
- * Base class for Resolution PlugIns, both <code>AttributeDefinitionPlugIn</code>&<code>DataConnectorPlugIn</code>
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public abstract class BaseResolutionPlugIn implements ResolutionPlugIn {
-
- private static Logger log = Logger.getLogger(BaseResolutionPlugIn.class.getName());
-
- /** The identifier for this PlugIn. */
- protected String id;
-
- /** Time, in seconds, for which the Attribute Resolver should cache resolutions of this PlugIn. */
- protected long ttl = 0;
-
- /** Whether to propagate errors out of the PlugIn as exceptions. */
- protected boolean propagateErrors = true;
-
- /** Dependencies. */
- protected Set connectorDependencyIds = new LinkedHashSet();
- protected Set attributeDependencyIds = new LinkedHashSet();
-
- protected BaseResolutionPlugIn(Element e) throws ResolutionPlugInException {
-
- String id = e.getAttribute("id");
- if (id == null || id.equals("")) {
- log.error("Attribute \"id\" required to configure plugin.");
- throw new ResolutionPlugInException("Failed to initialize Resolution PlugIn.");
- }
- this.id = id;
-
- String cacheTime = e.getAttribute("cacheTime");
- if (cacheTime != null && !cacheTime.equals("")) {
- try {
- this.ttl = Long.parseLong(cacheTime);
- } catch (NumberFormatException nfe) {
- log.error("Attribute \"cacheTime\" must be an integer between 0 and " + Long.MAX_VALUE + ".");
- throw new ResolutionPlugInException("Failed to initialize Resolution PlugIn.");
- }
- }
-
- String propagateFlag = e.getAttribute("propagateErrors");
- if (propagateFlag != null && (propagateFlag.equals("false") || propagateFlag.equals("0"))) {
- propagateErrors = false;
- }
-
- NodeList connectorNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace,
- "DataConnectorDependency");
-
- for (int i = 0; connectorNodes.getLength() > i; i++) {
- Element connector = (Element) connectorNodes.item(i);
- String connectorName = connector.getAttribute("requires");
- if (connectorName != null && !connectorName.equals("")) {
- addDataConnectorDependencyId(connectorName);
- } else {
- log.error("Data Connector dependency must be accompanied by a \"requires\" attribute.");
- throw new ResolutionPlugInException("Failed to initialize Resolution PlugIn.");
- }
- }
-
- NodeList attributeNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "AttributeDependency");
- for (int i = 0; attributeNodes.getLength() > i; i++) {
- Element attribute = (Element) attributeNodes.item(i);
- String attributeName = attribute.getAttribute("requires");
- if (attributeName != null && !attributeName.equals("")) {
- addAttributeDefinitionDependencyId(attributeName);
- } else {
- log.error("Attribute Definition dependency must be accompanied by a \"requires\" attribute.");
- throw new ResolutionPlugInException("Failed to initialize Resolution PlugIn.");
- }
- }
- }
-
- /** Returns the identifier for this PlugIn. */
- public String getId() {
-
- return id;
- }
-
- /** Returns the time, in seconds, for which the Attribute Resolver should cache resolutions of this PlugIn. */
- public long getTTL() {
-
- return ttl;
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn#getPropagateErrors()
- */
- public boolean getPropagateErrors() {
-
- return propagateErrors;
- }
-
- protected void addDataConnectorDependencyId(String id) {
-
- connectorDependencyIds.add(id);
- }
-
- protected void addAttributeDefinitionDependencyId(String id) {
-
- attributeDependencyIds.add(id);
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn#getAttributeDependencyIds()
- */
- public String[] getAttributeDefinitionDependencyIds() {
-
- return (String[]) attributeDependencyIds.toArray(new String[0]);
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn#getConnectorDependencyIds()
- */
- public String[] getDataConnectorDependencyIds() {
-
- return (String[]) connectorDependencyIds.toArray(new String[0]);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Contributed by SunGard SCT.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.security.Principal;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.BasicAttributes;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute;
-
-/**
- * The CompositeAttributeDefinition allows composing a single attribute from multiple attributes. It is particularly
- * useful when values from several columns of a DataBase must be 'concatenated' to form a single composite attribute. To
- * ensure that the results are same for a given set of source values, multi-valued source attributes must be ordered and
- * each must have the same number of values. This is true for the attribute values read using the JDBCDataConnector, but
- * not true with attributes read using the JNDIDirectoryDataConnector or the LDAPDirectoryDataConnector. Hence,
- * CompositeAttributeDefinition is only currently meaningful for attributes read from an RDB using the
- * JDBCDataConnector. The specification of this attribute definition is simple. You specify which source attributes to
- * compose and the format for composing them using the notation of java.text.MessageFormat. The format defaults to a
- * space separated concatenation of all source attributes. One use case is in the construction of a labeledURI attribute
- * from two attributes, the 'URL' and the 'URL_Title' that may appear as two columns in a DataBase. As per the
- * definition of labeledURI, it is essentially a 'space' separated concatenation of URL followed by the title. Since URL
- * itself should not contain any spaces (assuming it is properly encoded, converting spaces to +), where the URL ends
- * and the title begins is unambiguous. The specification fpr such a composite attribute is simply: format="{0} {1}"
- * orderedSourceNames="URL, URL_Title" The format definition in the above example is optional, since that is infact the
- * default if not specified. Another example of usage of this attribute is as follows: format="{0} ({1})"
- * orderedSourceNames="Group_Name, Group_Title" Notice that in this example, we are composing the name of a Group and
- * the descriptive title of the group in parenthesis using the format to create a single attribute from two attributes.
- *
- * @author <a href="mailto:vgoenka@sungardsct.com">Vishal Goenka </a>
- */
-
-/**
- * @author Walter Hoehn
- */
-public class CompositeAttributeDefinition extends BaseAttributeDefinition implements AttributeDefinitionPlugIn {
-
- private static Logger log = Logger.getLogger(CompositeAttributeDefinition.class.getName());
-
- // The formatter used to compose from all Source Attributes
- private MessageFormat sourceFormat;
-
- // Names of source attributes to compose the target from, in ordered list
- private String[] sourceNames;
-
- // Names of source attributes in a Set for convenience of checking membership
- private Set<String> sourceNamesSet;
-
- public CompositeAttributeDefinition(Element e) throws ResolutionPlugInException {
-
- super(e);
-
- try {
- // Since there are more than one source objects in an ordered list, one sourceName doesn't make sense. In
- // this
- // respect, it differs from other attribute definition
- if (e.hasAttribute("sourceName"))
- throw new ResolutionPlugInException(
- "sourceName is not an allowed attribute for CompositeAttributeDefinition (" + getId() + ")");
-
- String orderedSourceNames = e.getAttribute("orderedSourceNames");
- if ((orderedSourceNames == null) || ("".equals(orderedSourceNames)))
- throw new ResolutionPlugInException(
- "orderedSourceNames is a required attribute for CompositeAttributeDefinition (" + getId() + ")");
-
- // We assume space or comma as separators
- StringTokenizer st = new StringTokenizer(orderedSourceNames, " ,");
- ArrayList<String> sourceNamesList = new ArrayList<String>();
- while (st.hasMoreTokens()) {
- String token = st.nextToken().trim();
- if (token.length() > 0) sourceNamesList.add(token);
- }
- sourceNamesSet = new HashSet<String>();
- sourceNamesSet.addAll(sourceNamesList);
- sourceNames = (String[]) sourceNamesList.toArray(new String[0]);
-
- String format = e.getAttribute("format");
- // default format is essentially all ordered attribute values separated by a space
- if ((format == null) || ("".equals(format))) {
- StringBuffer defaultFormat = new StringBuffer();
- for (int i = 0; i < sourceNames.length; i++) {
- defaultFormat.append("{").append(i).append("}");
- if (i < sourceNames.length - 1) defaultFormat.append(" ");
- }
- format = defaultFormat.toString();
- }
- sourceFormat = new MessageFormat(format);
- } catch (ResolutionPlugInException ex) {
- // To ensure that exceptions thrown in the constructor are logged!
- log.error(ex.getMessage());
- throw ex;
- } catch (RuntimeException ex) {
- // To ensure that exceptions thrown in the constructor are logged!
- log.error(ex.getMessage());
- throw ex;
- }
- }
-
- /**
- * Get ordered attribute values for all source attributes from the dependent data connectors. The values of all
- * multi-valued attribute MUST be ordered and MUST be of same size or else the results can be unpredictable.
- */
- private int addAttributesFromConnectors(Dependencies depends, Attributes sourceAttrs, int valueCount)
- throws ResolutionPlugInException {
-
- Iterator connectorDependIt = connectorDependencyIds.iterator();
- while (connectorDependIt.hasNext()) {
- Attributes attrs = depends.getConnectorResolution((String) connectorDependIt.next());
- if (attrs != null) {
- for (int i = 0; i < sourceNames.length; i++) {
- Attribute attr = attrs.get(sourceNames[i]);
- if (attr != null) {
- int size = attr.size();
- if (!attr.isOrdered() && (size > 1)) { throw new ResolutionPlugInException(
- "Multi-valued attribute (" + attr.getID()
- + ") MUST be ordered for CompositeAttributeDefinition (" + getId() + ")"); }
- if (valueCount == -1) {
- valueCount = size; // initialize valueCount
- } else if (valueCount != size) { throw new ResolutionPlugInException("Multi-valued attribute ("
- + attr.getID() + ") has different number of values (" + size
- + ") than other attribute(s) that have (" + valueCount + ") values. "
- + "All attributes must have same number of values for CompositeAttributeDefinition ("
- + getId() + ")"); }
- if (sourceAttrs.put(attr) != null) { throw new ResolutionPlugInException("Attribute ("
- + attr.getID() + ") occured more than once in the dependency chain for (" + getId()
- + ") and I don't know which one to pick"); }
- }
- }
- }
- }
- return valueCount;
- }
-
- /**
- * Get ordered attribute values for all source attributes from the dependent attributes. The values of all
- * multi-valued attribute MUST be ordered and MUST be of same size or else the results can be unpredictable.
- */
- private int addAttributesFromAttributeDependencies(Dependencies depends, Attributes sourceAttrs, int valueCount)
- throws ResolutionPlugInException {
-
- Iterator attrDependIt = attributeDependencyIds.iterator();
- while (attrDependIt.hasNext()) {
- ResolverAttribute attribute = depends.getAttributeResolution((String) attrDependIt.next());
- if (attribute != null) {
- if (sourceNamesSet.contains(attribute.getName())) {
- BasicAttribute attr = new BasicAttribute(attribute.getName(), true);
- int size = 0;
- for (Iterator iterator = attribute.getValues(); iterator.hasNext();) {
- attr.add(size++, iterator.next());
- }
- if (valueCount == -1) {
- valueCount = size; // initialize valueCount
- } else if (valueCount != size) { throw new ResolutionPlugInException("Multi-valued attribute ("
- + attr.getID() + ") has different number of values (" + size
- + ") than other attribute(s) that have (" + valueCount + ") values. "
- + "All attributes must have same number of values for CompositeAttributeDefinition ("
- + getId() + ")"); }
- if (sourceAttrs.put(attr) != null) { throw new ResolutionPlugInException("Attribute ("
- + attr.getID() + ") occured more than once in the dependency chain for (" + getId()
- + ") and I don't know which one to pick"); }
- } else {
- log
- .warn("Attribute Dependency ("
- + attribute.getName()
- + ") is not listed in the orderedSourceNames attribute for the CustomAttributeDefinition for ("
- + getId() + ")");
- }
- }
- }
- return valueCount;
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn#resolve(edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute,
- * java.security.Principal, java.lang.String, java.lang.String,
- * edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies)
- */
- public void resolve(ResolverAttribute attribute, Principal principal, String requester, String responder,
- Dependencies depends) throws ResolutionPlugInException {
-
- super.resolve(attribute, principal, requester, responder, depends);
-
- // Number of values that each source attribute has (must be same for all attributes)
- int valueCount = -1;
-
- // Collect attribute values from dependencies
- BasicAttributes attributes = new BasicAttributes();
- valueCount = addAttributesFromConnectors(depends, attributes, valueCount);
- valueCount = addAttributesFromAttributeDependencies(depends, attributes, valueCount);
-
- // If we got this far, all attributes are ordered and have 'valueCount' number of values
- for (int i = 0; i < valueCount; i++) {
- // put values in an array so we can use the formatter for creating the composite value
- Object[] values = new Object[sourceNames.length];
- try {
- for (int j = 0; j < sourceNames.length; j++) {
- Attribute attr = attributes.get(sourceNames[j]);
- if (attr == null)
- throw new ResolutionPlugInException("No value found for attribute (" + sourceNames[j]
- + ") during resolution of (" + getId() + ")");
- // get the ordered (i'th) value of the attribute
- values[j] = attr.get(i);
- }
- attribute.addValue(sourceFormat.format(values));
- } catch (ResolutionPlugInException e) {
- // Simply rethrow ...
- throw e;
- } catch (Exception e) {
- StringBuffer err = new StringBuffer();
- err.append("Error creating composite attribute [");
- if (values != null) {
- for (int ii = 0; ii < values.length; ii++) {
- if (values[ii] != null) err.append(values[ii].toString()).append(", ");
- else err.append("null ");
- }
- } else err.append(" null ");
- err.append("] using format ").append(sourceFormat.toPattern()).append(" for (").append(getId()).append(
- "): ").append(e.getMessage());
- log.error(err.toString());
- throw new ResolutionPlugInException(err.toString());
- }
- }
-
- attribute.setResolved();
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.security.Principal;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute;
-
-/**
- * Wrapper class for custom <code>AttributeDefinitionPlugIn</code> implementations.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class CustomAttributeDefinition implements ResolutionPlugIn, AttributeDefinitionPlugIn {
-
- private static Logger log = Logger.getLogger(CustomAttributeDefinition.class.getName());
- private AttributeDefinitionPlugIn custom;
- private String namespace = BaseAttributeDefinition.SHIB_ATTRIBUTE_NAMESPACE_URI;
-
- /** The time, in seconds, for which attribute created from this definition should be valid. */
- protected long lifeTime = -1;
-
- public CustomAttributeDefinition(Element e) throws ResolutionPlugInException {
-
- if (!e.getTagName().equals("CustomAttributeDefinition")) {
- log.error("Incorrect attribute definition configuration: expected <CustomAttributeDefinition> .");
- throw new ResolutionPlugInException("Failed to initialize Attribute Definition PlugIn.");
- }
-
- String className = e.getAttribute("class");
- if (className == null || className.equals("")) {
- log.error("Custom Attribute Definition requires specification of the attribute \"class\".");
- throw new ResolutionPlugInException("Failed to initialize Attribute Definition PlugIn.");
- } else {
- try {
- Class[] params = {Class.forName("org.w3c.dom.Element"),};
- Object[] passElement = {e};
- custom = (AttributeDefinitionPlugIn) Class.forName(className).getConstructor(params).newInstance(
- passElement);
- } catch (Exception loaderException) {
- log.error("Failed to load Custom Attribute Definition PlugIn implementation class: "
- + loaderException.getMessage());
- throw new ResolutionPlugInException("Failed to initialize Attribute Definition PlugIn.");
- }
- }
-
- String lifeTimeSpec = e.getAttribute("lifeTime");
- if (lifeTimeSpec != null && !lifeTimeSpec.equals("")) {
- try {
- lifeTime = Long.valueOf(lifeTimeSpec).longValue();
- log.debug("Explicit lifetime set for attribute (" + getId() + "). Lifetime: (" + lifeTime + ").");
- } catch (NumberFormatException nfe) {
- log.error("Bad value for attribute (lifeTime) for Attribute Definition (" + getId() + ").");
- }
- }
-
- String namespaceSpec = e.getAttribute("namespace");
- if (namespaceSpec != null && !namespaceSpec.equals("")) {
- namespace = namespaceSpec;
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn#resolve(edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute,
- * java.security.Principal, java.lang.String, java.lang.String,
- * edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies)
- */
- public void resolve(ResolverAttribute attribute, Principal principal, String requester, String responder,
- Dependencies depends) throws ResolutionPlugInException {
-
- custom.resolve(attribute, principal, requester, responder, depends);
- if (lifeTime != -1) {
- attribute.setLifetime(lifeTime);
- }
- attribute.setNamespace(namespace);
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.BaseResolutionPlugIn#getId()
- */
- public String getId() {
-
- return custom.getId();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.provider.BaseResolutionPlugIn#getTTL()
- */
- public long getTTL() {
-
- return custom.getTTL();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn#getAttributeDefinitionDependencyIds()
- */
- public String[] getAttributeDefinitionDependencyIds() {
-
- return custom.getAttributeDefinitionDependencyIds();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn#getDataConnectorDependencyIds()
- */
- public String[] getDataConnectorDependencyIds() {
-
- return custom.getDataConnectorDependencyIds();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn#getPropagateErrors()
- */
- public boolean getPropagateErrors() {
-
- return custom.getPropagateErrors();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.security.Principal;
-
-import javax.naming.directory.Attributes;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
-
-/**
- * Wrapper class for custom <code>DataConnectorPlugIn</code> implementations.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class CustomDataConnector implements DataConnectorPlugIn {
-
- private static Logger log = Logger.getLogger(CustomDataConnector.class.getName());
- private DataConnectorPlugIn custom;
-
- public CustomDataConnector(Element e) throws ResolutionPlugInException {
-
- if (!e.getTagName().equals("CustomDataConnector")) {
- log.error("Incorrect connector configuration: expected <CustomDataConnector> .");
- throw new ResolutionPlugInException("Failed to initialize Connector PlugIn.");
- }
-
- String className = e.getAttribute("class");
- if (className == null || className.equals("")) {
- log.error("Custom Data Connector requires specification of attributes \"class\".");
- throw new ResolutionPlugInException("Failed to initialize Connector PlugIn.");
- } else {
- try {
- Class[] params = {Class.forName("org.w3c.dom.Element"),};
- Object[] passElement = {e};
- custom = (DataConnectorPlugIn) Class.forName(className).getConstructor(params).newInstance(passElement);
- } catch (Exception loaderException) {
- // Try to be a little smart about logging errors
- // For some reason the message is not set on ClassNotFoundException
- log.error("Failed to load Custom Connector PlugIn implementation class: "
- + ((loaderException.getCause() != null)
- ? loaderException.getCause().getMessage()
- : loaderException.toString()));
- throw new ResolutionPlugInException("Failed to initialize Connector PlugIn.");
- }
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn#resolve(java.security.Principal,
- * java.lang.String, java.lang.String, edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies)
- */
- public Attributes resolve(Principal principal, String requester, String responder, Dependencies depends)
- throws ResolutionPlugInException {
-
- return custom.resolve(principal, requester, responder, depends);
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.BaseResolutionPlugIn#getId()
- */
- public String getId() {
-
- return custom.getId();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.provider.BaseResolutionPlugIn#getTTL()
- */
- public long getTTL() {
-
- return custom.getTTL();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn#getAttributeDefinitionDependencyIds()
- */
- public String[] getAttributeDefinitionDependencyIds() {
-
- return custom.getAttributeDefinitionDependencyIds();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn#getDataConnectorDependencyIds()
- */
- public String[] getDataConnectorDependencyIds() {
-
- return custom.getDataConnectorDependencyIds();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn#getFailoverDependencyId()
- */
- public String getFailoverDependencyId() {
-
- return custom.getFailoverDependencyId();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn#getPropagateErrors()
- */
- public boolean getPropagateErrors() {
-
- return custom.getPropagateErrors();
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Contributed by SunGard SCT.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.lang.reflect.Constructor;
-import java.security.Principal;
-import java.text.Format;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute;
-
-/**
- * The FormattedAttributeDefinition allows attribute values to be formatted using any custom formatter, such as the
- * java.text.MessageFormat, java.text.DateFormat or java.text.NumberFormat etc. It allows the source attribute to be
- * parsed using a specified formatter and the target to formatted using another formatter. Since the formatters for
- * source and target are both passed in as arguments along with the pattern string, a high degree of customization is
- * allowed. A value handler may also be specified, if needed. The value handler will see the 'target' value after the
- * target formatter has completed the value transformation. The 'format' attribute of the Source and Target elements
- * specify the class name of the formatter and MUST be a subclass of java.text.Format. The
- * <code>sourceFormat.parseObject(sourceValue)</code> method is used to convert the source attribute to an Object
- * (say, obj), which is then converted back to a String using the <code>targetFormat.format( obj )</code> method.
- *
- * @author <a href="mailto:vgoenka@sungardsct.com">Vishal Goenka </a>
- */
-
-public class FormattedAttributeDefinition extends BaseAttributeDefinition implements AttributeDefinitionPlugIn {
-
- private static Logger log = Logger.getLogger(FormattedAttributeDefinition.class.getName());
-
- // The format of Source Attribute
- private Format sourceFormat;
-
- // The format of Target Attribute
- private Format targetFormat;
-
- // if source and target formatters are same should we skip formatting? In a few cases, the formatter may still
- // produce
- // a different result so one may still want the formatting, even though the source and target formatters are
- // identical.
- private boolean skipFormatting = false;
-
- public FormattedAttributeDefinition(Element e) throws ResolutionPlugInException {
-
- super(e);
- NodeList sources = e.getElementsByTagName("Source");
- NodeList targets = e.getElementsByTagName("Target");
-
- if ((sources == null) || (sources.getLength() != 1) || (targets == null) || (targets.getLength() != 1)) {
- log
- .error("There MUST be exactly 1 'Source' and 1 'Target' definition for a FormattedAttributeDefinition for ("
- + getId() + ")");
- throw new ResolutionPlugInException(
- "There MUST be exactly 1 'Source' and 1 'Target' definition for a FormattedAttributeDefinition for ("
- + getId() + ")");
- }
- Element source = (Element) sources.item(0);
- Element target = (Element) targets.item(0);
-
- sourceFormat = createFormat(source);
- targetFormat = createFormat(target);
-
- if (sourceFormat.equals(targetFormat)) {
- String skipIfSameFormat = e.getAttribute("skipIfSameFormat");
- skipFormatting = Boolean.valueOf(skipIfSameFormat).booleanValue();
- if (!skipFormatting) {
- log.warn("Source and Target formats are identical for (" + getId()
- + "). Set 'skipIfSameFormat=true' on the CustomAttributeDefinition element to skip.");
- } else {
- log.debug("Source and Target formats are identical for (" + getId()
- + "). Formatting will be skipped since 'skipIfSameFormat=true'");
- }
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeDefinitionPlugIn#resolve(edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute,
- * java.security.Principal, java.lang.String, java.lang.String,
- * edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies)
- */
- public void resolve(ResolverAttribute attribute, Principal principal, String requester, String responder,
- Dependencies depends) throws ResolutionPlugInException {
-
- super.resolve(attribute, principal, requester, responder, depends);
-
- // Resolve all dependencies to arrive at the source values (unformatted)
- Collection results = getValuesFromAllDeps(attribute, principal, requester, depends);
-
- Iterator resultsIt = results.iterator();
-
- while (resultsIt.hasNext()) {
- String value = convertToString(resultsIt.next());
- if (skipFormatting) attribute.addValue(value);
- else {
- try {
- Object parsed = sourceFormat.parseObject(value);
- value = targetFormat.format(parsed);
- attribute.addValue(value);
- } catch (Exception e) {
- // We simply log an error for values that give errors during formatting rather than abandoning the
- // whole process
- log.error("Attribute value for (" + getId() + ") --> (" + value
- + ") failed during format conversion with exception: " + e.getMessage());
- }
- }
- }
- attribute.setResolved();
- }
-
- /**
- * Construct the specified formatter, which must be an instance of java.text.Format. It reads the attributes
- * 'format' and 'pattern' from the specified element, asserts that both are non-null and instantiates the class
- * specified by 'format' by passing in the 'pattern' to the single String argument constructor.
- *
- * @param element
- * the XML element describing the FormatType as defined in the FormattedAttributeDefinition.xsd
- * @return the initialized formatter, which must be a sub-class of java.text.Format
- */
- private Format createFormat(Element element) throws ResolutionPlugInException {
-
- String elementName = element.getTagName();
- String format = element.getAttribute("format");
- String pattern = element.getAttribute("pattern");
-
- log.debug(getId() + " <" + elementName + " format=\"" + format + "\" pattern=\"" + pattern + "\"/>");
-
- if ((format == null) || ("".equals(format)) || (pattern == null) || ("".equals(pattern))) {
- String error = elementName + " must have 'format' and 'pattern' attributes specified for (" + getId() + ")";
- log.error(error);
- throw new ResolutionPlugInException(error);
- }
- try {
- Class formatClass = Class.forName(format);
- if (!Format.class.isAssignableFrom(formatClass)) { throw new ResolutionPlugInException("Specified format ("
- + format + ") MUST be a subclass of java.text.Format"); }
- Constructor formatCons = formatClass.getConstructor(new Class[]{String.class});
- return (Format) formatCons.newInstance(new String[]{pattern});
- } catch (ClassNotFoundException e) {
- String error = "Specified format class (" + format + ") could not be found for (" + getId() + ")";
- log.error(error);
- throw new ResolutionPlugInException(error);
- } catch (Exception e) {
- String error = "Error creating " + elementName + " formatter for (" + getId() + "). Cause: "
- + e.getMessage();
- log.error(error, e);
- throw new ResolutionPlugInException(error);
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.sql.ResultSet;
-
-import javax.naming.directory.Attributes;
-
-/*
- * Built at the Canada Institute for Scientific and Technical Information (CISTI
- * <ahref="http://www.cisti-icist.nrc-cnrc.gc.ca/">http://www.cisti-icist.nrc-cnrc.gc.ca/ </a>, the National Research
- * Council Canada (NRC <a href="http://www.nrc-cnrc.gc.ca/">http://www.nrc-cnrc.gc.ca/ </a>) by David Dearman, COOP
- * student from Dalhousie University, under the direction of Glen Newton, Head research (IT)
- * <ahref="mailto:glen.newton@nrc-cnrc.gc.ca">glen.newton@nrc-cnrc.gc.ca </a>.
- */
-
-/**
- * Definition for the JDBC attribute extractor.
- *
- * @author David Dearman (dearman@cs.dal.ca)
- * @version 1.0 July 24, 2003
- *
- */
-
-public interface JDBCAttributeExtractor {
-
- /**
- * Method of extracting the attributes from the supplied result set.
- *
- * @param rs
- * The result set from the query which contains the attributes
- * @param minResultSet
- * The minimum number of rows that constitutes successful extraction
- * @param maxResultSet
- * The maximum number of rows that constitutes successful extraction
- * @return BasicAttributes as objects containing all the attributes
- * @throws JDBCAttributeExtractorException
- * If there is a complication in retrieving the attributes
- */
- public Attributes extractAttributes(ResultSet rs, int minResultSet, int maxResultSet)
- throws JDBCAttributeExtractorException;
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-/*
- * Built at the Canada Institute for Scientific and Technical Information (CISTI
- * <ahref="http://www.cisti-icist.nrc-cnrc.gc.ca/">http://www.cisti-icist.nrc-cnrc.gc.ca/ </a>, the National Research
- * Council Canada (NRC <a href="http://www.nrc-cnrc.gc.ca/">http://www.nrc-cnrc.gc.ca/ </a>) by David Dearman, COOP
- * student from Dalhousie University, under the direction of Glen Newton, Head research (IT)
- * <ahref="mailto:glen.newton@nrc-cnrc.gc.ca">glen.newton@nrc-cnrc.gc.ca </a>.
- */
-
-/**
- * Exception thrown by implementations of <code>JDBCAttributeExtractor</code> when problems are encountered extracting
- * attribributes for a <code>ResultSet</code>.
- *
- * @author David Dearman (dearman@cs.dal.ca)
- * @version 1.0 July 24, 2003
- *
- */
-
-public class JDBCAttributeExtractorException extends Exception {
-
- public JDBCAttributeExtractorException() {
-
- super();
- }
-
- public JDBCAttributeExtractorException(String s) {
-
- super(s);
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-
-import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
-import java.security.Principal;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Properties;
-
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.BasicAttributes;
-import javax.sql.DataSource;
-
-import org.apache.commons.dbcp.ConnectionFactory;
-import org.apache.commons.dbcp.DriverManagerConnectionFactory;
-import org.apache.commons.dbcp.PoolableConnectionFactory;
-import org.apache.commons.dbcp.PoolingDataSource;
-import org.apache.commons.pool.impl.GenericObjectPool;
-import org.apache.commons.pool.impl.StackKeyedObjectPoolFactory;
-import org.apache.log4j.Logger;
-import org.apache.log4j.Priority;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeResolver;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
-import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute;
-
-/*
- * Built at the Canada Institute for Scientific and Technical Information (CISTI
- * <ahref="http://www.cisti-icist.nrc-cnrc.gc.ca/">http://www.cisti-icist.nrc-cnrc.gc.ca/ </a>, the National Research
- * Council Canada (NRC <a href="http://www.nrc-cnrc.gc.ca/">http://www.nrc-cnrc.gc.ca/ </a>) by David Dearman, COOP
- * student from Dalhousie University, under the direction of Glen Newton, Head research (IT)
- * <ahref="mailto:glen.newton@nrc-cnrc.gc.ca">glen.newton@nrc-cnrc.gc.ca </a>.
- */
-
-/**
- * Data Connector that uses JDBC to access user attributes stored in databases.
- *
- * @author David Dearman (dearman@cs.dal.ca)
- * @author Walter Hoehn (wassa@columbia.edu)
- * @author Scott Cantor
- */
-
-public class JDBCDataConnector extends BaseDataConnector implements DataConnectorPlugIn {
-
- private static Logger log = Logger.getLogger(JDBCDataConnector.class.getName());
- protected String searchVal;
- protected int minResultSet = 0, maxResultSet = 0, retryInterval = 300;
- protected long deadSince = 0;
- protected DataSource dataSource;
- protected JDBCAttributeExtractor extractor;
- protected JDBCStatementCreator statementCreator;
-
- public JDBCDataConnector(Element e) throws ResolutionPlugInException {
-
- super(e);
-
- // Get the query string
- NodeList queryNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "Query");
- Node tnode = queryNodes.item(0).getFirstChild();
- if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
- searchVal = tnode.getNodeValue();
- }
- if (searchVal == null || searchVal.equals("")) {
- log.error("Database query must be specified.");
- throw new ResolutionPlugInException("Database query must be specified.");
- }
-
- // Load the supplied JDBC driver
- String dbDriverName = e.getAttribute("dbDriver");
- if (dbDriverName != null && (!dbDriverName.equals(""))) {
- loadDriver(dbDriverName);
- }
-
- String validationQuery = e.getAttribute("validationQuery");
- if (validationQuery == null || validationQuery.equals("")) {
- validationQuery = "select 1";
- }
-
- try {
- if (e.getAttributeNode("minResultSet") != null) {
- minResultSet = Integer.parseInt(e.getAttribute("minResultSet"));
- }
- if (e.getAttributeNode("maxResultSet") != null) {
- maxResultSet = Integer.parseInt(e.getAttribute("maxResultSet"));
- }
- if (e.getAttributeNode("retryInterval") != null) {
- retryInterval = Integer.parseInt(e.getAttribute("retryInterval"));
- }
- } catch (NumberFormatException ex) {
- log.error("Malformed result set and retry limits: using defaults.");
- }
-
- // Load site-specific implementation classes
- setupAttributeExtractor((Element) e.getElementsByTagNameNS(AttributeResolver.resolverNamespace,
- "AttributeExtractor").item(0));
- setupStatementCreator((Element) e.getElementsByTagNameNS(AttributeResolver.resolverNamespace,
- "StatementCreator").item(0));
-
- // Load driver properties
- Properties props = new Properties();
- NodeList propertiesNode = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "Property");
- for (int i = 0; propertiesNode.getLength() > i; i++) {
- Element property = (Element) propertiesNode.item(i);
- String propertiesName = property.getAttribute("name");
- String propertiesValue = property.getAttribute("value");
-
- if (propertiesName != null && !propertiesName.equals("") && propertiesValue != null
- && !propertiesValue.equals("")) {
- props.setProperty(propertiesName, propertiesValue);
- log.debug("Property: (" + propertiesName + ")");
- log.debug(" Value: (" + propertiesValue + ")");
- } else {
- log.error("Property is malformed.");
- throw new ResolutionPlugInException("Property is malformed.");
- }
- }
-
- // Initialize a pooling Data Source
- int maxActive = 5;
- int maxIdle = 5;
- int maxWait = 15;
- try {
- if (e.getAttributeNode("maxActive") != null) {
- maxActive = Integer.parseInt(e.getAttribute("maxActive"));
- }
- if (e.getAttributeNode("maxIdle") != null) {
- maxIdle = Integer.parseInt(e.getAttribute("maxIdle"));
- }
- if (e.getAttributeNode("maxWait") != null) {
- maxWait = Integer.parseInt(e.getAttribute("maxWait"));
- }
- } catch (NumberFormatException ex) {
- log.error("Malformed pooling limits: using defaults.");
- }
- if (e.getAttribute("dbURL") == null || e.getAttribute("dbURL").equals("")) {
- log.error("JDBC connection requires a dbURL property");
- throw new ResolutionPlugInException("JDBCDataConnection requires a \"dbURL\" property");
- }
- setupDataSource(e.getAttribute("dbURL"), props, maxActive, maxIdle, maxWait, validationQuery);
- }
-
- /**
- * Initialize a Pooling Data Source
- */
- private void setupDataSource(String dbURL, Properties props, int maxActive, int maxIdle, int maxWait,
- String validationQuery) throws ResolutionPlugInException {
-
- GenericObjectPool objectPool = new GenericObjectPool(null);
-
- objectPool.setMaxActive(maxActive);
- objectPool.setMaxIdle(maxIdle);
- if (maxWait > 0) objectPool.setMaxWait(1000 * maxWait);
- else objectPool.setMaxWait(maxWait);
-
- objectPool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
- objectPool.setTestOnBorrow(true);
-
- ConnectionFactory connFactory = null;
- PoolableConnectionFactory poolConnFactory = null;
-
- try {
- connFactory = new DriverManagerConnectionFactory(dbURL, props);
- log.debug("Connection factory initialized.");
- } catch (Exception ex) {
- log
- .error("Connection factory couldn't be initialized, ensure database URL, username and password are correct.");
- throw new ResolutionPlugInException("Connection factory couldn't be initialized: " + ex.getMessage());
- }
-
- try {
- poolConnFactory = new PoolableConnectionFactory(connFactory, objectPool, new StackKeyedObjectPoolFactory(),
- validationQuery, true, true);
- } catch (Exception ex) {
- log.debug("Poolable connection factory error");
- }
-
- dataSource = new PoolingDataSource(objectPool);
- log.info("Data Source initialized.");
- try {
- dataSource.setLogWriter(new Log4jPrintWriter(Logger.getLogger(JDBCDataConnector.class.getName() + ".Pool"),
- Priority.DEBUG));
- } catch (SQLException e) {
- log.error("Coudn't setup logger for database connection pool.");
- }
- }
-
- /**
- * Instantiate an Attribute Extractor, using the default if none was configured
- */
- private void setupAttributeExtractor(Element config) throws ResolutionPlugInException {
-
- String className = null;
- if (config != null) {
- className = config.getAttribute("class");
- }
- if (className == null || className.equals("")) {
- log.debug("Using default Attribute Extractor.");
- className = DefaultAE.class.getName();
- }
- try {
- Class aeClass = Class.forName(className);
- extractor = (JDBCAttributeExtractor) aeClass.newInstance();
- log.debug("Attribute Extractor implementation loaded.");
-
- } catch (ClassNotFoundException e) {
- log.error("The supplied Attribute Extractor class could not be found: " + e);
- throw new ResolutionPlugInException("The supplied Attribute Extractor class could not be found: "
- + e.getMessage());
- } catch (Exception e) {
- log.error("Unable to instantiate Attribute Extractor implementation: " + e);
- throw new ResolutionPlugInException("Unable to instantiate Attribute Extractor implementation: "
- + e.getMessage());
- }
- }
-
- /**
- * Instantiate a Statement Creator, using the default if none was configured
- */
- private void setupStatementCreator(Element config) throws ResolutionPlugInException {
-
- String scClassName = null;
- if (config != null) {
- scClassName = config.getAttribute("class");
- }
- if (scClassName == null || scClassName.equals("")) {
- log.debug("Using default Statement Creator.");
- scClassName = DefaultStatementCreator.class.getName();
- }
- try {
- Class scClass = Class.forName(scClassName);
-
- Class[] params = new Class[1];
- params[0] = Class.forName("org.w3c.dom.Element");
- try {
- Constructor implementorConstructor = scClass.getConstructor(params);
- Object[] args = new Object[1];
- args[0] = config;
- log.debug("Initializing Statement Creator of type (" + scClass.getName() + ").");
- statementCreator = (JDBCStatementCreator) implementorConstructor.newInstance(args);
- } catch (NoSuchMethodException nsme) {
- log
- .debug("Implementation constructor does have a parameterized constructor, attempting to load default.");
- statementCreator = (JDBCStatementCreator) scClass.newInstance();
- }
- log.debug("Statement Creator implementation loaded.");
-
- } catch (ClassNotFoundException e) {
- log.error("The supplied Statement Creator class could not be found: " + e);
- throw new ResolutionPlugInException("The supplied Statement Creator class could not be found: "
- + e.getMessage());
- } catch (Exception e) {
- log.error("Unable to instantiate Statement Creator implementation: " + e);
- throw new ResolutionPlugInException("Unable to instantiate Statement Creator implementation: "
- + e.getMessage());
- }
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn#resolve(java.security.Principal,
- * java.lang.String, java.lang.String, edu.internet2.middleware.shibboleth.aa.attrresolv.Dependencies)
- */
- public Attributes resolve(Principal principal, String requester, String responder, Dependencies depends)
- throws ResolutionPlugInException {
-
- log.debug("Resolving connector: (" + getId() + ")");
-
- // Are we alive?
- boolean alive = true;
- long now = System.currentTimeMillis();
- synchronized (this) {
- if (deadSince > 0 && now - deadSince < (1000 * retryInterval)) {
- alive = false;
- } else {
- deadSince = 0;
- }
- }
-
- if (!alive) {
- log.info("JDBC Connector (" + getId() + ") is dead, returning immediately");
- throw new ResolutionPlugInException("Connection is dead");
- }
-
- // Retrieve a connection from the connection pool
- Connection conn = null;
- try {
- conn = dataSource.getConnection();
- log.debug("Connection retrieved from pool");
- } catch (Exception e) {
- synchronized (this) {
- deadSince = now;
- }
- log.error("JDBC Connector (" + getId() + ") unable to fetch a connection from the pool, marking it dead");
- throw new ResolutionPlugInException("Unable to fetch a connection from the pool, marking it dead: "
- + e.getMessage());
- }
- if (conn == null) {
- log.error("Pool didn't return a properly initialized connection.");
- throw new ResolutionPlugInException("Pool didn't return a properly initialized connection.");
- }
-
- // Setup and execute a (pooled) prepared statement
- ResultSet rs = null;
- PreparedStatement preparedStatement = null;
- try {
- preparedStatement = conn.prepareStatement(searchVal);
- preparedStatement.clearParameters();
- statementCreator.create(preparedStatement, principal, requester, responder, depends);
- rs = preparedStatement.executeQuery();
- if (!rs.next()) {
- if (minResultSet == 0) return new BasicAttributes();
- else {
- log.error("Statement returned no rows, violating minResultSet of " + minResultSet);
- throw new ResolutionPlugInException("Statement didn't return any rows, violating minResultSet of "
- &nb