}
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);
}
for (int i = 0; userPolicies.length > i; i++) {
- Collection<Rule> rules = userPolicies[i].getMatchingRules(requester);
+ Collection<Rule> rules = userPolicies[i].getMatchingRules(requester, attributes);
for (Rule rule : rules) {
effectiveArp.addRule(rule);
}
/**
+ * 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
for (Iterator<? extends ArpAttribute> nameIterator = attributes.iterator(); nameIterator.hasNext();) {
attributeNames.add(nameIterator.next().getName());
}
- Collection<Rule> rules = createEffectiveArp(principal, requester).getAllRules();
+ 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();
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;
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>.
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()) {
}
}
+ // 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) {
* the SHAR making the request
*/
- public boolean matchesRequest(String requester) {
+ 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; }
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(Arp.arpNamespace, "attributeName", attributeName.toString());
+ constraintNode.setAttributeNS(Arp.arpNamespace, "matchFunction", matchFunctionIdentifier.toString());
+ constraintNode.setAttributeNS(Arp.arpNamespace, "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 {
+ log.error("Constraint matchFunction identifier not specified.");
+ throw new ArpMarshallingException("Constraint matchFunction identifier 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 matches value
+ if (element.hasAttribute("matches")) {
+ matches = element.getAttribute("matches");
+ } else {
+ log.error("Constraint matches value not specified.");
+ throw new ArpMarshallingException("Constraint matches value not specified.");
+ }
+
+ // 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;
+ }
+
+ 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;
+ }
+ }
}