Initial seed of merged of AT&T and JP Morgan code
diff --git a/openaz-pep/pom.xml b/openaz-pep/pom.xml new file mode 100755 index 0000000..bcf6443 --- /dev/null +++ b/openaz-pep/pom.xml
@@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>openaz</artifactId> + <groupId>org.openliberty.openaz</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>openaz-pep</artifactId> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>openaz-xacml</artifactId> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>openaz-xacml-pdp</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + </dependencies> + +</project> \ No newline at end of file
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java new file mode 100755 index 0000000..cd7975d --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java
@@ -0,0 +1,62 @@ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.XACML3; + +; + +/** + * Container class that maps attributes to predefined XACML Action category. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public class Action extends CategoryContainer { + + public static final String ACTION_ID_KEY = "ACTION_ID_KEY"; + + private String actionIdValue; + + private Action() { + super(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION); + } + + /** + * Creates a new Action instance + * + * @return + */ + public static Action newInstance() { + return new Action(); + } + + /** + * Create a new Action instance containing a single default attribute with the given value + * + * @param actionIdValue + * @return + */ + public static Action newInstance(String actionIdValue) { + Action a = new Action(); + a.actionIdValue = actionIdValue; + a.addAttribute(ACTION_ID_KEY, actionIdValue); + return a; + } + + /** + * Get the value for default attribute. + * + * @return + */ + public String getActionIdValue() { + return actionIdValue; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("action-id value: " + actionIdValue); + builder.append("\n"); + builder.append(super.toString()); + return builder.toString(); + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java new file mode 100755 index 0000000..4d9cc8c --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java
@@ -0,0 +1,92 @@ +package org.openliberty.openaz.pepapi; + + +/** + * A convenient abstraction for an action - resource pair. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public final class ActionResourcePair { + + private final Object action; + + private final Object resource; + + /** + * Creates a new action - resource pair + * + * @param action an Object representing the action being performed. + * @param resource an Object representing the resource on which the action is being performed. + */ + public ActionResourcePair(Object action, Object resource){ + this.resource = resource; + this.action = action; + } + + /** + * Returns the resource associated with this action - resource pair + * + * @return an Object representing the resource. + */ + public Object getResource() { + return resource; + } + + /** + * Returns the action associated with this action - resource pair. + * + * @return an Object representing the action. + */ + public Object getAction() { + return action; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((action == null) ? 0 : action.hashCode()); + result = prime * result + + ((resource == null) ? 0 : resource.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ActionResourcePair other = (ActionResourcePair) obj; + if (action == null) { + if (other.action != null) + return false; + } else if (!action.equals(other.action)) { + return false; + } + + if (resource == null) { + if (other.resource != null) { + return false; + } + } else if (!resource.equals(other.resource)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("\nAction: " + action.toString()); + builder.append("\nResource: " + resource.toString()); + return builder.toString(); + } + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java new file mode 100755 index 0000000..46682d0 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java
@@ -0,0 +1,21 @@ +package org.openliberty.openaz.pepapi; + +import java.util.Map; + +/** + * + */ +public interface Advice { + + /** + * + * @return + */ + public String getId(); + + /** + * + */ + public Map<String, Object[]> getAttributeMap(); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java new file mode 100755 index 0000000..c6c84bb --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java
@@ -0,0 +1,30 @@ +package org.openliberty.openaz.pepapi; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * Represents an Attribute match criterion, where an attribute with the given Id can take any of the values provided. + * If no value is available, then value matching is ignored. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +@Target({}) +@Retention(RetentionPolicy.CLASS) +public @interface Attribute { + + /** + * + * @return + */ + String id(); + + /** + * + * @return + */ + String[] anyValue() default {}; +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java new file mode 100755 index 0000000..010bc6f --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java
@@ -0,0 +1,140 @@ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.Identifier; + +import java.net.URI; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +/** + * Abstraction for an attribute container of a specific XACML category. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public class CategoryContainer { + + private final Map<String, Object[]> attributeMap; + + private final Identifier categoryIdentifier; + + CategoryContainer(Identifier categoryIdentifier) { + this.categoryIdentifier = categoryIdentifier; + this.attributeMap = new HashMap<String, Object[]>(); + } + + private final void addToMap(String id, Object[] values) { + if (values != null && values.length > 0) { + attributeMap.put(id, values); + }else { + throw new IllegalArgumentException("Values cannot be null"); + } + } + + public Identifier getCategoryIdentifier() { + return this.categoryIdentifier; + } + + /** + * Returns all the contained attributes as a Map of key - value pairs. + * + * @return + */ + public Map<String, Object[]> getAttributeMap() { + return Collections.unmodifiableMap(attributeMap); + } + + /** + * Add a new attribute with the given id and one or more String values + * + * @param id + * @param values + * @throws IllegalArgumentException, if values are null; + */ + public void addAttribute(String id, String... values) { + addToMap(id, values); + } + + /** + * Add a new attribute with the given id and one or more Long values + * + * @param id + * @param values + * @throws IllegalArgumentException, if values are null; + */ + public void addAttribute(String id, Long... values) { + addToMap(id, values); + } + + /** + * Add a new attribute with the given id and one or more Integer values + * + * @param id + * @param values + * @throws IllegalArgumentException, if values are null; + */ + public void addAttribute(String id, Integer... values) { + addToMap(id, values); + } + + /** + * Add a new attribute with the given id and one or more Double values + * + * @param id + * @param values + * @throws IllegalArgumentException, if values are null; + */ + public void addAttribute(String id, Double... values) { + addToMap(id, values); + } + + /** + * Add a new attribute with the given id and one or more Boolean values + * + * @param id + * @param values + * @throws IllegalArgumentException, if values are null; + */ + public void addAttribute(String id, Boolean... values) { + addToMap(id, values); + } + + /** + * Add a new attribute with the given id and one or more <code>java.util.Date</code> values + * + * @param id + * @param values + * @throws IllegalArgumentException, if values are null; + */ + public void addAttribute(String id, Date... values) { + addToMap(id, values); + } + + /** + * Add a new attribute with the given id and one or more URI values + * + * @param id + * @param values + * @throws IllegalArgumentException, if values are null; + */ + public void addAttribute(String id, URI... values) { + addToMap(id, values); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + for(Entry<String, Object[]> e: attributeMap.entrySet()) { + builder.append("Attribute Id: " + e.getKey()); + builder.append(", Attribute Values: "); + for(Object o: e.getValue()) { + builder.append(o.toString() + ", "); + } + builder.append("\n"); + } + return builder.toString(); + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java new file mode 100755 index 0000000..42f8c64 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java
@@ -0,0 +1,27 @@ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.XACML3; + +/** + * + * Container class that maps attributes to predefined XACML Environment category. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public final class Environment extends CategoryContainer { + + private Environment() { + super(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT); + } + + /** + * Creates a new Environment instance + * + * @return + */ + public static Environment newInstance() { + return new Environment(); + } + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java new file mode 100755 index 0000000..39a220b --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java
@@ -0,0 +1,29 @@ +package org.openliberty.openaz.pepapi; + +/** + * RuntimeException thrown when a registered handler class does not contain one of the + * required annotations - <code>@MatchAnyObligation</code>, <code>@MatchAllObligationAttributes</code>. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +@SuppressWarnings("serial") +public class InvalidAnnotationException extends RuntimeException { + + public InvalidAnnotationException() { + super(); + } + + public InvalidAnnotationException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidAnnotationException(String message) { + super(message); + } + + public InvalidAnnotationException(Throwable cause) { + super(cause); + } + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java new file mode 100755 index 0000000..41ea381 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java
@@ -0,0 +1,35 @@ +package org.openliberty.openaz.pepapi; + + +/** + * Container that holds <code>ObjectMapper</code> instances registered with the framework. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public interface MapperRegistry { + + /** + * Registers the provided ObjectMapper instance + * + * @param mapper + */ + public void registerMapper(ObjectMapper mapper); + + /** + * Registers the provided ObjectMapper instances + * + * @param mappers + */ + public void registerMappers(Iterable<? extends ObjectMapper> mappers); + + /** + * Returns the ObjectMapper instance registered for the given Class. + * + * @param clazz + * @return an ObjectMapper instance + * @throws org.openliberty.openaz.pepapi.PepException if no ObjectMapper could be found for class clazz; + */ + public ObjectMapper getMapper(Class<?> clazz); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java new file mode 100755 index 0000000..19f2859 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java
@@ -0,0 +1,25 @@ +package org.openliberty.openaz.pepapi; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Represents a union of Obligation Attribute match criterion. + * All attribute criterion supplied will be conjunctively matched by the framework. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MatchAllObligationAttributes { + + /** + * + * @return + */ + Attribute[] value(); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java new file mode 100755 index 0000000..502c3fd --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java
@@ -0,0 +1,25 @@ +package org.openliberty.openaz.pepapi; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Represents an Obligation criteria that matches any of the supplied Obligation ids. + * If no ids are provided, then any Obligation will be matched(catch-all). + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MatchAnyObligation { + + /** + * + * @return + */ + String[] value() default {}; + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java new file mode 100755 index 0000000..554523f --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java
@@ -0,0 +1,19 @@ +package org.openliberty.openaz.pepapi; + +/** + * Interface that abstracts an object that can be matched. Concrete implementations provide a match() function. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * @param <T> + */ +public interface Matchable<T> { + + /** + * Returns a boolean result after matching the given Object + * + * @param t + * @return a <code>boolean</code> value + */ + public boolean match(T t); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java new file mode 100755 index 0000000..0af85d9 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java
@@ -0,0 +1,47 @@ +package org.openliberty.openaz.pepapi; + + + +/** + * Converts a Java Class (typically an application Domain Object) into request attributes of some Category. + * Applications are expected to provide only a single ObjectMapper instance per Domain Type. + * + * Typically, there is a one-to-one relationship between the Domain Type and Attribute Category. The interface, however, takes + * a general approach allowing a Domain Type to be mapped to multiple categories. + * + * The conversion for the most part involves obtaining a <code>CategoryAttributes</code> instance for a specific category from the + * request context and then mapping Object properties as name-value pairs using one of the overloaded <code>setAttribute</code> + * methods. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public interface ObjectMapper { + + /** + * Returns a Class that represents the mapped domain type. + * + * @return a Class object + */ + public Class<?> getMappedClass(); + + /** + * Maps Object properties to attributes + * + * @param o - an instance of the domain object to be mapped + * @param pepRequest - the current Request Context + */ + public void map(Object o, PepRequest pepRequest); + + /** + * + * @param mapperRegistry + */ + public void setMapperRegistry(MapperRegistry mapperRegistry); + + /** + * + * @param pepConfig + */ + public void setPepConfig(PepConfig pepConfig); +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java new file mode 100755 index 0000000..76f3656 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java
@@ -0,0 +1,44 @@ +package org.openliberty.openaz.pepapi; + +import java.util.Map; + +/** + * The Obligation interface provides access to an Obligation + * object implementation that contains a set of zero or more + * Attributes. + * <p> + * The Obligation has an id: {@link #getId()} + * <p> + * Each attribute has an id, as well, which are used as the key Strings + * of the Maps returned by method: + * <ul> + * <li>{@link #getAttributeMap()}</li> + * </ul> + * Each key String has an associated value, which can be an + * an array of Objects. + * <p> + * + * @author Josh Bregman, Rich Levinson, Prateek Mishra + * + */ +public interface Obligation { + + /** + * Return the Id for this Obligation. + * + * @return a string containing the Id of this Obligation + */ + public String getId(); + + /** + * Returns a Map of Obligation Attribute name,object-value-array pairs, + * indexed by name, where name is the AttributeId and the value + * is an array of one or more Object values of the "attribute" + * (where an array with length > 1 indicates a multi-valued attribute). + * <p> + * @return a Map of String (AttributeId name), Object array + * (Attribute values) pairs + */ + public Map<String, Object[]> getAttributeMap(); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java new file mode 100755 index 0000000..13cd008 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java
@@ -0,0 +1,11 @@ +package org.openliberty.openaz.pepapi; + + +/** + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public interface ObligationHandler extends Matchable<Obligation>, ObligationStoreAware { + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java new file mode 100755 index 0000000..a76733f --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java
@@ -0,0 +1,20 @@ +package org.openliberty.openaz.pepapi; + + +import java.util.Map; + +/** + * Abstraction for a Obligation Handler registration mechanism. Subclasses provide specific implementations. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + */ +public interface ObligationHandlerRegistry { + + /** + * Returns a Map of <code>Matchable</code> implementations keyed by handler Class. + * + * @return + */ + public Map<Class<?>, Matchable<Obligation>> getRegisteredHandlerMap(); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java new file mode 100755 index 0000000..1d3b368 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java
@@ -0,0 +1,18 @@ +package org.openliberty.openaz.pepapi; + +import java.util.Map; + +/** + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public interface ObligationRouter { + + /** + * + * @param obligationMap + */ + public void routeObligations(Map<String, Obligation> obligationMap); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java new file mode 100755 index 0000000..9b65f95 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java
@@ -0,0 +1,27 @@ +package org.openliberty.openaz.pepapi; + +import java.util.Set; + +/** + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public interface ObligationStore { + + /** + * + * @param oHandlerClass + * @return + */ + public Set<Obligation> getHandlerObligations(Class<?> oHandlerClass); + + /** + * + * @param oHandlerClass + * @param obligationId + * @return + */ + public Obligation getHandlerObligationById(Class<?> oHandlerClass, String obligationId); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java new file mode 100755 index 0000000..99a65a2 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java
@@ -0,0 +1,17 @@ +package org.openliberty.openaz.pepapi; + + +/** + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public interface ObligationStoreAware { + + /** + * + * @param oStore + */ + public void setObligationStore(ObligationStore oStore); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java new file mode 100755 index 0000000..20b95fb --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java
@@ -0,0 +1,89 @@ +package org.openliberty.openaz.pepapi; + +import java.util.List; + +/** + * + * Serves as the main entry point into the PepAPI framework. It coordinates authorization request creation, execution and + * response assemblage. Applications typically work with a single instance of PepAgent which is thread-safe. + * + * The <code>decide()</code> method, which provides the most general mechanism for authorization, accepts a collection of application Domain Objects, + * each with it's own <code>ObjectMapper</code> defined. The client application thus passes these Domain Objects directly, <code>decide()</code> uses + * reflection to determine their type, and then finds a type-specific mapper. + * + * This mechanism relies on application defined library of Object Mappers, one for each Domain Object that the client + * program expects to use in an authorization call. + * + * It is important to note that Java Primitives/Wrappers and other standard types(except Collections) are not supported out of the box. + * This is primarily because there is no sensible default mapping between a Java Standard Type and a XACML category and hence + * it's impossible for the framework to make a mapping decision at runtime. However, client applications may enforce their own rules as + * they see fit by providing Custom ObjectMapper(s) for these types. + * + * <code>simpleDecide()</code> method addresses the simplest of use cases where attributes involved are simple userId, actionId and resourceId Strings. + * + * <code>bulkDecide()</code> provides an abstraction for a MultiRequest, where in client applications may provide collection of Domain Object + * bindings/associations each of which map to individual requests. The method separates out Domain Object associations with multiple cardinality + * from the ones shared across requests. + * + * Thus, in a <code>bulkDecide()</code> call applications provide two sets of arguments: + * - a List of Domain Object bindings, each of which map to an individual request. + * - a collection of common Domain Objects shared across all requests. + * + * Specific AzService implementations(PDP Providers) may implement bulkDecide() as a XACML MultiRequest (Note: XACML Multi Decision Profile is optional) + * or as individual requests executed iteratively. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public interface PepAgent { + + + /** + * Returns a authorization decision for the given subjectId, actionId, + * resourceId Strings. + * + * @param subjectId + * @param actionId + * @param resourceId + * @return + * @throws PepException + * - if an appropriate ObjectMapper cannot be found. + * - if the underlying AzService instance/PDP throws an exception + * - if the PepAgent is configured to throw PepExceptions for "Indeterminate" or "Not Applicable" decisions. + * @throws IllegalArgumentException if any of the arguments are null + */ + public PepResponse simpleDecide(String subjectId, String actionId, String resourceId); + + /** + * Returns an authorization decision for the given collection of Domain Objects each with it's own + * ObjectMapper instance. Java Primitives/Wrappers or other Standard types (except Collections) are not supported + * out of the box. However, client applications may enforce their own rules as they see fit by providing Custom ObjectMapper(s) + * for these types. + * + * @param objects + * @return + * @throws PepException + * - if an appropriate ObjectMapper cannot be found. + * - if the underlying AzService instance/PDP throws an exception + * - if the PepAgent is configured to throw PepException for "Indeterminate" or "Not Applicable" decisions. + * @throws IllegalArgumentException if any of the arguments are null + */ + public PepResponse decide(Object... objects); + + /** + * Returns a PepResponse instance representing a collection of decisions, each of which corresponds to + * an association. Each association represents a specific instance of Domain Object binding. A typical example for an association + * would be an Action-Resource pair. + * + * @param associations a list of Domain Object bindings, each of which maps to a individual Request. + * @param objects a collection of common Domain Objects shared across all Requests. + * @return + * @throws PepException + * - if an appropriate ObjectMapper cannot be found. + * - if the underlying AzService instance/PDP throws an exception + * - if the PepAgent is configured to throw PepExceptions for "Indeterminate" or "Not Applicable" decisions. + * @throws IllegalArgumentException if any of the arguments are null + */ + public List<PepResponse> bulkDecide(List<?> associations, Object... objects); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java new file mode 100755 index 0000000..3cb7601 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java
@@ -0,0 +1,16 @@ +package org.openliberty.openaz.pepapi; + +/** + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public interface PepAgentFactory { + + /** + * Returns a PepAgent instance + * + * @return + */ + public PepAgent getPepAgent(); +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java new file mode 100755 index 0000000..897c2f1 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java
@@ -0,0 +1,51 @@ +package org.openliberty.openaz.pepapi; + +import java.util.List; + +/** + * @authors Ajith Nair, David Laurance, Darshak Kothari + */ +public interface PepConfig { + + /** + * + * @return + */ + public String getIssuer(); + + /** + * + * @return + */ + public String getDefaultSubjectId(); + + /** + * + * @return + */ + public String getDefaultResourceId(); + + /** + * + * @return + */ + public String getDefaultActionId(); + + /** + * + * @return + */ + public PepResponseBehavior getIndeterminateBehavior(); + + /** + * + * @return + */ + public PepResponseBehavior getNotApplicableBehavior(); + + /** + * + * @return + */ + public List<String> getMapperClassNames(); +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java new file mode 100755 index 0000000..6f141d6 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java
@@ -0,0 +1,66 @@ +/** + * Copyright 2009-2011 Oracle, 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. + * + * Authors: + * 1.1 (2011): Rich Levinson, Prateek Mishra (Oracle) + * 1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle) + * Contributor: + * Rich Levinson (Oracle) + */ +package org.openliberty.openaz.pepapi; + +/** + * The PepException is used to provide additional + * information to callers of the PepApi when + * exception conditions occur. + * <p> + * PepApi 1.1: now extends RuntimeException in order + * that users do not require try/catch blocks + * when using PepApi 1.1. + * <p> + * @author Josh Bregman, Rich Levinson, Prateek Mishra + */ +public class PepException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * Create a PepException containing a Throwable that + * specifies the cause of this PepException. + * @param cause + */ + public PepException(Throwable cause) { + super(cause); + } + + /** + * Create a PepException containing the message provided + * and a Throwable containing further information as to + * the cause of the PepException. + * @param message + * @param cause + */ + public PepException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Create a PepException containing the message provided. + * @param message + */ + public PepException(String message) { + super(message); + } + + public PepException() {super();} +} +
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java new file mode 100755 index 0000000..fe7391c --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java
@@ -0,0 +1,46 @@ +/** + * Copyright 2009-2011 Oracle, 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. + * + * Authors: + * (2014): Ajith Nair, David Laurance + * 1.1 (2011): Rich Levinson, Prateek Mishra (Oracle) + * 1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle) + * Contributor: + * Rich Levinson (Oracle) + */ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Request; + +/** + * + * @author Josh Bregman, Rich Levinson, Prateek Mishra + * + */ +public interface PepRequest { + + /** + * Returns a PepRequestAttributes instance that represents the attribute category identified + * by the categoryIdentfier parameter. + * + * @param categoryIdentifier an identifier for a category + */ + public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier); + + /** + * + * @return + */ + public Request getWrappedRequest(); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java new file mode 100755 index 0000000..b011e9b --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java
@@ -0,0 +1,128 @@ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.RequestAttributes; + +import java.net.URI; +import java.util.Date; + +/** + * Convenient wrapper around a RequestAttributes{@link com.att.research.xacml.api.RequestAttributes} instance, + * representing a collection of request attributes that belong to a particular category. + * + */ +public interface PepRequestAttributes { + + /** + * Returns an Indentifier representing the attribute category that the PepRequestAttributes encapsulates + * + * @return Identifier + */ + public Identifier getCategory(); + + /** + * Returns an id representing the xml:id + * + * @return Identifier + */ + public String getId(); + + /** + * Creates and adds an attribute with the name as the AttributeId, + * Date array elements as AttributeValue(s) into the underlying attribute collection. + * The attribute will NOT be returned by the PDP in the response after request evaluation. + * + * @param name + * a string with a name to be used as AttributeId + * @param values + * a Date array to be used as AttributeValue(s) + * @throws IllegalArgumentException if the array is null + */ + public void addAttribute(String name, Date... values); + + /** + * Creates and adds an attribute with the name as the AttributeId, + * String array elements as AttributeValue(s) into the underlying attribute collection. + * The attribute will NOT be returned by the PDP in the response after request evaluation. + * + * @param name + * a string with a name to be used as AttributeId + * @param values + * a String array to be used as AttributeValue(s) + * @throws IllegalArgumentException if the array is null + */ + public void addAttribute(String name, String... values); + + /** + * Creates and adds an attribute with the name as the AttributeId, + * Integer array elements as AttributeValue(s) into the underlying attribute collection. + * The attribute will NOT be returned by the PDP in the response after request evaluation. + * + * @param name + * a string with a name to be used as AttributeId + * @param values + * an Integer array to be used as AttributeValue(s) + * @throws IllegalArgumentException if the array is null + */ + public void addAttribute(String name, Integer... values); + + /** + * Creates and adds an attribute with the name as the AttributeId, + * Boolean array elements as AttributeValue(s) into the underlying attribute collection. + * The attribute will NOT be returned by the PDP in the response after request evaluation. + * + * @param name + * a string with a name to be used as AttributeId + * @param values + * a Boolean array to be used as AttributeValue(s) + * @throws IllegalArgumentException if the array is null + */ + public void addAttribute(String name, Boolean... values); + + + /** + * Creates and adds an attribute with the name as the AttributeId, + * Long array elements as AttributeValue(s) into the underlying attribute collection. + * The attribute will NOT be returned by the PDP in the response after request evaluation. + * + * @param name + * a string with a name to be used as AttributeId + * @param values + * a Long array to be used as AttributeValue(s) + * @throws IllegalArgumentException if the array is null + */ + public void addAttribute(String name, Long... values); + + /** + * Creates and adds an attribute with the name as the AttributeId, + * Double array elements as AttributeValue(s) into the underlying attribute collection. + * The attribute will NOT be returned by the PDP in the response after request evaluation. + * + * @param name + * a string with a name to be used as AttributeId + * @param values + * a Double array to be used as AttributeValue(s) + * @throws IllegalArgumentException if the array is null + */ + public void addAttribute(String name, Double... values); + + /** + * Creates and adds an attribute with the name as the AttributeId, + * URI array elements as AttributeValue(s) into the underlying attribute collection. + * The attribute will NOT be returned by the PDP in the response after request evaluation. + * + * @param name + * a string AttributeId of the attribute being set + * @param values + * a URI array to be used as AttributeValue(s + * @throws IllegalArgumentException if the array is null + */ + public void addAttribute(String name, URI... values); + + /** + * + * @return + */ + public RequestAttributes getWrappedRequestAttributes(); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java new file mode 100755 index 0000000..5b9a2ee --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java
@@ -0,0 +1,48 @@ +/** + * Copyright 2009-2011 Oracle, 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. + * + * Authors: + * 1.1 (2011): Rich Levinson, Prateek Mishra (Oracle) + * 1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle) + * Contributor: + * Rich Levinson (Oracle) + */ +package org.openliberty.openaz.pepapi; + +import java.util.List; + +/** + * + * @author Josh Bregman, Rich Levinson, Prateek Mishra + * + */ +public interface PepRequestFactory { + + /** + * + * @return + * @throws org.openliberty.openaz.pepapi.PepException, if no ObjectMappers found. + * @throws IllegalArgumentException,, if any argument is null. + */ + public PepRequest newPepRequest(Object[] objects); + + /** + * + * @param associations + * @param objects + * @return + * @throws org.openliberty.openaz.pepapi.PepException, if ObjectMappers are not found. + * @throws IllegalArgumentException,, if the arguments are null. + */ + public PepRequest newBulkPepRequest(List<?> associations, Object[] objects); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java new file mode 100755 index 0000000..b27ea6b --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java
@@ -0,0 +1,72 @@ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Result; + +import java.util.Collection; +import java.util.Map; + +/** + * @author Josh Bregman, Rich Levinson, Prateek Mishra + */ +public interface PepResponse { + + /** + * Returns the decision associated with the current result. + * @return true if the user was granted access to the resource, + * otherwise false + * @throws PepException if the {@link PepResponseBehavior} + * configured in the {@link PepResponseFactory} + * indicates that for the response should be thrown + */ + public boolean allowed() throws PepException; + + /** + * Return the set of {@link org.openliberty.openaz.pepapi.Obligation}s associated with the + * current result indexed by ObligationId. + * @return a Map of ObligationId, Obligation pairs + * @throws PepException + * @see org.openliberty.openaz.pepapi.Obligation#getId() + */ + public Map<String, Obligation> getObligations() throws PepException; + + /** + * Return the set of {@link org.openliberty.openaz.pepapi.Advice}s associated with the + * current result indexed by adviceId. + * @return a Map of adviceId, Advice pairs + * @throws PepException + * @see org.openliberty.openaz.pepapi.Advice#getId() + */ + public Map<String, Advice> getAdvices() throws PepException; + + /** + * Return the object association that is tied to the current + * result. The association is the same object that was + * used to create the PepRequest and may be used to + * correlate the PepResponse results with the association + * pairs that were used to create the PepRequest. + * @return an object that was used as the action-resource in the PepRequest + * @throws PepException + */ + public Object getAssociation() throws PepException; + + /** + * + * @return + */ + public Collection<Attribute> getAttributes(); + + /** + * + * @return + */ + public Map<Identifier, Collection<Attribute>> getAttributesByCategory(); + + /** + * + * @return + */ + public Result getWrappedResult(); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java new file mode 100755 index 0000000..ad1c70d --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java
@@ -0,0 +1,22 @@ +package org.openliberty.openaz.pepapi; + +/** + * This enum provides the options that can be set using the + * {@link org.openliberty.openaz.pepapi.PepResponseFactory} to determine the behavior when + * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} is called AND the + * decision is either Indeterminate or NotApplicable. + * + * @author Josh Bregman, Rich Levinson, Prateek Mishra + * + */ +public enum PepResponseBehavior { + + /** The behavior is to allow (Permit) access by returning true when the condition for which this behavior is assigned occurs */ + RETURN_YES, + + /** The behavior is to disallow (Deny) access by returning false when the condition for which this behavior is assigned occurs */ + RETURN_NO, + + /** The behavior is to disallow (Deny) access by throwing a PepException when the condition for which this behavior is assigned occurs */ + THROW_EXCEPTION +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java new file mode 100755 index 0000000..82b92c7 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java
@@ -0,0 +1,51 @@ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.Result; + +/** + * Factory for creating and configuring <code>PepResponse</code>. + * <br> + * This class creates {@link org.openliberty.openaz.pepapi.PepResponse} objects and configures + * the behavior of how the <code>PepResponse</code> interprets the + * results from the AzService or any other PDP that is supported + * by an implementation of PepApi (org.openliberty.openaz.azapi.pep.*). + * <br> + * The {@link PepResponseBehavior} that is invoked when + * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} is called and the associated status code + * has been returned by the PDP and is being handled by the PepResponse + * provider impl, can be configured to be one of: + * <ul> + * <li> + * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} returns true (PERMIT: {@link PepResponseBehavior#RETURN_YES}), + * <li> + * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} returns false (DENY: {@link PepResponseBehavior#RETURN_NO}), + * <li> + * or{@link org.openliberty.openaz.pepapi.PepResponse#allowed()} throws an exception (DENY: {@link PepResponseBehavior#THROW_EXCEPTION}). + * </ul> + * <p> + * In general, a Permit returns true, and a Deny returns false, + * but there are also other types of returns, including + * NotApplicable and Indeterminate. The configuration is to + * specify for each of the 4 xacml-defined conditions, what + * the behavior will be. i.e. for each of the "special" + * conditions there is a choice to return either true (Permit), + * false (Deny), or throw an Exception. + * <p> + * In addition, PDP-specific status codes can be specified, such + * that when the impl detects one of the configured status codes + * has been returned, then the {@link PepResponseBehavior} configured + * for that status code will be returned. + * <p> + * Finally, a default {@link PepResponseBehavior} may be configured + * for any status code that has not been explicitly configured + * or does not have its own default provided by the impl. The + * default if the statusCode default has not been configured is + * {@link PepResponseBehavior#THROW_EXCEPTION}. + * <p> + * @author Josh Bregman, Rich Levinson, Prateek Mishra + */ +public interface PepResponseFactory { + + public PepResponse newPepResponse(Result result); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java new file mode 100755 index 0000000..09b6203 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java
@@ -0,0 +1,25 @@ +package org.openliberty.openaz.pepapi; + +/** + * + * @author Josh Bregman, Rich Levinson, Prateek Mishra + */ +public enum PepResponseType { + /** The PepResponse returned for this query type will contain + * only the list of resource action associations that are + * allowed. + */ + ONLY_ALLOWED_RESULTS, + /** + * The PepResponse returned for this query type will contain + * only the list of resource action associations that are + * denied. + */ + ONLY_DENIED_RESULTS, + /** The PepResponse returned for this query type will contain + * the complete list of results for each resource action association + * that was requested, including allowed, denied, notapplicable, + * and indeterminate. + */ + ALL_RESULTS; +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java new file mode 100755 index 0000000..851f3a1 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java
@@ -0,0 +1,24 @@ +package org.openliberty.openaz.pepapi; + +/** + * An interface that may be implemented to process the + * PepResponse that is returned from the main decide() + * call before the final results are returned to the user. + * + * @author Josh Bregman, Rich Levinson, Prateek Mishra + * + */ +public interface PostDecisionHandler { + + /** + * This method is used to apply post-decision custom + * processing to the {@link org.openliberty.openaz.pepapi.PepResponse} after it has + * been returned. + * + * @param request + * @throws org.openliberty.openaz.pepapi.PepException + */ + public void postDecide(PepRequest request, PepResponse response) + throws PepException; + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java new file mode 100755 index 0000000..472c9e8 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java
@@ -0,0 +1,23 @@ +package org.openliberty.openaz.pepapi; + +/** + * An interface that can be used for preliminary processing + * of a PepRequest before it is actually submitted to the + * main decide() method. + * + * @author Josh Bregman, Rich Levinson, Prateek Mishra + * + */ +public interface PreDecisionHandler { + + /** + * This method is used to apply preliminary custom + * processing to the {@link org.openliberty.openaz.pepapi.PepRequest} prior to its + * being submitted. + * + * @param request + * @throws org.openliberty.openaz.pepapi.PepException + */ + public void preDecide(PepRequest request) + throws PepException; +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java new file mode 100755 index 0000000..aa878d1 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java
@@ -0,0 +1,129 @@ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.XACML3; + +import java.net.URI; +import java.util.Date; + +/** + * Container class that maps attributes to predefined XACML Resource category. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public final class Resource extends CategoryContainer { + + public static final String RESOURCE_ID_KEY = "RESOURCE_ID_KEY"; + + private Object resourceIdValue; + + private Resource(){ + super(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + } + + /** + * Creates a new Resource instance + * + * @return + */ + public static Resource newInstance() { + return new Resource(); + } + + /** + * Creates a new Resource instance containing a single default attribute with the given String value. + * + * @param resourceIdValue + * @return + */ + public static Resource newInstance(String resourceIdValue) { + Resource r = new Resource(); + r.resourceIdValue = resourceIdValue; + r.addAttribute(RESOURCE_ID_KEY, resourceIdValue); + return r; + } + + /** + * Creates a new Resource instance containing a single default attribute with the given URI value. + * + * @param resourceIdValue + * @return + */ + public static Resource newInstance(URI resourceIdValue) { + Resource r = new Resource(); + r.resourceIdValue = resourceIdValue; + r.addAttribute(RESOURCE_ID_KEY, resourceIdValue); + return r; + } + + /** + * Creates a new Resource instance containing a single default attribute with the given Long value. + * + * @param resourceIdValue + * @return + */ + public static Resource newInstance(Long resourceIdValue) { + Resource r = new Resource(); + r.resourceIdValue = resourceIdValue; + r.addAttribute(RESOURCE_ID_KEY, resourceIdValue); + return r; + } + + /** + * Creates a new Resource instance containing a single default attribute with the given Double value. + * + * @param resourceIdValue + * @return + */ + public static Resource newInstance(Double resourceIdValue) { + Resource r = new Resource(); + r.resourceIdValue = resourceIdValue; + r.addAttribute(RESOURCE_ID_KEY, resourceIdValue); + return r; + } + + /** + * Creates a new Resource instance containing a single default attribute with the given Boolean value. + * + * @param resourceIdValue + * @return + */ + public static Resource newInstance(Boolean resourceIdValue) { + Resource r = new Resource(); + r.resourceIdValue = resourceIdValue; + r.addAttribute(RESOURCE_ID_KEY, resourceIdValue); + return r; + } + + /** + * Creates a new Resource instance containing a single default attribute with the given <code>java.util.Date</code> value. + * + * @param resourceIdValue + * @return + */ + public static Resource newInstance(Date resourceIdValue) { + Resource r = new Resource(); + r.resourceIdValue = resourceIdValue; + r.addAttribute(RESOURCE_ID_KEY, resourceIdValue); + return r; + } + + /** + * Returns the value of the default resourceIdValue attribute + * + * @return + */ + public Object getResourceIdValue() { + return resourceIdValue; + } + + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("resource-id value : " + resourceIdValue); + builder.append("\n"); + builder.append(super.toString()); + return builder.toString(); + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java new file mode 100755 index 0000000..011be09 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java
@@ -0,0 +1,60 @@ +package org.openliberty.openaz.pepapi; + +import com.att.research.xacml.api.XACML3; + +/** + * Container class that maps attributes to predefined XACML AccessSubject category. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public class Subject extends CategoryContainer { + + public static final String SUBJECT_ID_KEY = "SUBJECT_ID_KEY"; + + private String subjectIdValue; + + private Subject() { + super(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT); + } + + /** + * Creates a new Subject instance + * + * @return + */ + public static Subject newInstance() { + return new Subject(); + } + + /** + * Creates a new Subject instance containing a single default attribute with the given String value. + * + * @param subjectIdValue + * @return + */ + public static Subject newInstance(String subjectIdValue) { + Subject s = new Subject(); + s.subjectIdValue = subjectIdValue; + s.addAttribute(SUBJECT_ID_KEY, subjectIdValue); + return s; + } + + /** + * Returns the value of the default subjectIdValue attribute + * + * @return + */ + public String getSubjectIdValue() { + return subjectIdValue; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("subject-id value : " + subjectIdValue); + builder.append("\n"); + builder.append(super.toString()); + return builder.toString(); + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java new file mode 100755 index 0000000..7c52cb6 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java
@@ -0,0 +1,27 @@ +package org.openliberty.openaz.pepapi; + +/** + * Runtime Exception thrown when the framework cannot find a registered handler to deal with the obligation. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +@SuppressWarnings("serial") +public class UnhandleableObligationException extends RuntimeException { + + public UnhandleableObligationException() { + super(); + } + + public UnhandleableObligationException(String message, Throwable cause) { + super(message, cause); + } + + public UnhandleableObligationException(String message) { + super(message); + } + + public UnhandleableObligationException(Throwable cause) { + super(cause); + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html new file mode 100755 index 0000000..40d15ff --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html
@@ -0,0 +1,75 @@ +<html> +<body> +The goal of this +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/package-summary.html" +>"PepApi interface package"</a> +is to provide a set of interfaces that provide a framework +that will simplify the creation of Policy Enforcement Points (PEPs) +that use an underlying authorization provider that is accessed through the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/package-summary.html" +>"AzApi"</a> package. +<p> +To accomplish this goal, the PepApi interface package provides a common +interface that applications and containers can use to make authorization +calls to possibly any kind of authorization provider that uses a +request/response interface. +<p> +To keep the common interface both flexible and easy to use, this +PepApi package makes some simplifying assumptions: + +<P> +<ul> + <li>An authorization request context can be one of three varieties: + <ul> + <li>A single request for authorization of a single action on + a single resource + <li>A bulk request that consists of multiple single requests. + <li>A query request that returns (in minimal or verbose form) + the set of decisions on all resources and actions within a "scope" + </ul> + <li>An authorization request consists of a single subject, + a single action, and a single resource, with an optional environment + <li>Most applications can represent the subject,action,resource as Strings. + <li>Most applications need the Date, Boolean, Double, Integer, String, Time and DateTime types of XACML + <li>All attributes have a single issuer + <li>Some applications need to represent the subject,action,resource as an object with attributes (i.e a Map) + <li>Some frameworks and containers needs to represent the subject,action,resources as native objects, and want to + use the same API as their applications. + <li>An authorization response is primarily a yes/no decision + <li>Applications use obligations, and want to consume the attributes of the obligation as Strings. + +</ul> +</P> +The pep package is a simple layer on top of the azapi package. +All of the state is held inside of the classes in the azapi package. +This was done for both simplicity and to accommodate the creation of PEPs +that can benefit from the simpler API but may need a little more than the +above assumptions allow. +This additional capability is accomplished by being able to retrieve the +AzApiRequestContext from the PepRequest and being able to retrieve the +AzApiResponseContext from the PepResponse. +Since all of the state is in the azapi package, PEPs can just grab a +handle and continue building the request or processing the response. +<p> +Note: the "scope" of the PepApi has been conceptually expanded to +include non-AzApi authorization providers as well as AzApi-based +providers. This change has not impacted the PepApi, but it has impacted +how to most effectively conceptualize the implementations of PepApi. +<p> +The primary concept is to consider the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html" +>reference impl</a> +to be an application of a general framework, where this particular +instance the framework is being applied to an AzApi-packaged authorization +provider. In fact, the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html" +>"reference AzApi SunXacml PDP impl"</a>, +may be considered to be just such an "AzApi-packaged" provider. +<p> +There is a tutorial provided with the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html#package_description" +>PepApiImpl</a> +package javadoc page that provides general guidelines for implementing a +non-AzApi provider to be used by PepApi. +</body> +</html> \ No newline at end of file
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java new file mode 100755 index 0000000..be24376 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java
@@ -0,0 +1,22 @@ +package org.openliberty.openaz.pepapi.std; + + +import org.openliberty.openaz.pepapi.Action; + +/** + * Created by ajith on 12/11/14. + */ +public class ActionMapper extends CategoryContainerMapper { + + public ActionMapper() { + super(Action.class); + } + + @Override + protected String resolveAttributeId(String attributeId) { + if(attributeId.equals(Action.ACTION_ID_KEY)) { + return getPepConfig().getDefaultActionId(); + } + return attributeId; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java new file mode 100755 index 0000000..ff97b85 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java
@@ -0,0 +1,35 @@ +package org.openliberty.openaz.pepapi.std; + + +import org.openliberty.openaz.pepapi.*; + +public final class ActionResourcePairMapper implements ObjectMapper { + + private MapperRegistry mapperRegistry; + + private PepConfig pepConfig; + + @Override + public Class<?> getMappedClass() { + return ActionResourcePair.class; + } + + @Override + public void map(Object o, PepRequest pepRequest) { + ActionResourcePair actionResource = (ActionResourcePair)o; + Object action = actionResource.getAction(); + Object resource = actionResource.getResource(); + mapperRegistry.getMapper(action.getClass()).map(action, pepRequest); + mapperRegistry.getMapper(resource.getClass()).map(resource, pepRequest); + } + + @Override + public void setMapperRegistry(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java new file mode 100755 index 0000000..b614b15 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java
@@ -0,0 +1,46 @@ +package org.openliberty.openaz.pepapi.std; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.*; + + +public final class ArrayMapper implements ObjectMapper { + + private static final Log logger = LogFactory.getLog(ArrayMapper.class); + + private PepConfig pepConfig; + + private MapperRegistry mapperRegistry; + + @Override + public Class<Object[]> getMappedClass() { + return Object[].class; + } + + @Override + public void map(Object o, PepRequest pepRequest) { + Object[] array = (Object[])o; + if(array != null && array.length > 0) { + ObjectMapper mapper = mapperRegistry.getMapper(array[0].getClass()); + if(mapper != null) { + for(Object item: array) { + mapper.map(item, pepRequest); + } + }else { + logger.error("Can't map an Object of class: " + array[0].getClass().getName()); + throw new PepException("Can't map an Object of class: " + array[0].getClass().getName()); + } + } + } + + @Override + public void setMapperRegistry(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java new file mode 100755 index 0000000..115368f --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java
@@ -0,0 +1,95 @@ +package org.openliberty.openaz.pepapi.std; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.*; + +import java.net.URI; +import java.util.Date; +import java.util.Map; +import java.util.Map.Entry; + + +public class CategoryContainerMapper implements ObjectMapper { + + private static final Log logger = LogFactory.getLog(CategoryContainerMapper.class); + + private Class<?> mappedClass; + + private MapperRegistry mapperRegistry; + + private PepConfig pepConfig; + + public CategoryContainerMapper(Class<?> mappedClass) { + this.mappedClass = mappedClass; + } + + @Override + public Class<?> getMappedClass() { + return this.mappedClass; + } + + @Override + public void map(Object o, PepRequest pepRequest) { + CategoryContainer a = (CategoryContainer)o; + PepRequestAttributes pepRequestAttributes = pepRequest.getPepRequestAttributes(a.getCategoryIdentifier()); + Map<String, Object[]> aMap = a.getAttributeMap(); + if(aMap != null) { + for(Entry<String, Object[]> e: aMap.entrySet()) { + String attributeId = resolveAttributeId(e.getKey()); + Object[] values = e.getValue(); + if(values != null && values.length > 0) { + map(pepRequestAttributes, attributeId, values); + } else { + logger.error("No value assigned for attribute : " + attributeId); + throw new IllegalArgumentException("No or null value for attribute : " + attributeId); + } + } + } + } + + @Override + public void setMapperRegistry(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } + + protected String resolveAttributeId(String attributeId) { + return attributeId; + } + + private final void map(PepRequestAttributes pepRequestAttributes, String key, Object... values) { + Object value = values[0]; + if (value instanceof String) { + pepRequestAttributes.addAttribute(key, (String[]) values); + } else if (value instanceof Long) { + pepRequestAttributes.addAttribute(key, (Long[]) values); + } else if (value instanceof Integer) { + pepRequestAttributes.addAttribute(key, (Integer[]) values); + } else if (value instanceof Double) { + pepRequestAttributes.addAttribute(key, (Double[]) values); + } else if (value instanceof Boolean) { + pepRequestAttributes.addAttribute(key, (Boolean[]) values); + } else if (value instanceof URI) { + pepRequestAttributes.addAttribute(key, (URI[]) values); + } else if (value instanceof Date) { + pepRequestAttributes.addAttribute(key, (Date[]) values); + }else { + logger.error("Type: " + value.getClass().getName() + " cannot be mapped for attribute: " + key); + throw new PepException("Can't map an object of class: " + value.getClass().getName()); + } + } + + protected PepConfig getPepConfig() { + return this.pepConfig; + } + + protected MapperRegistry getMapperRegistry() { + return this.mapperRegistry; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java new file mode 100755 index 0000000..dd6df7b --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java
@@ -0,0 +1,46 @@ +package org.openliberty.openaz.pepapi.std; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.*; + +import java.util.Collection; + + +public final class CollectionMapper implements ObjectMapper { + + private static final Log logger = LogFactory.getLog(CollectionMapper.class); + + private MapperRegistry mapperRegistry; + + private PepConfig pepConfig; + + @Override + public Class<?> getMappedClass() { + return Collection.class; + } + + @Override + public void map(Object o, PepRequest pepRequest) { + Collection<?> collection = (Collection<?>)o; + for(Object item: collection) { + ObjectMapper mapper = mapperRegistry.getMapper(item.getClass()); + if(mapper != null) { + mapper.map(item, pepRequest); + }else { + logger.error("Can't map an Object of class: " + item.getClass().getName()); + throw new PepException("Can't map an Object of class: " + item.getClass().getName()); + } + } + } + + @Override + public void setMapperRegistry(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java new file mode 100755 index 0000000..9c11151 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java
@@ -0,0 +1,13 @@ +package org.openliberty.openaz.pepapi.std; + + +import org.openliberty.openaz.pepapi.Obligation; + +public final class MatchAnyCriterion implements ObligationCriterion { + + @Override + public boolean match(Obligation obligation) { + return true; + } + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java new file mode 100755 index 0000000..f19836e --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java
@@ -0,0 +1,123 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.RequestReference; +import com.att.research.xacml.std.StdMutableRequest; +import com.att.research.xacml.std.StdMutableRequestReference; +import com.att.research.xacml.std.StdRequestAttributesReference; +import org.openliberty.openaz.pepapi.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * + */ +final class MultiRequest implements PepRequest { + + private static final String REQUEST_ATTR_ID_PREFIX = "attributes"; + + private final Map<Identifier, PepRequestAttributes> pepRequestAttributesMapByCategory; + + private final MapperRegistry mapperRegistry; + + private final PepConfig pepConfig; + + private final Object[] sharedRequestObjects; + + private List<?> associations; + + private final AtomicInteger idCounter; + + private final StdMutableRequest wrappedRequest; + + private StdMutableRequestReference currentRequestReference; + + private RequestReference sharedRequestReference; + + static MultiRequest newInstance(PepConfig pepConfig, MapperRegistry mapperRegistry, List<?> associations, Object[] sharedRequestObjects) { + MultiRequest m = new MultiRequest(pepConfig, mapperRegistry, associations, sharedRequestObjects); + m.mapSharedRequestObjects(); + m.mapAssociations(); + return m; + } + + private MultiRequest(PepConfig pepConfig, MapperRegistry mapperRegistry, List<?> associations, Object[] sharedRequestObjects) { + this.pepRequestAttributesMapByCategory = new HashMap<Identifier, PepRequestAttributes>(); + this.sharedRequestObjects = sharedRequestObjects; + this.associations = associations; + this.mapperRegistry = mapperRegistry; + this.pepConfig = pepConfig; + this.idCounter = new AtomicInteger(1); + this.wrappedRequest = new StdMutableRequest(); + this.currentRequestReference = new StdMutableRequestReference(); + } + + private void mapSharedRequestObjects() { + if(sharedRequestObjects == null) { + throw new IllegalArgumentException("One or more arguments are null"); + } + for(Object o: sharedRequestObjects) { + if(o == null) { + throw new IllegalArgumentException("One or more arguments are null"); + } + ObjectMapper mapper = mapperRegistry.getMapper(o.getClass()); + if(mapper == null) { + throw new IllegalArgumentException("No mappers found for class: " + o.getClass().getName()); + } + mapper.map(o, this); + } + //Collect + sharedRequestReference = currentRequestReference; + } + + private void mapAssociations() { + if(associations == null) { + throw new IllegalArgumentException("One or more arguments are null"); + } + for(Object association: associations) { + if(association == null) { + throw new IllegalArgumentException("One or more arguments are null"); + } + + //Prepare + pepRequestAttributesMapByCategory.clear(); + currentRequestReference = new StdMutableRequestReference(sharedRequestReference.getAttributesReferences()); + wrappedRequest.add(currentRequestReference); + + //Map + ObjectMapper mapper = mapperRegistry.getMapper(association.getClass()); + if(mapper == null) { + throw new IllegalArgumentException("No mappers found for class: " + association.getClass().getName()); + } + mapper.map(association, this); + } + } + + @Override + public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier) { + PepRequestAttributes pepRequestAttributes = pepRequestAttributesMapByCategory.get(categoryIdentifier); + if(pepRequestAttributes == null) { + String xmlId = generateRequestAttributesXmlId(); + StdPepRequestAttributes p = new StdPepRequestAttributes(xmlId, categoryIdentifier); + p.setIssuer(pepConfig.getIssuer()); + pepRequestAttributes = p; + pepRequestAttributesMapByCategory.put(categoryIdentifier, pepRequestAttributes); + wrappedRequest.add(pepRequestAttributes.getWrappedRequestAttributes()); + currentRequestReference.add(new StdRequestAttributesReference(xmlId)); + } + return pepRequestAttributes; + } + + private String generateRequestAttributesXmlId() { + return REQUEST_ATTR_ID_PREFIX + idCounter.getAndIncrement(); + } + + @Override + public Request getWrappedRequest() { + return wrappedRequest; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java new file mode 100755 index 0000000..23f00cb --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java
@@ -0,0 +1,87 @@ +package org.openliberty.openaz.pepapi.std; + +import org.openliberty.openaz.pepapi.Obligation; + +import java.util.*; + +public final class ObligationAttributeCriterion implements ObligationCriterion { + + private String id; + + private Set<String> valueSet; + + public ObligationAttributeCriterion(String id) { + this.id = id; + this.valueSet = new HashSet<String>(); + } + + ObligationAttributeCriterion(String id, String...values) { + this(id); + if(values != null && values.length > 0){ + this.valueSet.addAll(Arrays.asList(values)); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + + ((valueSet == null) ? 0 : valueSet.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ObligationAttributeCriterion other = (ObligationAttributeCriterion) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (valueSet == null) { + if (other.valueSet != null) + return false; + } else if (!valueSet.equals(other.valueSet)) + return false; + return true; + } + + public String getId() { + return id; + } + + public Set<String> getValueSet() { + return Collections.unmodifiableSet(valueSet); + } + + @Override + public boolean match(Obligation obligation) { + Map<String, Object[]> obligationAttrMap = obligation.getAttributeMap(); + if(!obligationAttrMap.containsKey(this.id)) { + return false; + } + //Proceed with value matching, if the AttributeMatch has a defined value set to match. + if(!valueSet.isEmpty()) { + Object[] attributeValues = obligationAttrMap.get(this.id); + boolean valueFound = false; + if(attributeValues != null) { + for(Object attributeValue: attributeValues) { + if(valueSet.contains(attributeValue)) { + valueFound = true; + break; + } + } + } + return valueFound; + } + return true; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java new file mode 100755 index 0000000..8a32271 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java
@@ -0,0 +1,28 @@ +package org.openliberty.openaz.pepapi.std; + +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.Matchable; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public final class ObligationCriteria implements Matchable<Obligation> { + + private Set<ObligationCriterion> criteria; + + ObligationCriteria(Collection<ObligationCriterion> criteria){ + this.criteria = new HashSet<ObligationCriterion>(); + this.criteria.addAll(criteria); + } + + @Override + public boolean match(Obligation obligation) { + for(ObligationCriterion criterion: criteria){ + if(!criterion.match(obligation)){ + return false; + } + } + return true; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java new file mode 100755 index 0000000..3572bec --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java
@@ -0,0 +1,37 @@ +package org.openliberty.openaz.pepapi.std; + + + +import java.util.HashSet; +import java.util.Set; + + +public final class ObligationCriteriaBuilder { + + private Set<ObligationCriterion> criteria = new HashSet<ObligationCriterion>(); + + public ObligationCriteriaBuilder matchAttribute(String attributeId) { + criteria.add(new ObligationAttributeCriterion(attributeId)); + return this; + } + + public ObligationCriteriaBuilder matchAttributeWithAnyGivenValue(String attributeId, + String... values) { + criteria.add(new ObligationAttributeCriterion(attributeId, values)); + return this; + } + + public ObligationCriteriaBuilder matchAnyObligationId(String... obligationIds) { + criteria.add(new ObligationIdCriterion(obligationIds)); + return this; + } + + public ObligationCriteriaBuilder matchAnyObligation() { + criteria.add(new MatchAnyCriterion()); + return this; + } + + public final ObligationCriteria build() { + return new ObligationCriteria(criteria); + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java new file mode 100755 index 0000000..82d8af1 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java
@@ -0,0 +1,10 @@ +package org.openliberty.openaz.pepapi.std; + + +import org.openliberty.openaz.pepapi.Obligation; + +public interface ObligationCriterion { + + public boolean match(Obligation obligation); + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java new file mode 100755 index 0000000..3763b87 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java
@@ -0,0 +1,25 @@ +package org.openliberty.openaz.pepapi.std; + +import org.openliberty.openaz.pepapi.Obligation; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public final class ObligationIdCriterion implements ObligationCriterion { + + private Set<String> obligationIdSet; + + public ObligationIdCriterion(String... obligationIds){ + this.obligationIdSet = new HashSet<String>(); + if(obligationIds != null) { + this.obligationIdSet.addAll(Arrays.asList(obligationIds)); + } + } + + @Override + public boolean match(Obligation obligation) { + return this.obligationIdSet.contains(obligation.getId()); + } + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java new file mode 100755 index 0000000..983a811 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java
@@ -0,0 +1,84 @@ +package org.openliberty.openaz.pepapi.std; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.*; +import java.util.Properties; + +/** + * + */ +public class PepUtils { + + private static final Log logger = LogFactory.getLog(PepUtils.class); + + public static Class<?> loadClass(String className) { + ClassLoader currentClassLoader = PepUtils.class.getClassLoader(); + Class<?> clazz; + try { + clazz = currentClassLoader.loadClass(className); + } catch (ClassNotFoundException e) { + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + clazz = contextClassLoader.loadClass(className); + } catch (ClassNotFoundException e1) { + throw new IllegalArgumentException(e); + } + } + return clazz; + } + + + public static <T> T instantiateClass(Class<T> clazz) { + try { + return clazz.newInstance(); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + } + + + public static Properties loadProperties(String propertyFile) { + Properties properties = new Properties(); + + //Try the location as a file first. + File file = new File(propertyFile); + InputStream in; + if(file.exists() && file.canRead()) { + if (!file.isAbsolute()) { + file = file.getAbsoluteFile(); + } + try { + in = new FileInputStream(file); + } catch (FileNotFoundException e) { + logger.info(propertyFile + " is not a file."); + } + } + + in = PepUtils.class.getResourceAsStream(propertyFile); + + if(in == null) { + logger.error("Invalid classpath of file location: " + propertyFile); + throw new IllegalArgumentException("Invalid classpath or file location: " + propertyFile); + } + + try { + properties.load(in); + } catch (IOException e) { + logger.error(e); + throw new IllegalArgumentException(e); + } finally { + if(in != null) { + try { + in.close(); + } catch (IOException e) { + logger.debug("Error closing stream", e); + } + } + } + return properties; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java new file mode 100755 index 0000000..113d781 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java
@@ -0,0 +1,22 @@ +package org.openliberty.openaz.pepapi.std; + + +import org.openliberty.openaz.pepapi.Resource; + +/** + * Created by ajith on 12/11/14. + */ +public class ResourceMapper extends CategoryContainerMapper { + + public ResourceMapper() { + super(Resource.class); + } + + @Override + protected String resolveAttributeId(String attributeId) { + if(attributeId.equals(Resource.RESOURCE_ID_KEY)) { + return getPepConfig().getDefaultResourceId(); + } + return attributeId; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java new file mode 100755 index 0000000..6649bac --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java
@@ -0,0 +1,47 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.AttributeAssignment; +import org.openliberty.openaz.pepapi.Advice; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +final class StdAdvice implements Advice { + + private com.att.research.xacml.api.Advice wrappedAdvice; + + StdAdvice(com.att.research.xacml.api.Advice advice) { + this.wrappedAdvice = advice; + } + + /** + * Return the Id for this Advice. + * + * @return a string containing the Id of this Advice + */ + public String getId(){ + return wrappedAdvice.getId().stringValue(); + } + + @Override + public Map<String, Object[]> getAttributeMap() { + Map<String, List<Object>> map = new HashMap<String, List<Object>>(); + for(AttributeAssignment a: wrappedAdvice.getAttributeAssignments()) { + String attributeId = a.getAttributeId().stringValue(); + List<Object> values = map.get(attributeId); + if(values == null) { + values = new ArrayList<Object>(); + map.put(attributeId, values); + } + values.add(a.getAttributeValue().getValue()); + } + Map<String, Object[]> attributeMap = new HashMap<String, Object[]>(); + for(Map.Entry<String, List<Object>> e: map.entrySet()) { + attributeMap.put(e.getKey(), e.getValue().toArray(new Object[1])); + } + return attributeMap; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java new file mode 100755 index 0000000..1c05ab3 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java
@@ -0,0 +1,99 @@ +package org.openliberty.openaz.pepapi.std; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public final class StdMapperRegistry implements MapperRegistry { + + private static final Log logger = LogFactory.getLog(StdMapperRegistry.class); + + private final Map<Class<?>, ObjectMapper> map; + + private PepConfig pepConfig; + + private StdMapperRegistry(PepConfig pepConfig) { + //Register defaults. + this.pepConfig = pepConfig; + map = new HashMap<Class<?>, ObjectMapper>(); + registerMapper(new CollectionMapper()); + registerMapper(new ArrayMapper()); + registerMapper(new SubjectMapper()); + registerMapper(new ActionMapper()); + registerMapper(new ResourceMapper()); + registerMapper(new CategoryContainerMapper(Environment.class)); + registerMapper(new CategoryContainerMapper(CategoryContainer.class)); + registerMapper(new ActionResourcePairMapper()); + } + + public static MapperRegistry newInstance(PepConfig pepConfig) { + return new StdMapperRegistry(pepConfig); + } + + public static MapperRegistry newInstance(PepConfig pepConfig, List<ObjectMapper> mappers) { + MapperRegistry mapperRegistry = newInstance(pepConfig); + if(mappers != null) { + mapperRegistry.registerMappers(mappers); + } + return mapperRegistry; + } + + @Override + public void registerMapper(ObjectMapper mapper) { + mapper.setPepConfig(pepConfig); + mapper.setMapperRegistry(this); + map.put(mapper.getMappedClass(), mapper); + } + + @Override + public void registerMappers(Iterable<? extends ObjectMapper> mappers) { + for(ObjectMapper mapper: mappers) { + registerMapper(mapper); + } + } + + @Override + public ObjectMapper getMapper(Class<?> clazz) { + ObjectMapper mapper = null; + Class<?> c = clazz; + while(mapper == null && !c.equals(Object.class)) { + mapper = getClassMapper(c); + c = c.getSuperclass(); + } + + //Handle Arrays. + if(mapper == null) { + if(clazz.isArray()) { + mapper = getMapper(Object[].class); + } + } + + if(mapper != null) { + logger.debug("Mapper :" + mapper.getClass().getName() + " found for class: " + clazz); + return mapper; + }else { + throw new PepException("No ObjectMapper found for Object of Class: " + clazz); + } + } + + private ObjectMapper getClassMapper(Class<?> clazz) { + ObjectMapper mapper = map.get(clazz); + if(mapper == null) { + Class<?>[] interfaces = clazz.getInterfaces(); + if(interfaces != null && interfaces.length > 0) { + for(Class<?> inf: interfaces) { + mapper = map.get(inf); + if(mapper != null) { + break; + } + } + } + } + return mapper; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java new file mode 100755 index 0000000..d2fd1ca --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java
@@ -0,0 +1,48 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.AttributeAssignment; +import org.openliberty.openaz.pepapi.Obligation; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +final class StdObligation implements Obligation { + + private com.att.research.xacml.api.Obligation wrappedObligation; + + StdObligation(com.att.research.xacml.api.Obligation obligation) { + this.wrappedObligation = obligation; + } + + /** + * Return the Id for this Obligation. + * + * @return a string containing the Id of this Obligation + */ + public String getId(){ + return wrappedObligation.getId().stringValue(); + } + + @Override + public Map<String, Object[]> getAttributeMap() { + Map<String, List<Object>> map = new HashMap<String, List<Object>>(); + for(AttributeAssignment a: wrappedObligation.getAttributeAssignments()) { + String attributeId = a.getAttributeId().stringValue(); + List<Object> values = map.get(attributeId); + if(values == null) { + values = new ArrayList<Object>(); + map.put(attributeId, values); + } + values.add(a.getAttributeValue().getValue()); + } + + Map<String, Object[]> attributeMap = new HashMap<String, Object[]>(); + for(Map.Entry<String, List<Object>> e: map.entrySet()) { + attributeMap.put(e.getKey(), e.getValue().toArray(new Object[1])); + } + return attributeMap; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java new file mode 100755 index 0000000..488ce5b --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java
@@ -0,0 +1,106 @@ +package org.openliberty.openaz.pepapi.std; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationHandler; +import org.openliberty.openaz.pepapi.ObligationHandlerRegistry; +import org.openliberty.openaz.pepapi.Attribute; +import org.openliberty.openaz.pepapi.MatchAllObligationAttributes; +import org.openliberty.openaz.pepapi.MatchAnyObligation; +import org.openliberty.openaz.pepapi.Matchable; + +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * An <code>ObligationHandlerRegistry</code> implementation that accept handler classes that are either ObligationHandler instances + * or contain any of the following annotations - <code> @MatchAnyObligation, @MatchAllObligationAttributes</code> + * that represents Obligation criteria for registration. + * + * @author Ajith Nair + * + */ +public class StdObligationHandlerRegistry implements ObligationHandlerRegistry { + + private static final Log logger = LogFactory.getLog(StdObligationHandlerRegistry.class); + + private final Map<Class<?>, Matchable<Obligation>> oHandlerCriteriaMap; + + private StdObligationHandlerRegistry(List<?> oHandlers) { + oHandlerCriteriaMap = new HashMap<Class<?>, Matchable<Obligation>>(); + for (Object oHandler : oHandlers) { + Class<?> oHandlerClass = oHandler.getClass(); + Matchable<Obligation> matchable = null; + if(oHandler instanceof ObligationHandler) { + matchable = (ObligationHandler)oHandler; + }else { + matchable = processAnnotation(oHandlerClass); + } + + if (matchable != null) { + oHandlerCriteriaMap.put(oHandlerClass, matchable); + }else { + logger.error("Obligation Handler Class: " + oHandlerClass + + " is not an instance of ObligationHandler or doesn't contain a valid Annotation"); + throw new IllegalArgumentException("Obligation Handler Class: " + oHandlerClass + + " is not an instance of ObligationHandler or doesn't contain a valid Annotation"); + } + } + } + + /** + * Process Annotations in the classes provided and translate those into <code>ObligationCriteria</code>. + * + * @param oHandlerClass + * @return an ObligationCriteria instance. + */ + private ObligationCriteria processAnnotation(Class<?> oHandlerClass) { + ObligationCriteria criteria = null; + for (Annotation a : oHandlerClass.getAnnotations()) { + if (a.annotationType().equals(MatchAnyObligation.class)) { + String[] obligationIds = ((MatchAnyObligation) a).value(); + ObligationCriteriaBuilder criteriaBuilder = new ObligationCriteriaBuilder(); + if (obligationIds != null && obligationIds.length > 0) { + criteriaBuilder.matchAnyObligationId(obligationIds); + } else { + criteriaBuilder.matchAnyObligation(); + } + criteria = criteriaBuilder.build(); + } else if (a.annotationType().equals(MatchAllObligationAttributes.class)) { + ObligationCriteriaBuilder criteriaBuilder = new ObligationCriteriaBuilder(); + MatchAllObligationAttributes attributeObligationAnnotation = + (MatchAllObligationAttributes) a; + for (Attribute attribute : attributeObligationAnnotation.value()) { + String attributeId = attribute.id(); + String[] anyValue = attribute.anyValue(); + if (anyValue != null && anyValue.length > 0) { + criteriaBuilder.matchAttributeWithAnyGivenValue( + attributeId, anyValue); + } else { + criteriaBuilder.matchAttribute(attributeId); + } + } + criteria = criteriaBuilder.build(); + } + } + return criteria; + } + + /** + * Returns a new instance of <code>StdObligationHandlerRegistry</code>. + * + * @param oHandlers + * @return + */ + public static ObligationHandlerRegistry newInstance(List<?> oHandlers) { + return new StdObligationHandlerRegistry(oHandlers); + } + + @Override + public Map<Class<?>, Matchable<Obligation>> getRegisteredHandlerMap() { + return this.oHandlerCriteriaMap; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java new file mode 100755 index 0000000..6cf3b2c --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java
@@ -0,0 +1,87 @@ +package org.openliberty.openaz.pepapi.std; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationHandlerRegistry; +import org.openliberty.openaz.pepapi.ObligationRouter; +import org.openliberty.openaz.pepapi.UnhandleableObligationException; +import org.openliberty.openaz.pepapi.Matchable; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * Entity that routes obligations at runtime. + * + * @see org.openliberty.openaz.pepapi.Obligation + * @author Ajith Nair + */ +public final class StdObligationRouter implements ObligationRouter { + + private static final Log logger = LogFactory.getLog(StdObligationRouter.class); + + private final ObligationHandlerRegistry registrationHandler; + + private final ThreadLocalObligationStore obligationStore; + + StdObligationRouter(ObligationHandlerRegistry registrationHandler, + ThreadLocalObligationStore threadLocalOStore) { + this.registrationHandler = registrationHandler; + this.obligationStore = threadLocalOStore; + } + + public static StdObligationRouter newInstance( + ObligationHandlerRegistry registrationHandler, + ThreadLocalObligationStore threadLocalOStore) { + return new StdObligationRouter(registrationHandler, + threadLocalOStore); + } + + /** + * Handles runtime obligations and routes to appropriate policy enforcement points as required. + * + * @param obligationMap a <code>Map</code> of <code>Obligation</code>s keyed by Obligation ID. + * @throws org.openliberty.openaz.pepapi.UnhandleableObligationException if an Obligation cannot be handled/routed. + */ + @Override + public void routeObligations(Map<String, Obligation> obligationMap) { + //Clear any stale Obligations on the current thread. + obligationStore.clear(); + if(obligationMap != null) { + Map<Class<?>, Set<Obligation>> obligationMapByHandlerClass + = new HashMap<Class<?>, Set<Obligation>>(); + for(Entry<String, Obligation> oe: obligationMap.entrySet()) { + boolean isObligationHandleable = false; + String obligationId = oe.getKey(); + Obligation obligation = oe.getValue(); + for(Entry<Class<?>, Matchable<Obligation>> pe : + this.registrationHandler.getRegisteredHandlerMap().entrySet()) { + Class<?> handlerClass = pe.getKey(); + Matchable<Obligation> matchable = pe.getValue(); + if(matchable.match(obligation)) { + Set<Obligation> handlerObligationSet = obligationMapByHandlerClass.get(handlerClass); + if(handlerObligationSet == null){ + handlerObligationSet = new HashSet<Obligation>(); + obligationMapByHandlerClass.put(handlerClass, handlerObligationSet); + } + handlerObligationSet.add(obligation); + isObligationHandleable = true; + if(logger.isDebugEnabled()) { + logger.debug("Obligation - " + obligationId + " matched by Handler - " + handlerClass); + } + } + } + if(!isObligationHandleable) { + throw new UnhandleableObligationException( + "No ObligationHandlers available for handling Obligation: " + + oe.getKey()); + } + } + obligationStore.setObligations(obligationMapByHandlerClass); + } + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java new file mode 100755 index 0000000..519eefb --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java
@@ -0,0 +1,192 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPEngineFactory; +import com.att.research.xacml.api.pdp.PDPException; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONResponse; +import com.att.research.xacml.std.json.JSONStructureException; +import com.att.research.xacml.util.FactoryException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.*; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + + +final class StdPepAgent implements PepAgent { + + @SuppressWarnings("unused") + private static final Log logger = LogFactory.getLog(StdPepAgent.class); + + private Properties xacmlProperties; + + private PepConfig pepConfig; + + private PDPEngine pdpEngine; + + private PDPEngineFactory pdpEngineFactory; + + private List<ObligationStoreAware> obligationHandlers; + + private PepRequestFactory pepRequestFactory; + + private PepResponseFactory pepResponseFactory; + + StdPepAgent() { + obligationHandlers = new ArrayList<ObligationStoreAware>(); + } + + final void initialize() { + assert(pdpEngineFactory != null); + + //Instantiate PDPEngine + if(pdpEngine == null) { + try { + pdpEngine = pdpEngineFactory.newEngine(xacmlProperties); + } catch (FactoryException e) { + throw new PepException(e); + } + } + + List<ObjectMapper> objectMappers = new ArrayList<ObjectMapper>(); + for(String mapperClassName: pepConfig.getMapperClassNames()) { + Class<? extends ObjectMapper> clazz = (Class<? extends ObjectMapper>)PepUtils.loadClass(mapperClassName); + objectMappers.add(PepUtils.instantiateClass(clazz)); + } + MapperRegistry mapperRegistry = StdMapperRegistry.newInstance(pepConfig, objectMappers); + + ObligationRouter oRouter = null; + if(!obligationHandlers.isEmpty()) { + ObligationHandlerRegistry oHandlerRegistry = StdObligationHandlerRegistry.newInstance(obligationHandlers); + ThreadLocalObligationStore oStore = ThreadLocalObligationStore.newInstance(); + for(ObligationStoreAware oHandler: obligationHandlers) { + oHandler.setObligationStore(oStore); + } + oRouter = StdObligationRouter.newInstance(oHandlerRegistry, oStore); + } + + //Instantiate PepRequestFactory + pepRequestFactory = new StdPepRequestFactory(pepConfig, mapperRegistry); + //Instantiate PepResponseFactory + pepResponseFactory = new StdPepResponseFactory(pepConfig, oRouter); + } + + @Override + public PepResponse decide(Object... objects) { + return decide(pepRequestFactory.newPepRequest(objects)).get(0); + } + + @Override + public PepResponse simpleDecide(String subjectId, String actionId, + String resourceId) { + return decide(Subject.newInstance(subjectId), Action.newInstance(actionId), Resource.newInstance(resourceId)); + } + + @Override + public List<PepResponse> bulkDecide(List<?> actionResourcePairs, Object... objects) { + return decide(pepRequestFactory.newBulkPepRequest(actionResourcePairs, objects)); + } + + private List<PepResponse> decide(PepRequest pepRequest) { + List<PepResponse> pepResponses = new ArrayList<PepResponse>(); + Request request = pepRequest.getWrappedRequest(); + + //Log request + if(logger.isDebugEnabled()) { + logRequest(request); + } + + Response response; + try { + response = pdpEngine.decide(request); + } catch (PDPException e) { + logger.error(e); + throw new PepException(e); + } + + //Log the response + if(logger.isDebugEnabled()) { + logResponse(response); + } + + for(Result result: response.getResults()) { + pepResponses.add(pepResponseFactory.newPepResponse(result)); + } + return pepResponses; + } + + private void logRequest(Request request) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + JSONRequest.convert(request, out); + logger.debug(out.toString("UTF-8")); + } catch (IOException e) { + logger.debug("Error printing XACML request in JSON", e); + } catch (JSONStructureException e) { + logger.debug("Error printing XACML request in JSON", e); + }finally { + if(out != null) { + try { + out.close(); + } catch (IOException e) { + logger.debug("Error closing stream"); + } + } + } + } + + private void logResponse(Response response) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + JSONResponse.convert(response, out); + logger.debug(out.toString("UTF-8")); + } catch (IOException e) { + logger.debug("Error printing XACML response in JSON", e); + } catch (JSONStructureException e) { + logger.debug("Error printing XACML response in JSON", e); + }finally { + if(out != null) { + try { + out.close(); + } catch (IOException e) { + logger.debug("Error closing stream"); + } + } + } + } + + public PDPEngine getPdpEngine() { + return pdpEngine; + } + + public PepConfig getPepConfig() { + return pepConfig; + } + + void setPdpEngineFactory(PDPEngineFactory pdpEngineFactory) { + this.pdpEngineFactory = pdpEngineFactory; + } + + void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } + + void setXacmlProperties(Properties properties) { + this.xacmlProperties = properties; + } + + void setObligationHandlers(List<ObligationStoreAware> obligationHandlers) { + if(obligationHandlers != null) { + this.obligationHandlers = new ArrayList<ObligationStoreAware>(); + this.obligationHandlers.addAll(obligationHandlers); + } + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java new file mode 100755 index 0000000..bcff6fd --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java
@@ -0,0 +1,59 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.pdp.PDPEngineFactory; +import com.att.research.xacml.util.FactoryException; +import org.openliberty.openaz.pepapi.*; + +import java.util.List; +import java.util.Properties; + + +public class StdPepAgentFactory implements PepAgentFactory { + + private volatile PepAgent pepAgent; + + private PDPEngineFactory pdpEngineFactory; + + private Properties xacmlProperties; + + private PepConfig pepConfig; + + private List<ObligationStoreAware> obligationHandlers; + + public StdPepAgentFactory(String propertyFile) { + this(PepUtils.loadProperties(propertyFile)); + } + + public StdPepAgentFactory(Properties properties) { + this.xacmlProperties = properties; + this.pepConfig = new StdPepConfig(properties); + try { + //FIXME: Error when invoking newInstance() with properties. + pdpEngineFactory = PDPEngineFactory.newInstance(); + } catch (FactoryException e) { + throw new PepException(e); + } + } + + @Override + public PepAgent getPepAgent() { + if(pepAgent == null) { + synchronized(this) { + if(this.pepAgent == null) { + StdPepAgent pa = new StdPepAgent(); + pa.setPepConfig(pepConfig); + pa.setXacmlProperties(xacmlProperties); + pa.setPdpEngineFactory(pdpEngineFactory); + pa.setObligationHandlers(obligationHandlers); + pa.initialize(); + pepAgent = pa; + } + } + } + return pepAgent; + } + + public void setObligationHandlers(List<ObligationStoreAware> obligationHandlers) { + this.obligationHandlers = obligationHandlers; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java new file mode 100755 index 0000000..7aee915 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java
@@ -0,0 +1,144 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.XACML3; +import com.google.common.base.Splitter; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.PepConfig; +import org.openliberty.openaz.pepapi.PepResponseBehavior; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + + +public final class StdPepConfig implements PepConfig { + + private static final Log logger = LogFactory.getLog(StdPepConfig.class); + + private static final String PEP_ISSUER = "pep.issuer"; + + private static final String PEP_DEFAULT_SUBJECT_ID = "pep.subject.id"; + + private static final String PEP_DEFAULT_ACTION_ID = "pep.action.id"; + + private static final String PEP_DEFAULT_RESOURCE_ID = "pep.resource.id"; + + private static final String PEP_INDETERMINATE_BEHAVIOR = "pep.indeterminate.behavior"; + + private static final String PEP_NOTAPPLICABLE_BEHAVIOR = "pep.notapplicable.behavior"; + + private static final String PEP_MAPPER_CLASSES = "pep.mapper.classes"; + + private String issuer; + + private String subjectIdURI; + + private String actionIdURI; + + private String resourceIdURI; + + private PepResponseBehavior indeterminateBehavior; + + private PepResponseBehavior notApplicableBehavior; + + private List<String> mapperClassNames; + + public StdPepConfig() { + //Defaults + subjectIdURI = XACML3.ID_SUBJECT_SUBJECT_ID.stringValue(); + actionIdURI = XACML3.ID_ACTION_ACTION_ID.stringValue(); + resourceIdURI = XACML3.ID_RESOURCE_RESOURCE_ID.stringValue(); + indeterminateBehavior = PepResponseBehavior.THROW_EXCEPTION; + notApplicableBehavior = PepResponseBehavior.RETURN_NO; + mapperClassNames = Collections.EMPTY_LIST; + } + + public StdPepConfig(Properties properties) { + this(); + issuer = properties.getProperty(PEP_ISSUER); + + String subjectIdURI = properties.getProperty(PEP_DEFAULT_SUBJECT_ID); + if(!StringUtils.isEmpty(subjectIdURI)){ + this.subjectIdURI = subjectIdURI; + } + + String actionIdURI = properties.getProperty(PEP_DEFAULT_ACTION_ID); + if(!StringUtils.isEmpty(actionIdURI)) { + this.actionIdURI = actionIdURI; + } + + String resourceIdURI = properties.getProperty(PEP_DEFAULT_RESOURCE_ID); + if(!StringUtils.isEmpty(resourceIdURI)) { + this.resourceIdURI = resourceIdURI; + } + + String indeterminateString = properties.getProperty(PEP_INDETERMINATE_BEHAVIOR); + if(!StringUtils.isEmpty(indeterminateString)) { + PepResponseBehavior indeterminateBehavior = PepResponseBehavior.valueOf(indeterminateString); + if(indeterminateBehavior == null) { + logger.error("Invalid indeterminate behavior found in configuration."); + //TODO: Throw exception ? + } + this.indeterminateBehavior = indeterminateBehavior; + } + + String notapplicableString = properties.getProperty(PEP_NOTAPPLICABLE_BEHAVIOR); + if(!StringUtils.isEmpty(notapplicableString)) { + PepResponseBehavior notApplicableBehavior = PepResponseBehavior.valueOf(notapplicableString); + if(notApplicableBehavior == null) { + logger.error("Invalid notapplicable behavior found in configuration."); + //TODO: Throw exception ? + } + this.notApplicableBehavior = notApplicableBehavior; + } + + + String mapperClassNameString = properties.getProperty(PEP_MAPPER_CLASSES); + if(!StringUtils.isEmpty(mapperClassNameString)) { + List mapperClassNames = new ArrayList<String>(); + for(String className: Splitter.on(",").omitEmptyStrings().trimResults().split(mapperClassNameString)) { + mapperClassNames.add(className); + } + this.mapperClassNames = Collections.unmodifiableList(mapperClassNames); + } + + } + + @Override + public String getIssuer() { + return issuer; + } + + @Override + public String getDefaultSubjectId() { + return subjectIdURI; + } + + @Override + public String getDefaultResourceId() { + return resourceIdURI; + } + + @Override + public String getDefaultActionId() { + return actionIdURI; + } + + @Override + public PepResponseBehavior getIndeterminateBehavior() { + return indeterminateBehavior; + } + + @Override + public PepResponseBehavior getNotApplicableBehavior() { + return notApplicableBehavior; + } + + @Override + public List<String> getMapperClassNames() { + return mapperClassNames; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java new file mode 100755 index 0000000..3b08374 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java
@@ -0,0 +1,91 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.std.StdMutableRequest; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + + +final class StdPepRequest implements PepRequest { + + private static final String REQUEST_ATTR_ID_PREFIX = "attributes"; + + private static final Log logger = LogFactory.getLog(StdPepRequest.class); + + private final StdMutableRequest wrappedRequest; + + private final Map<Identifier, PepRequestAttributes> pepRequestAttributesMapByCategory; + + private final MapperRegistry mapperRegistry; + + private final PepConfig pepConfig; + + private final Object[] requestObjects; + + private final AtomicInteger idCounter; + + static StdPepRequest newInstance(PepConfig pepConfig, MapperRegistry mapperRegistry, Object[] requestObjects) { + StdPepRequest stdPepRequest = new StdPepRequest(pepConfig, mapperRegistry, requestObjects); + stdPepRequest.map(); + return stdPepRequest; + } + + /** + * + * @return + */ + private String generateRequestAttributesXmlId() { + return REQUEST_ATTR_ID_PREFIX + idCounter.getAndIncrement(); + } + + private StdPepRequest(PepConfig pepConfig, MapperRegistry mapperRegistry, Object[] requestObjects) { + this.pepConfig = pepConfig; + this.mapperRegistry = mapperRegistry; + this.requestObjects = requestObjects; + this.pepRequestAttributesMapByCategory = new HashMap<Identifier, PepRequestAttributes>(); + this.idCounter = new AtomicInteger(1); + this.wrappedRequest = new StdMutableRequest(); + } + + @Override + public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier) { + PepRequestAttributes pepRequestAttributes = pepRequestAttributesMapByCategory.get(categoryIdentifier); + if(pepRequestAttributes == null) { + String xmlId = generateRequestAttributesXmlId(); + StdPepRequestAttributes p = new StdPepRequestAttributes(xmlId, categoryIdentifier); + p.setIssuer(pepConfig.getIssuer()); + pepRequestAttributes = p; + pepRequestAttributesMapByCategory.put(categoryIdentifier, pepRequestAttributes); + wrappedRequest.add(pepRequestAttributes.getWrappedRequestAttributes()); + } + return pepRequestAttributes; + } + + private void map() { + if(requestObjects == null) { + throw new IllegalArgumentException("One or more arguments are null"); + } + for(Object o: requestObjects) { + if(o == null) { + throw new IllegalArgumentException("One or more arguments are null"); + } + ObjectMapper mapper = mapperRegistry.getMapper(o.getClass()); + if(mapper == null) { + throw new IllegalArgumentException("No mappers found for class: " + o.getClass().getName()); + } + mapper.map(o, this); + } + } + + @Override + public Request getWrappedRequest() { + return wrappedRequest; + } + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java new file mode 100755 index 0000000..40a0409 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java
@@ -0,0 +1,125 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.RequestAttributes; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdMutableAttribute; +import com.att.research.xacml.std.StdMutableRequestAttributes; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.PepRequestAttributes; + +import java.net.URI; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + + +final class StdPepRequestAttributes implements PepRequestAttributes { + + private static final Log log = LogFactory.getLog(StdPepRequestAttributes.class); + + private final String id; + + private final Identifier categoryIdentifier; + + private String issuer; + + private StdMutableRequestAttributes wrappedRequestAttributes; + + //Internal map to hold mutable attributes as StdMutableRequestAttributes + // does not return a mutable view of Attributes. + private Map<Identifier, StdMutableAttribute> attributeMapById; + + StdPepRequestAttributes(String id, Identifier categoryIdentifier) { + this.id = id; + this.categoryIdentifier = categoryIdentifier; + this.attributeMapById = new HashMap<Identifier, StdMutableAttribute>(); + this.wrappedRequestAttributes = new StdMutableRequestAttributes(); + this.wrappedRequestAttributes.setCategory(categoryIdentifier); + this.wrappedRequestAttributes.setXmlId(id); + } + + @Override + public Identifier getCategory() { + return categoryIdentifier; + } + + @Override + public void addAttribute(String name, Date... values) { + addAttribute(name, values, XACML3.ID_DATATYPE_DATE); + } + + @Override + public void addAttribute(String name, String... values) { + addAttribute(name, values, XACML3.ID_DATATYPE_STRING); + } + + @Override + public void addAttribute(String name, Integer... values) { + addAttribute(name, values, XACML3.ID_DATATYPE_INTEGER); + } + + @Override + public void addAttribute(String name, Boolean... values) { + addAttribute(name, values, XACML3.ID_DATATYPE_BOOLEAN); + } + + @Override + public void addAttribute(String name, Long... values) { + addAttribute(name, values, XACML3.ID_DATATYPE_INTEGER); + } + + @Override + public void addAttribute(String name, Double... values) { + addAttribute(name, values, XACML3.ID_DATATYPE_DOUBLE); + } + + @Override + public void addAttribute(String name, URI... values) { + addAttribute(name, values, XACML3.ID_DATATYPE_ANYURI); + } + + private <T> void addAttribute(String name, T[] values, Identifier dataTypeId) { + if(values == null) { + throw new IllegalArgumentException("Null attribute value provided for attribute: " + name); + } + Identifier attributeId = new IdentifierImpl(name); + StdMutableAttribute mutableAttribute = attributeMapById.get(attributeId); + if(mutableAttribute == null) { + mutableAttribute = new StdMutableAttribute(); + mutableAttribute.setAttributeId(new IdentifierImpl(name)); + mutableAttribute.setCategory(categoryIdentifier); + mutableAttribute.setIncludeInResults(false); + mutableAttribute.setIssuer(issuer == null?"":issuer); + attributeMapById.put(attributeId, mutableAttribute); + wrappedRequestAttributes.add(mutableAttribute); + } + for(T value: values) { + if(value != null) { + mutableAttribute.addValue(new StdAttributeValue<T>(dataTypeId, value)); + } + } + } + + @Override + public RequestAttributes getWrappedRequestAttributes() { + return wrappedRequestAttributes; + } + + @Override + public String getId() { + return id; + } + + public String getIssuer() { + return issuer; + } + + public void setIssuer(String issuer) { + this.issuer = issuer; + } + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java new file mode 100755 index 0000000..a6a81b9 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java
@@ -0,0 +1,40 @@ +package org.openliberty.openaz.pepapi.std; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.MapperRegistry; +import org.openliberty.openaz.pepapi.PepConfig; +import org.openliberty.openaz.pepapi.PepRequest; +import org.openliberty.openaz.pepapi.PepRequestFactory; + +import java.util.List; + + +final class StdPepRequestFactory implements PepRequestFactory { + + private static final Log logger = LogFactory.getLog(StdPepRequestFactory.class); + + private final PepConfig pepConfig; + + private final MapperRegistry mapperRegistry; + + /** + * + * @param pepConfig + */ + StdPepRequestFactory(PepConfig pepConfig, MapperRegistry mapperRegistry) { + this.pepConfig = pepConfig; + this.mapperRegistry = mapperRegistry; + } + + @Override + public PepRequest newPepRequest(Object[] objects) { + return StdPepRequest.newInstance(pepConfig, mapperRegistry, objects); + } + + @Override + public PepRequest newBulkPepRequest(List<?> associations, Object[] objects) { + return MultiRequest.newInstance(pepConfig, mapperRegistry, associations, objects); + } + +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java new file mode 100755 index 0000000..2a19d30 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java
@@ -0,0 +1,127 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.*; +import com.att.research.xacml.api.Attribute; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Advice; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + + +final class StdPepResponse implements PepResponse { + + private static final Log logger = LogFactory.getLog(StdPepResponse.class); + + private final Result wrappedResult; + + private final PepConfig pepConfig; + + private final ObligationRouter obligationRouter; + + static PepResponse newInstance(PepConfig pepConfig, ObligationRouter obligationRouter, Result result) { + return new StdPepResponse(pepConfig, obligationRouter, result); + } + + private StdPepResponse(PepConfig pepConfig, ObligationRouter obligationRouter, Result result) { + this.pepConfig = pepConfig; + this.wrappedResult = result; + this.obligationRouter = obligationRouter; + } + + @Override + public boolean allowed() throws PepException { + if(obligationRouter != null) { + obligationRouter.routeObligations(getObligations()); + } + switch(wrappedResult.getDecision()) { + case PERMIT: + return true; + case DENY: + return false; + case NOTAPPLICABLE: + return enforceBehavior(pepConfig.getNotApplicableBehavior(), "Not Applicable"); + //TODO: Handle various indeterminate status codes. + case INDETERMINATE: + case INDETERMINATE_DENY: + case INDETERMINATE_DENYPERMIT: + case INDETERMINATE_PERMIT: + Status status = wrappedResult.getStatus(); + String formatted = String.format("Decision: Indeterminate, Status Code: %s, Status Message: %s", + status.getStatusCode(), status.getStatusMessage()); + logger.error(formatted); + throw new PepException(formatted); + default: + throw new PepException("Invalid response from PDP"); + } + } + + @Override + public Map<String, Obligation> getObligations() throws PepException { + Map<String, Obligation> obligationMap = new HashMap<String, Obligation>(); + for(com.att.research.xacml.api.Obligation wrappedObligation: wrappedResult.getObligations()) { + Obligation obligation = new StdObligation(wrappedObligation); + obligationMap.put(obligation.getId(), obligation); + } + return obligationMap; + } + + @Override + public Map<String, Advice> getAdvices() throws PepException { + Map<String, Advice> adviceMap = new HashMap<String, Advice>(); + for(com.att.research.xacml.api.Advice wrappedAdvice: wrappedResult.getAssociatedAdvice()) { + Advice advice = new StdAdvice(wrappedAdvice); + adviceMap.put(advice.getId(), advice); + } + return adviceMap; + } + + @Override + public Object getAssociation() throws PepException { + return null; + } + + @Override + public Collection<Attribute> getAttributes() { + Collection<Attribute> attributes = new ArrayList<Attribute>(); + for(AttributeCategory category: wrappedResult.getAttributes()) { + attributes.addAll(category.getAttributes()); + } + return attributes; + } + + @Override + public Map<Identifier, Collection<Attribute>> getAttributesByCategory() { + Map<Identifier, Collection<Attribute>> attributesByCategory = new HashMap<Identifier, Collection<Attribute>>(); + for(AttributeCategory category: wrappedResult.getAttributes()) { + attributesByCategory.put(category.getCategory(), category.getAttributes()); + } + return attributesByCategory; + } + + @Override + public Result getWrappedResult() { + return wrappedResult; + } + + private boolean enforceBehavior( + PepResponseBehavior pepResponseBehavior, String decision) throws PepException { + switch (pepResponseBehavior) { + case RETURN_YES: + return true; + case RETURN_NO: + return false; + case THROW_EXCEPTION: + logger.info("Throwing an exception as per configured behavior for decision: " + decision); + throw new PepException("Exception being thrown based on configured " + + "behavior for decision: " + decision); + default: + throw new PepException("Invalid PepResponseBehavior"); + } + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java new file mode 100755 index 0000000..627f80e --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java
@@ -0,0 +1,29 @@ +package org.openliberty.openaz.pepapi.std; + +import com.att.research.xacml.api.Result; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.ObligationRouter; +import org.openliberty.openaz.pepapi.PepConfig; +import org.openliberty.openaz.pepapi.PepResponse; +import org.openliberty.openaz.pepapi.PepResponseFactory; + + +final class StdPepResponseFactory implements PepResponseFactory { + + private static final Log logger = LogFactory.getLog(StdPepResponseFactory.class); + + private PepConfig pepConfig; + + private ObligationRouter obligationRouter; + + StdPepResponseFactory(PepConfig pepConfig, ObligationRouter obligationRouter) { + this.pepConfig = pepConfig; + this.obligationRouter = obligationRouter; + } + + @Override + public PepResponse newPepResponse(Result result) { + return StdPepResponse.newInstance(pepConfig, obligationRouter, result); + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java new file mode 100755 index 0000000..82c4bee --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java
@@ -0,0 +1,22 @@ +package org.openliberty.openaz.pepapi.std; + + +import org.openliberty.openaz.pepapi.Subject; + +/** + * Created by ajith on 12/11/14. + */ +public class SubjectMapper extends CategoryContainerMapper { + + public SubjectMapper() { + super(Subject.class); + } + + @Override + protected String resolveAttributeId(String attributeId) { + if(attributeId.equals(Subject.SUBJECT_ID_KEY)) { + return getPepConfig().getDefaultSubjectId(); + } + return attributeId; + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java new file mode 100755 index 0000000..2c1d981 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java
@@ -0,0 +1,96 @@ +package org.openliberty.openaz.pepapi.std; + + +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationStore; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * Acts as a store for Obligation instances in the current thread of execution. + * + * @author Ajith Nair, David Laurance, Darshak Kothari + * + */ +public final class ThreadLocalObligationStore implements ObligationStore { + + private static final ThreadLocal<Map<Class<?>, Set<Obligation>>> obligationMapContainer = + new ThreadLocal<Map<Class<?>, Set<Obligation>>>(); + + private ThreadLocalObligationStore(){} + + public static ThreadLocalObligationStore newInstance() { + return new ThreadLocalObligationStore(); + } + + /** + * Set Obligations for the current thread of execution. + * + * @param obligationMap a <code>Map</code> containing <code>Obligation</code> instances keyed by ObligationHandler Class. + */ + void setObligations(Map<Class<?>, Set<Obligation>> obligationMap) { + if(obligationMap != null && !obligationMap.isEmpty()) { + obligationMapContainer.set(Collections.unmodifiableMap(obligationMap)); + }else { + obligationMapContainer.set(null); + } + } + + /** + * Returns all obligations in the current thread of execution. + * + * @return a <code>Set</code> of <code>Obligation</code> instances. + */ + public Set<Obligation> getAllObligations() { + Set<Obligation> allObligations = new HashSet<Obligation>(); + Map<Class<?>, Set<Obligation>> obligationMap = obligationMapContainer.get(); + if(obligationMap != null){ + for(Entry<Class<?>, Set<Obligation>> e: obligationMap.entrySet()){ + allObligations.addAll(e.getValue()); + } + } + return allObligations; + } + + /** + * Returns all obligations that the given ObligationHandler can handle, in the current thread of execution. + * + * @param oHandlerClass + * @return a <code>Set</code> of <code>Obligation</code> instances. + */ + @Override + public Set<Obligation> getHandlerObligations(Class<?> oHandlerClass) { + Set<Obligation> obligations = new HashSet<Obligation>(); + Map<Class<?>, Set<Obligation>> obligationMap = obligationMapContainer.get(); + if(obligationMap != null && obligationMap.get(oHandlerClass) != null){ + obligations.addAll(obligationMap.get(oHandlerClass)); + } + return obligations; + } + + + @Override + public Obligation getHandlerObligationById(Class<?> oHandlerClass, + String obligationId) { + Set<Obligation> obligations = getHandlerObligations(oHandlerClass); + if(obligations != null){ + for(Obligation obligation: obligations){ + if(obligation.getId().equals(obligationId)){ + return obligation; + } + } + } + return null; + } + + /** + * Clear all obligations in the current thread. + */ + void clear() { + obligationMapContainer.remove(); + } +}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html new file mode 100755 index 0000000..a9013f8 --- /dev/null +++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html
@@ -0,0 +1,1058 @@ +<html> +<body> +This package is the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html" +>OpenAz reference "implementation"</a> +of the OpenAz +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/package-summary.html" +>"PepApi interface package"</a>, +and therefore generally contains implementation classes +and only implementation-specific interfaces, also included is a +<a href="#tutorial">PepApi tutorial</a> that describes the approach +to building a PepApi implementation for a specific authorization +provider, as well as a 2nd <a href="#tutorialmappers">Mapper tutorial</a> +that describes the overall approach to writing mappers. +<p> +The goal of this package is twofold: +<ul> +<li>The primary goal is to provide a reference implementation of PepApi +that uses an AzApi-based authorization provider, which in this case is the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html" +>SimpleConcreteSunXacmlService</a>, +which is the SunXacml PDP wrapped in an +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/package-summary.html" +>implementation of the AzApi interface</a>. +<li>The secondary goal is to provide a reference framework, which other +providers can use as a model for implementation strategy of both AzApi +and non-AzApi based authorization providers. +</ul> + +In order to support the 2nd objective, the following is a high level +"tutorial" about the PepApi and this implementation of it. At present, +this tutorial is in preliminary form, however, even in the current +state, the information may prove useful to anyone who is interested in +developing an implementation of PepApi. + +<a name="tutorial"><H2>OpenAz PepApi Implementation Tutorial (v113)</H2></a> +<H3>Contents</H3> +<ul> +<li><a href="#highleveloverview">High Level Overview</a> +<li><a href="#sixlayerlist">List of Six OpenAz Layers</a> +<li><a href="#separationapispi">Separation of PepApi to application API +and provider SPI</a> +<li><a href="#highlevelsepapispi">High Level Overview API/SPI Separation</a> +<li><a href="#detailsepapispi">Detail list of API/SPI separated methods</a> +<li><a href="#pepapilayer">Appl client PepApi "API LAYER"</a> +<li><a href="#suggestedspiapproaches">Suggested approaches for XyzApi provider SPI implementation</a> +<li><a href="#pepapiseqmodel">PepApi Object Sequence Model</a> +<li><a href="#somediscussion">Some discussion items</a> +<ul> +<li><a href="#basicpattern">Basic Processing Pattern</a> +<li><a href="#highlowinterfacHigh Level and Low Level Interface Layers</a> +<li><a href="#basicpurpose">Basic Purpose of PepApi</a> +<li><a href="#standardpdps">Standard PDPs</a> +<li><a href="#xacmlreps">Representations of XACML</a> +<li><a href="#openazreleases">OpenAz Release Philosophy</a> +<li><a href="#thesixlayersdisc">The Six Layers</a> +<li><a href="#layer5disc">Layer 5: AzApi Impl</a> +<li><a href="#azapivssunxacml">AzApi vs SunXacml</a> +<li><a href="#canonicalform">Canonical Form</a> +</ul> +<li><a href="#tutorialmappers">Part II: Mappers Tutorial</a> +</ul> + +<a name="highleveloverview"> +<H3>High Level Overview: Appl, PepApi, AzApi, AzProvider</H3></a> +<p> +To understand the "top level" picture of what is currently provided +for implementations in the OpenAz project, we can identify six layers +of operational modules (including "interfaces" as a layer). Each layer +description starts with the identifier of a jar file in the OpenAz project +that contains an implementation of the functionality described in the layer. +<p> +In addition, experience with OpenAz has shown, the PepApi is best represented +as having 2 portions: an application-oriented API, and a provider-oriented SPI, +which will be noted in the following list and explained further below. +<p> +The PepApi provider is primarily concerned with implementing Layer 3 in the +list below. The other layers are generally provided either from the OpenAz site +(layers 2,4 for interfaces, layer 1 for test code, layers 5,6 for sample +AzApi impl and PDP), or from customer application environments (layer 1, +when customer is ready to implement PepApi client), or from PDP vendors +(layers 5 and 6). +<p> +<a name="sixlayerlist"><H4>List of the Six OpenAz Module Layers</H4></a> +<ul> +<li><b>Layer 1:</b> +"<top-of-project>\openaz\test\build\openliberty-openaz-test.jar" +<br> +This layer is implemented by a package that contains sample test programs, +and may be thought of as the "application layer", and generally only +uses the "API" portion of PepApi. +For example, test.TestStyles, demonstrates various usage scenarios +of PepApi. + +<li><b>Layer 2:</b> "<top-of-project> +"<top-of-project>\openaz\azapi\build\openliberty-openaz-azapi.jar" +<br> +This layer is implemented by a package that contains the actual +"PepApi interfaces" (API and SPI), and may be considered to be the second layer +of "modules", which, while not having any executable code, do control +what code can be compiled that is purported to "implement" the interface. +(Note: Even though the jar file contains "azapi" in the name, +it also contains the "pepapi".) + +<li><b>Layer 3:</b> +"<top-of-project>\openaz\pep\build\openliberty-openaz-pep.jar" +<br> +This package contains an example implementation of the PepApi, +and may be considered to be the "third layer" of OpenAz. +It also contains an implementation of an "AzApi client", i.e. a +module that uses AzApi directly to make authorization decisions. +As such, this layer may be considered to both implement a PepApi +provider, as well as, in this case, an AzApi client, or in the more +general, case a client to any request-response oriented +authorization provider. +<br> +In addition, this layer generally uses its own implementation of +the SPI portion of PepApi, which facilitates its implementation +of the API portion. + +<li><b>Layer 4:</b> +"<top-of-project>\openaz\azapi\build\openliberty-openaz-azapi.jar" +<br> +This package contains the actual "interfaces" that comprise the AzApi, +and, in the same sense as the layer 2 PepApi above, may be considered +to be a layer of modules that control compatibility with other +modules, esp in layer 5. (Note: this is the same jar file as used +by layer 2, i.e. it contains both sets of interfaces.) + +<li><b>Layer 5:</b> +"<top-of-project>\openaz\pdp\build\openliberty-openaz-pdp.jar" +<br> +This package contains an example implementation of AzApi, and may be +considered to be the "fifth layer" of OpenAz. Similarly to Layer 3, +this package also contains a client implementation, where the client +in this case is to the SunXacml PDP provider. + +<li><b>Layer 6:</b> +"<top-of-project>/pdp/lib/sunxacml.jar" +<br> +This jar file contains the SunXacml PDP impl, which may be considered +as the sixth layer of modules in OpenAz. +</ul> + + +<a name="separationapispi"> +<H3>Separation of PepApi into API and SPI parts.</H3></a> +This section first describes the approach at a high level, then +provides a detailed review of the complete PepApi interface to +designate the API and SPI parts of each PepApi interface. + +<a name="highlevelsepapispi"> +<H4>High level view of API/SPI separation</H4></a> +The first thing that is probably useful to recognize is that the PepApi +really consists of an application facing API plus an implementer's SPI +(Service Provider Interface). +If there is sufficient demand for a more formal separation, that will be +considered in the future. +<p> +The following is a high level view of the API/SPI separation: +<pre> + Consider the following functionality as being the main + part of each portion of the PepApi: + + APPL API LAYER: + + Use newPepRequest methods to build request + Use decide() method to make decision + Use allowed and next methods to look at results + Use getObligations, getObligationId, getStringValues to + look at obligations within each result + + PROVIDER SPI LAYER: + + Take Appl Api Request and + submit as Authorization Provider Request + + Take Authorization Provider Response objects and + process and return them as Appl Api Response objects + + + Summary of architecture: + + Appl Client Impl + PepApi Appl Client API + PepApi Provider SPI + PepApi Provider Impl + <AzProvider>API {AzProvider = Az | Xyz} + <AzProvider> Impl + + + Current AzApi strategy: + + +--------------------+ + | Appl client (impl) | <b><i>Layer 1</i></b> + +--------------------+ + | ^ + v | + +-----------------------------------+ + | PepApi appl client api (intf) | <b><i>Layer 2</i></b> + | - - - - - - - - - - - - - - - - - | + | PepApi provider api/spi (impl) | <b><i>Layer 3</i></b> + | includes use of PepApi spi | + | plus AzApi Client | + +-----------------------------------+ + | ^ + v | + +-----------------------------------+ + | AzApi client api (intf) | <b><i>Layer 4</i></b> + | - - - - - - - - - - - - - - - - - | + | AzApi provider (impl) | <b><i>Layer 5</i></b> + | plus SunXacml client | + +-----------------------------------+ + | ^ + v | + +----------------------------+ + | SunXacml provider (impl) | <b><i>Layer 6</i></b> + +----------------------------+ + + + + Suggested strategy for an Xyz provider: + + +--------------------+ + | Appl client (impl) | <b><i>Layer 1</i></b> + +--------------------+ + | ^ + v | + +-----------------------------------+ + | PepApi appl client api (intf) | <b><i>Layer 2</i></b> + | - - - - - - - - - - - - - - - - - | + | PepApi provider api/spi (impl) | <b><i>Layer 3</i></b> + | includes use of custom PepApi spi | + | plus XyzApi Client | + +-----------------------------------+ + | ^ + v | + +-----------------------------------+ + | <i>XyzApi client api</i> (intf) | <b><i>Layer 4</i></b> + | - - - - - - - - - - - - - - - - - | + | XyzApi provider (impl) | <b><i>Layers 5,6</i></b> + +-----------------------------------+ + + +</pre> +Note: because in the XyzApi provider case, the "standard" api is effectively +the XyzApi, itself, there is no need for the impl to act as a client to a +different interface, and so layers 5 and 6 are effectively consolidated to +a single logical layer. + +<a name="detailsepapispi"> +<H4>Detail list of API/SPI separated methods</H4></a> +The following list of interfaces and methods describe the API/SPI +separation. +<p>Note +<ul> +<li>There are only a few interfaces and methods involved with +the application-facing API, namely: +<ul> +<li>PepRequestFactory +<li>PepRequest +<li>PepResponse +<li>Obligation +</ul> +<li>All the PepApi interfaces are used and/or include methods that appear +in the SPI portion. +<li>Methods marked with "**" have AzApi-specific items in the interface +that need to be addressed by non-AzApi implementations. In most cases, +simply making the item null will satisfactorily address the situation for +a non-AzApi implementation, however, it is likely that a corresponding +element of the implementation will need to be used instead to fulfill +the functional capability. For example, a non-AzApi impl will have no +use for an AzRequestContext, however, it will likely have its own +RequestContext that will need to be considered as an alternative which +can be included in an extension class that has an additional provider-specific +method. +Note: items marked with "**" are followed by comment at end of line +with number referring to the suggested approaches for these issues +described at the end of the SPI detail section. +</ul> + +<pre> + ------------------------------------------------------------------- +</pre> +<a name="pepapilayer"><H4> APPL CLIENT PepApi "API LAYER":</H4></a> +<pre> +<a name="apipepreqfact"><H5>Interface PepRequestFactory</H5></a> + PepRequest newPepRequest( + Object subjectObj, Object actionObj, + Object resourceObj, Object environmentObj) + PepRequest newPepRequest( + Object subjectObj, Object actionResourceObject, + Object environmentObj) + PepRequest newPepRequest( + String subjectName, String actionId, + String resourceId) + + PepRequest newBulkPepRequest( + Object subjectObj, List actionObjects, + List resourceObjects, Object environmentObj) + PepRequest newBulkPepRequest( + Object subjectObj, List actionResourceObjects, + Object environmentObj) + + PepRequest newQueryPepRequest( + Object subjectObj, Object environmentObj, + String scope, PepRequestQueryType queryType) + +<a name="apipepreq"><H5>Interface PepRequest</H5></a> + PepResponse decide() + +<a name="apipeprsp"><H5>Interface PepResponse</H5></a> + boolean allowed() + Object getAction() + Object getResource() + Map<String,Obligation> getObligations() + boolean next() + +<a name="apiobligation"><H5>Interface Obligation</H5></a> + String getObligationId() + Map<String,String> getStringValues() + + ------------------------------------------------------------------- +</pre> +<a name="pepspilayer"><H4> PROVIDER PepApi "SPI LAYER":</H4></a> +<pre> +<a name="spipepreqfact"><H5>Interface PepRequestFactory</H5></a> + ** AzService getAzService() // (#1) return null for non-AzApi + + String getContainerName() + String getProviderClassName() + + RequestAttributesFactory<T> getRequestAttributesFactory(T t) + <T extends Enum<T> & AzCategoryId> + PepResponseFactory getResponseFactory() + + DecisionHandler getDecisionHandler() + List<PostDecisionHandler> getPostDecisionHandlers() + List<PreDecisionHandler> getPreDecisionHandlers() + +<a name="spipepreq"><H5>Interface PepRequest</H5></a> + ** AzRequestContext getAzRequestContext() // return null for non-AzApi + + PepRequestFactory getPepRequestFactory() + + void setAccessSubject(Object subjectObject) + void setResourceAction(Object resource, Object action) + void setEnvironment(Object envObject) + void setBulkResourceActions(List resourceObjects, List actionObjects) + + PepRequestOperation getOperation() + ** Object getActionObject(AzResourceActionAssociation azRaa) // (#3) + ** Object getResourceObject(AzResourceActionAssociation azRaa) // (#3) + + void setScope(String scope) + String getScope() + + void setQueryReturnAllowed(boolean queryReturnAllowed) + boolean isQueryForAllowedResults() + +<a name="spijavaobjmap"><H5>Interface JavaObjectMapper:</H5></a> + Set<Class> getSupportedClasses() + + boolean canMapObject(Object obj) + + <T extends Enum<T> & AzCategoryId> + RequestAttributes<T> map( + Object javaObject, + RequestAttributes<T> azWrapperObject) + +<a name="spireqattrfact"> +<H5>Interface RequestAttributesFactory<T extends Enum<T> & AzCategoryId></H5></a> + RequestAttributes<T> createObject(PepRequest ctx) + void setMappers(List<JavaObjectMapper> mappers) + List<JavaObjectMapper> getMappers() + Set<Class> getSupportedClasses() + +<a name="spiattr"> +<H5>Interface Attributes<T extends Enum<T> & AzCategoryId></H5></a> + ** AzEntity<T> getAzEntity() // (#1) return null for non-AzApi + +<a name="spireqattr"> +<H5>Interface RequestAttributes<T extends Enum<T> & AzCategoryId> + extends Attributes<T></H5></a> + PepRequest getPepRequest() + + void setAttribute(String name, Boolean value) + void setAttribute(String name, Date date) + void setAttribute(String name, Integer value) + void setAttribute(String name, String value) + +<a name="spidechnd"><H5>Interface DecisionHandler</H5></a> + PepResponse decide(PepRequest request) +<a name="spipredechnd"><H5>Interface PreDecisionHandler</H5></a> + void preDecide(PepRequest request) +<a name="spipostdechnd"><H5>Interface PostDecisionHandler</H5></a> + void postDecide(PepRequest request, PepResponse response) + +<a name="spipepreqrspfact"><H5>Interface PepResponseFactory:</H5></a> + ** PepResponse createPepResponse( + AzResponseContext responseContext, // (#1) pass null for non-AzApi + PepRequest pepRequest, + PepRequestOperation operation) + + ** PepResponse createPepResponse( + Set<AzResourceActionAssociation> actionResourceAssociations, // (#3) + PepRequest pepRequest, + boolean queryAllowed) + + ObligationFactory getObligationFactory() + + PepResponseBehavior getMissingAttributeBehavior() + PepResponseBehavior getNotApplicableBehavior() + PepResponseBehavior getProcessingErrorBehavior() + PepResponseBehavior getSyntaxErrorBehavior() + + void setMissingAttributeBehavior( + PepResponseBehavior missingAttributeBehavior) + void setNotApplicableBehavior( + PepResponseBehavior notApplicableBehavior) + void setProcessingErrorBehavior( + PepResponseBehavior processingErrorBehavior) + void setSyntaxErrorBehavior( + PepResponseBehavior syntaxErrorBehavior) + +<a name="spipeprsp"><H5>Interface PepResponse</H5></a> + ** AzResponseContext getAzResponseContext() // (#1) return null for non-AzApi + +<a name="spioblfact"><H5>Interface ObligationFactory</H5></a> + ** Obligation createObject(AzEntity<AzCategoryIdObligation> entity) // (#2) pass null for non-AzApi + +<a name="spiobl"><H5>Interface Obligation + extends ResponseAttributes<AzCategoryIdObligation></H5></a> + +<a name="spirspattrfact"> +<H5>Interface ResponseAttributesFactory<T extends Enum<T> & AzCategoryId></H5></a> + ** ResponseAttributes<T> createObject(AzEntity<T> entity) // (#2) pass null for non-AzApi + +<a name="spirspattr"> +<H5>Interface ResponseAttributes<T extends Enum<T> & AzCategoryId> + extends Attributes<T></H5></a> + + ------------------------------------------------------------------- +</pre> +<a name="suggestedspiapproaches"> +<H4>Suggested approaches for XyzApi provider SPI implementation</H4></a> +<pre> +Note: these suggestions presume the Xyz provider is following the +code structure in the org.openliberty.openaz.pep impl package +and that the approach is to substitute Xyz request and response objects, +and Xyz entity attribute collections for those provided by AzApi. +The basic idea would be to have a parallel impl, for example: +org.openliberty.openaz.xyz, with basically the same set of classes, +but with some of the following modifications considered. + + 1. return null for getAz<object>() in: + PepRequestFactory.getAzService() + PepRequest.getAzRequestContext() + Attributes<T>.getAzEntity() + PepResponse.getAzResponseContext() + + 2. Pass null for az<object> parameter in: + PepResponseFactory.createPepResponse(azResponseContext, ...) + ResponseAttributesFactory.createObject(azEntity) + ObligationFactory.createObject(azEntity) + + 3. Consider extending AzResourceActionAssociation as + XyzResourceActionAssociation and use in the following: + + PepRequest.getActionObject(AzResourceActionAssociation azRaa) + PepRequest.getResourceObject(AzResourceActionAssociation azRaa) + + PepResponseFactory.createPepResponse( + Set<AzResourceActionAssociation> azRaas, + PepRequest pepRequest, + boolean queryAllowed) + + AzResourceActionAssociation javadoc is here: + http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzResourceActionAssociation.html + + Within XyzResourceActionAssociation extension return null for the + following AzApi-dependent methods: + + AzResourceActionAssociation.getAzAction() + AzResourceActionAssociation.getAzResource() + AzResourceActionAssociation.getAzResourceActionAssociationId() + + Add new XyzResourceActionAssociation method to return + action and resource objects: + + XyzObject getXyzAction() + XyzObject getXyzResource() + + Then the XyzResourceActionAssociation object can be used + for correlation based on the XyzObject references for + action and resource in the XyzPepRequestImpl that + implement PepRequest, i.e. + + PepRequest.getActionObject(XyzResourceActionAssociation xyzRaa) + PepRequest.getResourceObject(XyzResourceActionAssociation xyzRaa) + + Similarly for creating a collection of return objects + in response to a query, the XyzPepResponseFactoryImpl + should be able to pass: + + PepResponseFactory.createPepResponse( + Set<XyzResourceActionAssociation> xyzRaas, + PepRequest pepRequest, + boolean queryAllowed) + + although one needs to check if generics will allow this pass + of a Set of subclasses of the class for which the interface + is defined. + +</pre> +<a name="pepapiseqmodel"><H3>PepApi Object sequence model</H3></a> +The following section contains a quasi-sequence diagram that shows the +relations between the components of the PepApi in approximate order of +their invocation at runtime. +<pre> + + +------------------------------------------+ + | PepRequestFactory | + | PepReqFactImpl(azSvc) // impl azSvc set | + | pr = newPepRequest | + | | (sObj,aObj,rObj,eObj) | + | | newPEPRequest(op) | + | | azReqCtx = azSvc.createAzReqCtx() | + | | new PepReqImpl(azReqCtx, this, op) | + | | setAccessSubject(sObj) | + +---|--------------------------------------+ + | + V + +---------------------------------------------------------------+ + | PepRequest | + | PepReqImpl(azReqCtx, this, op) // set values from params | + | setAccessSubject(subjObj) | + | createAccessSubject(subjObj) //'Subject' implies <T> | + | subjFact = getPepReqFact.getReqAttrFact(catId<T>) | + | +<-- subjInit = subjFact.createObj(this) | + | | subjMapd = mapJavObject(subjObj, subjInit, subjFact) | + | | mapJavaObject(subjObj, subjInit, subjFact) | + | +<---- mapper = subjFact.getMappers().next() | + | | | mapper.map(subjObj, subjInit) | + |+<--- decide() | + +|-|-|----------------------------------------------------------+ + | | | + | | V + | | +-----------------------------------------------------------+ + | | | SubjectFactory | + | | | createObject(pr) | + | | | azReqCtx = pr.getAzReqCtx() | + | | | azSubjInit = azReqCtx.createAzEntity(catIdSubj) | + | | | azReqCtx.addAzEntity(azSubjInit) | + | | | +<- return new Subject(azSubjInit, pr, this) | + | | +-|---------------------------------------------------------+ + | | | + | | V + | | +-----------------------------------------------------------+ + | | | Subject | + | | | Subject(azSubjInit, pr, subjFact) | + | | | +<- super[RequestAttributes](azSubjInit, pr, subjFact) | + | | +-|---------------------------------------------------------+ + | | | + | | V + | | +-----------------------------------------------------------+ + | | | RequestAttributes | + | | | RequestAttributes(azSubjInit, pr, subjFact) | + | | | set this.pr, this.subjFact | + | | | +<- super[Attributes](azSubjInit) | + | | +-|---------------------------------------------------------+ + | | | + | | V + | | +-----------------------------------------------------------+ + | | | Attributes | + | | | Attributes(azSubjInit) | + | | | this.azEntity = azSubjInit | + | | +-----------------------------------------------------------+ + | | + | V + | +-----------------------------------------------------------+ + | | JavaObjectMapper | + | | map(subjObj, reqAttrSubjInit) | + | | convertObj(subjObj, reqAttrSubjInit) | + | | attrId = getVocab(subjObj) | + | | +<- reqAttrSubjInit.setAttribute(attrId, subjObj) | + | +---|-------------------------------------------------------+ + | | + | V + | +-----------------------------------------------------------+ + | | RequestAttributes | + | | setAttribute(attrId, subjObj) | + | | azEntity.createAzAttribute(issuer, attrId, | + | | azEntity.createAzAttributeValue(azDataTyp, subjObj) | + | +-----------------------------------------------------------+ + | + V + +----------------------------------------------------------+ + | DecisionHandler | + | decide(pepReq) | + | azRspCtx = azSvc.decide(pepReq.getAzReqCtx() | + | +<- pepRspFact = pepReq.getPepReqFact.getRspFact() | + | | pepRsp = pepRspFact.createPepRsp(azRspCtx,pepReq,op) | | + | | return pepRsp | + +-|--------------------------------------------------------+ + | + V + +----------------------------------------------------------+ + | PepResponseFactory | + | createPepRsp(azRspCtx,pepReq,op) | + | +<- pepRsp = new PepRspImpl(azRspCtx, pepReq, this, op) | + | | return pepRsp | + +-|--------------------------------------------------------+ + | + V + +----------------------------------------------------------+ + | PepResponse | + | PepRspImpl(azRspCtx,pepReq,pepRspFact,op) | + | set this.azRspCtx,this.pepReq,this.pepRspFact,this.op | + | this.azResultIterator = azRspCtx.getRslts.iterator() | + | allowed() | + | next() // point to next azResult | + | curAzResult = azResultIterator.next() | + | getResource(), getAction() | + | azRaa = this.getAzResourceActionAssociation() | + | resObj = this.getPepReq.getResourceObject(azRaa) | + | return resObj | + | getObligations() | + | curAzObls = curAzResult.getAzObligations() | + | curAzObl = curAzObls.next() | + | oblFact = this.getRspFact.getOblFact() | + | Obligation pepObl = oblFact.createObject(curAzObl) | + +-|--------------------------------------------------------+ + | + V + +----------------------------------------------------------+ + | ObligationFactory | + | createObject(azObligation) | + | +<- return new Obligation(azObligation) | + +----------------------------------------------------------+ + | + V + +-----------------------------------------------------------+ + | Obligation | + | Obligation(azObligaion) | + | +<- super[ResponseAttributes](azObligation) | + +-|---------------------------------------------------------+ + | + V + +-----------------------------------------------------------+ + | ResponseAttributes | + | ResponseAttributes(azObligation) | + | +<- super[Attributes](azObligation) | + +-|---------------------------------------------------------+ + | + V + +-----------------------------------------------------------+ + | Attributes | + | Attributes(azObligation) | + | this.azEntity = azObligation | + +-----------------------------------------------------------+ + + +</pre> + +<a name="somediscussion"><h3>Some discussion items</h3></a> + +<a name="basicpattern"><h4>Basic Processing Pattern</h4></a> +The basic pattern is that the "container" of applications provides +both checking requests before the application receives them, and +checking requests in the process of application execution, where +it is necessary to determine if the current user has sufficient +authorization established to continue the current operation. +<p> + +<a name="highlowinterfaces"> +<h4>High Level and Low Level Interface Layers</h4></a> +PepApi is a "high level interface" intended to be totally flexible +in terms of the applications and containers that can use it, and +to also be "easy to use", comparable to existing platform-specific +authorization models, such as J2SE checkPermission and WebLogic +isAccessAllowed. +<p> +By contrast, AzApi is a "low level interface" intended to provide +a Java binding to the more general platform independent XACML +authorization model, which provides a general interface consisting +of a collection of collections of "canonical" Attributes that contain +both Attribute metadata and AttributeValues. +<p> + +<a name="basicpurpose"><h4>Basic Purpose of PepApi</h4></a> +Therefore, the intended purpose of a PepApi Impl, for example, +this package ({@link org.openliberty.openaz.pep}), is +to provide a "mapping" from the simple, application-friendly, PepApi +that the applications (and containers) use, to the more complex +AzApi, that the container would then typically use +to submit requests to standard XACML PDPs. +<p> + +<a name="standardpdps"><h4>Standard PDPs</h4></a> +"Standard XACML PDPs" are accessed using the XACML +Request/Response protocol, which is described in the XACML +specifications using XML to represent the details. However, +implementations are not required to use XML, but they are +required to maintain the semantics of XACML, which are normatively +defined in the specifications using the XML representation. +<p> + +<a name="xacmlreps"><h4>Representations of XACML</h4></a> +Furthermore, the XACML specifications do not specify what +representation is required in the PEP-PDP connection, so it is +possible that one end is expecting to use XML and the other +end is expecting to use some other serialization format of the +same information. Therefore, interoperability is somewhat +dependent on the "bindings" that XACML PEP and XACML PDPs have +provided for support. In the absence of a match, it would be +up to the vendors and/or enterprise system developers to either +provide a translation module or to simply select another +product that would be compatible. +<p> +It is not a goal of either the XACML Technical Committee nor +of the OpenAz project to attempt to resolve this issue, except +on an as-needed basis to serve the purposes of implementations +that are used within or want to integrate with the OpenAz Project. +<p> +So, for example, the initial release of OpenAz has, effectively, +two "providers" for AzApi, the top level classes of which are: +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteDummyService.html"> +<b>SimpleConcreteDummyService</b></a> and +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html"> +<b>SimpleConcreteSunXacmlService</b></a>. +The former, the "dummy service", +simply gives canned responses, and should be regarded as no more than +a test tool, however, its existence as an independent "provider" may +be useful for some types of demos. +<p> + +<a name="openazreleases"><h4>OpenAz Release Philosophy</h4></a> +To understand the working example in the "initial release of OpenAz" +(which is the current release, which should be considered to be +using the interfaces, i.e. AzApi and PepApi, in their "final form". +The "final form" is "final" in the sense that until there is a critical +mass (for example 3 implementations, including the current ref impl), +fixes to "bugs" found in either API should be considered fair game. +However, any "functionality" above and beyond what is currently +represented as the functionality of those interfaces, should be +considered candidates for a "second" or "next" release.) + +<a name="thesixlayersdisc"><H4>The Six Layers</H4></a> +One may think of the 6 layers as kind of a "stepladder" of mapping +the Objects from the local form within the application (Layer 1) to the +canonical form within AzApi (Layer 5). +<p> + +<a name="layer5disc"><H5>Layer 5: AzApi Impl</H5></a> +Then, from the AzApi impl (layer 5) the canonical form objects may +be mapped a 2nd time into the local object form required by the +XACML PDP. + +From the perspective of the six layers, we can examine some of the +possible "usage scenarios" for OpenAz. It turns out that there +really are two major pieces of standardization that OpenAz facilitates: + +<ul> +<li> First is the upper level "PepApi" (layer two), which provides +a standard Java interface to application environments, regardless +of the specific Objects the applications pass to PepApi. + +<ul> +<li>Note: It is "standard" in the sense that +applications do not have to be aware that +what is done with the Objects when they are passed to PepApi. +is that the Objects are "mapped" by the +layer 3 PepApi Impl to be used as input to the layer 4 AzApi +interface. +</ul> + +<li> Second is the lower level "AzApi" (layer four), which provides +a standard Java interface to XACML PDPs. + +<ul> +<li>Note: Again that the layer 5 AzApi Impl needs to generally +"map" the AzApi objects to those of the XACML Impl. +</ul> +</ul> + +The reason that layer 5 may need to do mapping is the existing +XACML implementations, in general, will not yet be using AzApi, +and so the most effective path to use AzApi is to implement a +mapping to the current objects used by the XACML PDP. +<ul> +<li> In fact, this is exactly what is done in the OpenAz layer five, +where the AzApi top level impl, +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html"> +<b>SimpleConcreteSunXacmlService</b></a>, +wraps the SunXacml PDP, which has its own interface, +<ul> +<li> <a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/PDP.html#evaluate(com.sun.xacml.ctx.RequestCtx)"> +ResponseCtx response = PDP.evaluate(RequestCtx request)</a> +</ul> +</ul> + +<a name="azapivssunxacml"><H4>AzApi vs SunXacml</H4></a> + +<p> +While the SunXacml interface is "similar" to the AzApi interface, +particularly the AzApi "decide()" call +<p> +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzService.html#decide(org.openliberty.openaz.azapi.AzRequestContext)"> +<b>AzService.decide</b></a> +( +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzRequestContext.html"> +<b>AzRequestContext</b></a> +}; + +<ul> +<li> AzResponseContext azRspCtx = AzService.decide(AzRequestContext azReqCtx) +</ul> + +<p> +there is still a "mapping" required to go from the AzApi implementation +objects to the SunXacml implementation objects. i.e. one must map the +AzApi +<a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/ctx/RequestCtx.html"> +<b>RequestCtx</b></a> +to the SunXacml and on the return, map the SunXacml +<a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/ctx/ResponseCtx.html"> +<b>ResponseCtx</b></a> to the AzApi +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzResponseContext.html"> +<b>AzResponseContext</b></a> + + +<a name="canonicalform"><H4>Canonical Form</H4></a> +Given the above description, one may ask why map to the canonical form +at all? Why not have layer 3 map directly to the local form of the +PDP, and therefore skip layers 4 and 5? + +<ul> +<li>In fact, the architecture is designed so that is a perfectly +legitimate strategy to take. However, the major drawback to this strategy +is that if the enterprise has a mix of PDPs from multiple vendors, +then configuration may begin to become complex, as one must keep track +of which vendor's PDP is servicing which application, so as to ensure +that the proper mappers are in place to map from the application +objects to the specific PDP vendor objects. + +<li>From a purely technical engineering for performance perspective, +it may appear that the benefit of an intermediate canonical form in +the runtime path, as kind of a standard "clearinghouse" is not +compelling enough on its own to justify the effort to achieve it. + +<li>However, there are additional considerations. Security Policy +is an all-encompassing concern for an enterprise that generally +applies to every activity conducted by the enterprise, whether +for concern of privacy, risk-avoidance, compliance, integrity, etc., +there needs to be a way to integrate security Policy to any activity. + +<li>In order to effectively manage security Policy, there needs to +be standard representations of the information in those Policies, +as well as a method to relate that information to the corresponding +representation of information in the enterprise that is collected +and assembled to a Request to be evaluated by Policy. +</ul> + +<a name="tutorialmappers"><H2>OpenAz Mappers Writing Tutorial (v114)</H2></a> +<H3>Contents</H3> +<ul> +<li><a href="#highleveloverviewmappers">High Level Overview: Mappers</a> +<li><a href="#structuremappers">Mapper structure</a> +<li><a href="#methodimplmappers">Mapper method implementation</a> +<li><a href="#permissionmappers">Permission Mapper</a> + +</ul> +</ul> + +<a name="highleveloverviewmappers"> +<H3>High Level Overview: Mappers</H3></a> +At the most fundamental level, the philosophy of OpenAz and PepApi/AzApi +that the process of authorization can be abstracted as Policy defined in +terms of "entities" represented as collections of "attributes", where the +entities and attributes can be represented by a common standard such +as XACML. Therefore, in theory, all that is required at runtime when an +authorization check is required is to look at the entities involved and +evaluate the Policy to determine if the attributes of the entities meet +the Policy criteria for granting access. +<p> +The "entities" involved in a typical access check include: +<ul> +<li>A User Entity, or "Subject", where the Subject is the entity that +is requesting access. +<li>A Resource Entity, where the Resource is the entity to which the +User Entity is requesting access. +<li>An Action Entity, where the action specifies the explicit operations +that the User Entity is requesting to apply to the Resource Entity. +<li>An optional Environment Entity, where the "environment" is generally +to be considered system conditions, such as time of day, that may factor +into the decision making process. All such attributes are generally +collected in an Environment Entity collection of Attributes. +</li> +</ul> +In the XACML Specification, all attributes are of a specific XACML +DataType, which means, as described in XACML Specification Section A.2: +<pre> + A.2. Data-types + + Although XML instances represent all data-types as strings, + an XACML PDP must reason about types of data that, while they + have string representations, are not just strings. + + Types such as Boolean, integer and double MUST be converted: + + - from their XML string representations + - to values that can be compared with values in their domain + of discourse, such as numbers. +</pre> +(Note: the XACML Specification uses both the term "data-type" and the +term "DataType", where the former refers to a generic notion of a +"data type", but within the XACML context, thus also implicitly +referring to the latter term, "DataType", which is the name of the +"XML attribute" used to specify the specific instance of XACML +data-type to be used in conjunction with the XACML Attribute element +that contains both the DataType attribute and AttributeValue element. +OpenAz will not make such a distinction and simply use the term "DataType" +or "datatype" interchangeably to in any of these contexts.) +<p> +In OpenAz, the "lower level" AzApi contains a separate interface for each +of the Xacml DataTypes and a specific Java Object Type is also associated +with each Xacml DataType. The collection of +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzAttributeValue.html" +>AzAttributeValue subinterfaces</a> +along with the associated list of "Known Implementing Classes" that reference +the reference impl implementations of these interfaces, effectively can +be considered the specification of the "AzApi Java Language Binding". +<p> +As such, in order to make an AzRequest to a XACML PDP, one needs to +collect the attributes associated with each entity (where the entities +are distinguished by +<a href ="">AzCategoryId</a> and submit the Java objects containing the +attribute values thru these standard interfaces. +<p> +The purpose of the lower level AzApi interface is to provide a +well-structured framework that has a standard representation of all +information that may ultimately prove necessary to submit a complete +authorization request. +<p> +However, in general, information in the runtime environment is not +in any particular standard form, so, in order to enable minimal impact +on existing runtime development practices, the PepApi was developed to +enable applications to submit whatever information objects are preferred +to be used in a particular application environment. +<p> +In order to make this strategy work the PepApi implementation needs to +"map" the information in the objects supplied by the application from +that environment-specific form to the AzApi standard form, which will +then enable seamless submission to a XACML PDP. +<p> +However, as described in the first tutorial above, the same strategy +will work with almost any PDP. This second tutorial will explain how +the reference impl mappers are designed, and it is expected that the +same design strategy can be applied to mapping to other PDP APIs, +as well, where instead of mapping application objects to azapi objects, +the mapping would be to the non-Xacml-PDP-specific objects. +<H3>How to build a Mapper</H3> +Probably the most straight-forward way to explain how to build a mapper +is to explain how the existing mappers provided in PepApi work. +<a name="structuremappers"><h4>Mapper structure</h4></a> +Looking at the javadoc for +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaObjectMapper.html" +>org.openliberty.openaz.pep.SimpleJavaObjectMapper</a> as a +typical example, we can make the following observations about its structure: +<ul> +<li>It implements the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/JavaObjectMapper.html" +>org.openliberty.openaz.azapi.pep.JavaObjectMapper</a> +interface. +<li>The javadoc says that it supports 3 objects: String, Date, and HashMap, +and that it maps those objects into RequestAttributes. +<li>The 3 JavaObjectMapper interface methods: canMapObject(), map(), and +getSupportedObjects() appear in the Method Summary for the +SimpleJavaObjectMapper. +<li>There are additional methods used within the implementation: +convertDate, convertString, convertMap. These methods do the actual +conversion of the application input object to the AzAttribute structures. +</ul> +<a name="methodimplmappers"><h4>Mapper method implementation</h4></a> +<h5>getSupportedObjects</h5> +Implementation of getSupportedObjects() in SimpleJavaObjectMapper is +to simply create a set containing a class object for each class that +the mapper supports. This is simply a hard-coded set which can be used +when configuring mappers to preliminarily determine object types supported. +<p> +For the SimpleJavaObjectMapper, this consists of a list of 3 class types: +String, Date, HashMap. +<h5>canMapObject</h5> +Implementation of canMapObject(Object obj) should be straight-forward. +In SimpleJavaObjectMapper there is simply a sequence of "if statements" +that use "instanceof" to test whether the obj parameter is an "instanceof" +one of the supported object classes. If there is a match then true +is returned, otherwise false is returned. +<h5>map</h5> +Implementation of the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/JavaObjectMapper.html#map(java.lang.Object,%20org.openliberty.openaz.azapi.pep.RequestAttributes)" +>map(Object obj, RequestAttributes<T> reqAttrs)</a> method is the +only place where there might be some non-trivial complexity to work thru. +<p> +In SimpleJavaObjectMapper, map(obj,reqAttrs) dispatches to a conversion +method for one of the supported object types by going thru a similar +sequence of "if instanceof" test and dispatching when a matching object +class is found. +<p> +Within the conversion methods, the first thing considered is the AzCategoryId +of the RequestAttributes target object, which for AzApi is an AzEntity +AzAttribute collection. When the Mapper.map method is invoked, the caller +needs to determine which AzCategoryId to pass to the method as the +generic parameter T of the RequestAttributes<T> object being passed. +<p> +Generally, this will be implicitly determined by the entity for which +the object being converted is intended. In the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/PepRequestFactory.html" +>PepApi PepRequestFactory.newPepRequest(*) methods</a>, +the objects passed are in an order that determines whether the object is +to be considered a Subject, Action, Resource, or Environment as +described in the signature to the newPepRequest methods. +<p> +One can get a rough idea of how this is implemented by following the +<a href="#pepapiseqmodel">PepApi sequence model</a> in the first tutorial +above. In particular, starting with PepRequestFactoryImpl call to +setAccessSubject(sObj), one can follow the diagram logic down to +the RequestAttributes.setAttribute(attrId, subjObj) method where the +Mapper has been invoked and the convertObject method within the Mapper +is setting the attribute on the AzEntity. +<a name="permissionmappers"><H4>Permission Mapper</H4></a> +A slightly more interesting case is the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaPermissionMapper.html">SimpleJavaPermissionMapper</a> +<p> +As described in the javadoc for +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaPermissionMapper.html#map(java.lang.Object,%20org.openliberty.openaz.azapi.pep.RequestAttributes)" +>SimpleJavaPermissionMapper.map()</a> +a Permission or any subclass of Permission can be processed and effectively +serialized into 3 String parameters, where the Permission subclass is assumed +to be a "resource-type", the name parameter is assumed to be the "resource-id", +and the action is assumed to be the "action-id", where resource-id and action-id +are as defined in Xacml, and resource-type is an OpenAz identifier used to +name a resource type. +<p> +Therefore these 3 parameters can be passed to the Xacml PDP and generally +policies will contain regular expression conditions on resource name in order +to create scopes of resources and actions subject to the policy. Some examples +demonstrating this technique are included in the test program +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/test/TestStyles.html" +>TestStyles</a> +where the code and javadoc of the testStyle* methods describe some of +the test cases, and the +<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/src/test/" +>code from the project</a> + may be examined. +</body> +</html> \ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java new file mode 100755 index 0000000..f2173a8 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java
@@ -0,0 +1,81 @@ +package org.openliberty.openaz.pepapi.std.test; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openliberty.openaz.pepapi.*; +import org.openliberty.openaz.pepapi.std.StdPepAgentFactory; + +import java.util.ArrayList; +import java.util.List; + + +public class TestAPI { + + private PepAgentFactory pepAgentFactory; + + @Before + public void setup() { + pepAgentFactory = new StdPepAgentFactory("/properties/testapi.xacml.properties"); + } + + + /** + * + */ + @Test + public void testPepAgent() { + Assert.assertNotNull(getPepAgent()); + } + + + /** + * + */ + @Test + public void testPermit(){ + PepResponse response = getPepAgent().simpleDecide("Julius Hibbert", + "read", "http://medico.com/record/patient/BartSimpson"); + Assert.assertNotNull(response); + Assert.assertEquals(true, response.allowed()); + } + + + /** + * + */ + @Test + public void testNotApplicable(){ + PepResponse response = getPepAgent().simpleDecide("Julius Hibbert", + "read","http://medico.com/record/patient/JohnSmith"); + Assert.assertNotNull(response); + Assert.assertEquals(false, response.allowed()); + } + + + /** + * + */ + @Test + public void testMultiRequest() { + List<Action> actions = new ArrayList<Action>(); + actions.add(Action.newInstance("read")); + actions.add(Action.newInstance("write")); + actions.add(Action.newInstance("update")); + actions.add(Action.newInstance("delete")); + + List<PepResponse> responses = getPepAgent().bulkDecide(actions, + Subject.newInstance("Julius Hibbert"), + Resource.newInstance("http://medico.com/record/patient/BartSimpson")); + Assert.assertNotNull(responses); + Assert.assertEquals(true, responses.get(0).allowed()); + Assert.assertEquals(true, responses.get(1).allowed()); + Assert.assertEquals(false, responses.get(2).allowed()); + Assert.assertEquals(false, responses.get(3).allowed()); + + } + + public PepAgent getPepAgent() { + return pepAgentFactory.getPepAgent(); + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java new file mode 100755 index 0000000..90cef8e --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java
@@ -0,0 +1,98 @@ +package org.openliberty.openaz.pepapi.std.test; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openliberty.openaz.pepapi.*; +import org.openliberty.openaz.pepapi.std.StdPepAgentFactory; + +import java.util.ArrayList; +import java.util.List; + + +public class TestAPIWithPIP { + + private static final Log log = LogFactory.getLog(TestAPIWithPIP.class); + + private PepAgentFactory pepAgentFactory; + + @Before + public void setup() { + pepAgentFactory = new StdPepAgentFactory("xacml.properties"); + } + + + /** + * + */ + @Ignore + @Test + public void testPepAgent() { + Assert.assertNotNull(getPepAgent()); + } + + + /** + * + */ + @Ignore + @Test + public void testPermit() { + PepResponse response = getPepAgent() + .simpleDecide("John Doe", + "read", + "http://medico.com/record/patient/BartSimpson"); + Assert.assertNotNull(response); + Assert.assertEquals(true, response.allowed()); + } + + + /** + * + */ + @Ignore + @Test + public void testNotApplicable() { + PepResponse response = getPepAgent() + .simpleDecide("John Smith", + "read", + "http://medico.com/record/patient/BartSimpson"); + Assert.assertNotNull(response); + Assert.assertEquals(false, response.allowed()); + } + + + /** + * + */ + @Ignore + @Test + public void testMultiRequest() { + List<Action> actions = new ArrayList<Action>(); + actions.add(Action.newInstance("read")); + actions.add(Action.newInstance("update")); + actions.add(Action.newInstance("write")); + actions.add(Action.newInstance("modify")); + + Resource resource = Resource.newInstance("http://medico.com/record/patient/BartSimpson"); + Subject subject = Subject.newInstance("John Doe"); + + List<PepResponse> responses = getPepAgent().bulkDecide(actions, resource, subject); + Assert.assertNotNull(responses); + Assert.assertEquals(actions.size(), responses.size()); + Assert.assertEquals(true, responses.get(0).allowed()); + Assert.assertEquals(false, responses.get(1).allowed()); + Assert.assertEquals(true, responses.get(2).allowed()); + Assert.assertEquals(false, responses.get(3).allowed()); + for(PepResponse response: responses) { + log.debug(response.getAssociation()); + } + } + + public PepAgent getPepAgent() { + return pepAgentFactory.getPepAgent(); + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java new file mode 100755 index 0000000..830d28e --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java
@@ -0,0 +1,72 @@ +package org.openliberty.openaz.pepapi.std.test; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openliberty.openaz.pepapi.*; +import org.openliberty.openaz.pepapi.std.StdPepAgentFactory; +import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedCatchAllObligationHandler; +import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedFilteringObligationHandler; +import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedRedactionObligationHandler; + + +public class TestAnnotatedHandlerRegistration { + + @SuppressWarnings("unused") + private static Log log = LogFactory.getLog(TestAnnotatedHandlerRegistration.class); + + private PepAgentFactory pepAgentFactory; + + //TODO: Need to wire + private AnnotatedFilteringObligationHandler filterHandler; + + //TODO: Need to wire + private AnnotatedRedactionObligationHandler redactionHandler; + + //TODO: Need to wire + private AnnotatedCatchAllObligationHandler catchAllHandler; + + + @Before + public void setup() { + pepAgentFactory = new StdPepAgentFactory("xacml.properties"); + } + + + + /** + * + */ + @Ignore + @Test + public void testPepAgent() { + Assert.assertNotNull(getPepAgent()); + } + + + + /** + * + */ + @Ignore + @Test + public void testRegistration() { + Subject subject = Subject.newInstance("John Smith"); + subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:age", "45"); + PepResponse response = getPepAgent().decide(subject, Action.newInstance("view"), + Resource.newInstance("resource1")); + Assert.assertNotNull(response); + Assert.assertEquals(true, response.allowed()); + filterHandler.enforce(); + redactionHandler.enforce(); + catchAllHandler.enforce(); + } + + public PepAgent getPepAgent() { + return pepAgentFactory.getPepAgent(); + } + +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java new file mode 100755 index 0000000..40a39da --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java
@@ -0,0 +1,85 @@ +package org.openliberty.openaz.pepapi.std.test; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openliberty.openaz.pepapi.*; +import org.openliberty.openaz.pepapi.std.StdPepAgentFactory; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + + +public class TestDataTypes { + + private PepAgentFactory pepAgentFactory; + + @Before + public void setup() { + /*System.setProperty("xacml.properties" , + getClass().getClassLoader().getResource("properties/testdatatypes.xacml.properties").getPath());*/ + pepAgentFactory = new StdPepAgentFactory("/properties/testdatatypes.xacml.properties"); + } + + + /** + * + */ + @Test + public void testPepAgent() { + Assert.assertNotNull(getPepAgent()); + } + + + /** + * + */ + @Test + public void testPermitWithURIResource() { + Subject subject = Subject.newInstance("John Smith"); + Action action = Action.newInstance("view"); + Resource resource = Resource.newInstance(URI.create("file://repository/classified/abc")); + PepResponse response = getPepAgent().decide(subject, action, resource); + Assert.assertNotNull(response); + Assert.assertEquals(true, response.allowed()); + } + + + /** + * + */ + @Test + public void testPermitWithIntegerResource() { + Subject subject = Subject.newInstance("John Smith"); + Action action = Action.newInstance("view"); + Resource resource = Resource.newInstance(101L); + PepResponse response = getPepAgent().decide(subject, action, resource); + Assert.assertNotNull(response); + Assert.assertEquals(true, response.allowed()); + } + + + /** + * + */ + @Test + public void testMultiRequestWithURI() { + List<Resource> resources = new ArrayList<Resource>(); + resources.add(Resource.newInstance(URI.create("file://repository/classified/abc"))); + resources.add(Resource.newInstance(URI.create("file://repository/classified/xyz"))); + + Subject subject = Subject.newInstance("John Smith"); + Action action = Action.newInstance("view"); + + List<PepResponse> responses = getPepAgent().bulkDecide(resources, action, subject); + Assert.assertNotNull(responses); + for(PepResponse response: responses) { + Assert.assertEquals(true, response.allowed()); + } + } + + public PepAgent getPepAgent() { + return pepAgentFactory.getPepAgent(); + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java new file mode 100755 index 0000000..0c4c50e --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java
@@ -0,0 +1,123 @@ +package org.openliberty.openaz.pepapi.std.test; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openliberty.openaz.pepapi.*; +import org.openliberty.openaz.pepapi.std.StdPepAgentFactory; +import org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContext; +import org.openliberty.openaz.pepapi.std.test.mapper.Client; +import org.openliberty.openaz.pepapi.std.test.mapper.Document; + +import java.util.ArrayList; +import java.util.List; + + +public class TestMapper { + + @SuppressWarnings("unused") + private static Log logger = LogFactory.getLog(TestMapper.class); + + private PepAgentFactory pepAgentFactory; + + @Before + public void setup() { + this.pepAgentFactory = new StdPepAgentFactory("/properties/testmapper.xacml.properties"); + } + + /** + * + */ + @Test + public void testPepAgent() { + Assert.assertNotNull(getPepAgent()); + } + + /** + * + */ + @Test + public void testPermit() { + Subject subject = Subject.newInstance("John Smith"); + subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER"); + + Action action = Action.newInstance("write"); + + Document doc = new Document(1, "OnBoarding Document", "ABC Corporation", "John Smith"); + PepResponse response = getPepAgent().decide(subject, action, doc); + Assert.assertNotNull(response); + Assert.assertEquals(true, response.allowed()); + } + + /** + * + */ + @Test + public void testNotApplicable(){ + Subject subject = Subject.newInstance("John Smith"); + subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER"); + + Action action = Action.newInstance("write"); + Document doc = new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe"); + PepResponse response = getPepAgent().decide(subject, action, doc); + Assert.assertNotNull(response); + Assert.assertEquals(false, response.allowed()); + } + + @Test(expected=PepException.class) + public void testMix(){ + Subject subject = Subject.newInstance("John Smith"); + subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER"); + + Action action = Action.newInstance("write"); + + Document doc1 = new Document(1, "OnBoarding Document", "ABC Corporation", "John Smith"); + Document doc2 = new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe"); + List<Object> resourceList = new ArrayList<Object>(); + resourceList.add(doc1); + resourceList.add(doc2); + + PepResponse response = getPepAgent().decide(subject, action, resourceList); + Assert.assertNotNull(response); + response.allowed(); + } + + @Test + public void testVarArgsPermit(){ + Subject subject = Subject.newInstance("John Smith"); + subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_READER"); + BusinessRequestContext bc = new BusinessRequestContext("USA", "05:00 EST"); + + Action action = Action.newInstance("read"); + List<Object> resources = new ArrayList<Object>(); + resources.add(new Document(1, "OnBoarding Document", "XYZ Corporation", "Jim Doe")); + resources.add(new Client("XYZ Corporation", "USA")); + + PepResponse response = getPepAgent().decide(subject, action, resources, bc); + Assert.assertNotNull(response); + Assert.assertEquals(true, response.allowed()); + } + + @Test + public void testVarArgsDeny(){ + Subject subject = Subject.newInstance("John Smith"); + subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_READER"); + BusinessRequestContext bc = new BusinessRequestContext("INDIA", "05:00 IST"); + + List<Object> resources = new ArrayList<Object>(); + resources.add(new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe")); + resources.add(new Client("XYZ Corporation", "USA")); + + Action action = Action.newInstance("write"); + + PepResponse response = getPepAgent().decide(subject, action, resources, bc); + Assert.assertNotNull(response); + Assert.assertEquals(false, response.allowed()); + } + + public PepAgent getPepAgent() { + return pepAgentFactory.getPepAgent(); + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java new file mode 100755 index 0000000..1820428 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java
@@ -0,0 +1,21 @@ +package org.openliberty.openaz.pepapi.std.test.mapper; + +public class BusinessRequestContext { + + private final String requestCountry; + + private final String requestTime; + + public BusinessRequestContext(String country, String time){ + this.requestCountry = country; + this.requestTime = time; + } + + public String getRequestCountry() { + return requestCountry; + } + + public String getRequestTime() { + return requestTime; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java new file mode 100755 index 0000000..3b1c93a --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java
@@ -0,0 +1,34 @@ +package org.openliberty.openaz.pepapi.std.test.mapper; + +import com.att.research.xacml.api.XACML3; +import org.openliberty.openaz.pepapi.*; + +public class BusinessRequestContextMapper implements ObjectMapper { + + private MapperRegistry mapperRegistry; + + private PepConfig pepConfig; + + @Override + public Class<?> getMappedClass() { + return BusinessRequestContext.class; + } + + @Override + public void map(Object o, PepRequest pepRequest) { + BusinessRequestContext bc = (BusinessRequestContext)o; + PepRequestAttributes envAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT); + envAttributes.addAttribute("jpmc:request-context:country", bc.getRequestCountry()); + envAttributes.addAttribute("jpmc:request-context:time", bc.getRequestTime()); + } + + @Override + public void setMapperRegistry(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java new file mode 100755 index 0000000..9c2ca08 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java
@@ -0,0 +1,20 @@ +package org.openliberty.openaz.pepapi.std.test.mapper; + +public class Client { + + private final String name; + + private final String countryOfDomicile; + + public Client(String name, String countryOfDomicile){ + this.name = name; + this.countryOfDomicile = countryOfDomicile; + } + + public String getName() { + return name; + } + public String getCountryOfDomicile() { + return countryOfDomicile; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java new file mode 100755 index 0000000..b482a44 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java
@@ -0,0 +1,34 @@ +package org.openliberty.openaz.pepapi.std.test.mapper; + +import com.att.research.xacml.api.XACML3; +import org.openliberty.openaz.pepapi.*; + +public class ClientMapper implements ObjectMapper { + + private MapperRegistry mapperRegistry; + + private PepConfig pepConfig; + + @Override + public Class<?> getMappedClass() { + return Client.class; + } + + @Override + public void map(Object o, PepRequest pepRequest) { + Client c = (Client)o; + PepRequestAttributes resAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + resAttributes.addAttribute("jpmc:client:name", c.getName()); + resAttributes.addAttribute("jpmc:client:country-of-domicile", c.getCountryOfDomicile()); + } + + @Override + public void setMapperRegistry(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java new file mode 100755 index 0000000..cd36245 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java
@@ -0,0 +1,32 @@ +package org.openliberty.openaz.pepapi.std.test.mapper; + +public class Document { + + private final Integer documentId; + private final String documentName; + private final String clientName; + private final String documentOwner; + + public Document(Integer documentId, String documentName, String clientName, String documentOwner){ + this.documentId = documentId; + this.documentName = documentName; + this.clientName = clientName; + this.documentOwner = documentOwner; + } + + public Integer getDocumentId() { + return documentId; + } + + public String getDocumentName() { + return documentName; + } + + public String getDocumentOwner() { + return documentOwner; + } + + public String getClientName() { + return clientName; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java new file mode 100755 index 0000000..498d3ee --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java
@@ -0,0 +1,37 @@ +package org.openliberty.openaz.pepapi.std.test.mapper; + +import com.att.research.xacml.api.XACML3; +import org.openliberty.openaz.pepapi.*; + +public class DocumentMapper implements ObjectMapper { + + private MapperRegistry mapperRegistry; + + private PepConfig pepConfig; + + @Override + public Class<?> getMappedClass() { + return Document.class; + } + + @Override + public void map(Object o, PepRequest pepRequest) { + Document d = (Document)o; + PepRequestAttributes resourceAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-id", d.getDocumentId()); + resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-type", "Document"); + resourceAttributes.addAttribute("jpmc:document:document-name", d.getDocumentName()); + resourceAttributes.addAttribute("jpmc:document:client-name", d.getClientName()); + resourceAttributes.addAttribute("jpmc:document:document-owner", d.getDocumentOwner()); + } + + @Override + public void setMapperRegistry(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } +} \ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java new file mode 100755 index 0000000..6a7b317 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java
@@ -0,0 +1,37 @@ +package org.openliberty.openaz.pepapi.std.test.mapper; + +import java.util.ArrayList; +import java.util.List; + +public class MedicalRecord { + + private String id; + + private List<String> accessUserGroup; + + public MedicalRecord(String id){ + this.id = id; + accessUserGroup = new ArrayList<String>(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List<String> getAccessUserGroup() { + return accessUserGroup; + } + + public void setAccessUserGroup(List<String> accessUserGroup) { + this.accessUserGroup = accessUserGroup; + } + + public void addUserToAccessGroup(String user) { + this.accessUserGroup.add(user); + } + +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java new file mode 100755 index 0000000..9882d30 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java
@@ -0,0 +1,36 @@ +package org.openliberty.openaz.pepapi.std.test.mapper; + +import com.att.research.xacml.api.XACML3; +import org.openliberty.openaz.pepapi.*; + +public class MedicalRecordMapper implements ObjectMapper { + + private MapperRegistry mapperRegistry; + + private PepConfig pepConfig; + + @Override + public Class<?> getMappedClass() { + return MedicalRecord.class; + } + + @Override + public void map(Object o, PepRequest pepRequest) { + MedicalRecord md = (MedicalRecord) o; + PepRequestAttributes resourceAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-type", "PatientMedicalRecord"); + resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-id", md.getId()); + for(String accessUser: md.getAccessUserGroup()) { + resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group", accessUser); + } + } + @Override + public void setMapperRegistry(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public void setPepConfig(PepConfig pepConfig) { + this.pepConfig = pepConfig; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java new file mode 100755 index 0000000..2fd5b9a --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java
@@ -0,0 +1,56 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationHandler; +import org.openliberty.openaz.pepapi.ObligationStore; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + + +public class AccessRestrictionObligationHandler implements ObligationHandler { + + private static Log log = LogFactory.getLog(AccessRestrictionObligationHandler.class); + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> accessOblgSet = obligationStore.getHandlerObligations(this.getClass()); + Assert.assertEquals(true, accessOblgSet.size() == 1); + for(Obligation oblg: accessOblgSet) { + Map<String, Object[]> attributeMap = oblg.getAttributeMap(); + Assert.assertNotNull(attributeMap); + for(Entry<String, Object[]> e: attributeMap.entrySet()){ + if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")){ + Assert.assertNotNull(e.getValue()); + } + if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group")){ + Object[] values = e.getValue(); + Assert.assertNotNull(values); + Assert.assertEquals(3, values.length); + } + } + } + Obligation accessGroupOblg = obligationStore.getHandlerObligationById( + this.getClass(), + "urn:oasis:names:tc:xacml:2.0:obligation:access-restriction"); + Assert.assertNotNull(accessGroupOblg); + log.info(accessGroupOblg.getId()); + } + + @Override + public boolean match(Obligation obligation) { + return obligation.getId(). + equals("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction"); + } + + @Override + public void setObligationStore(ObligationStore oStore) { + this.obligationStore = oStore; + } + +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java new file mode 100755 index 0000000..6239412 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java
@@ -0,0 +1,52 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationHandler; +import org.openliberty.openaz.pepapi.ObligationStore; +import org.openliberty.openaz.pepapi.std.test.util.HasResult; + +import java.util.Map; +import java.util.Set; + +public class AgeRestrictionObligationHandler implements ObligationHandler, HasResult { + + private static Log log = LogFactory.getLog(AgeRestrictionObligationHandler.class); + + private ObligationStore obligationStore; + + public String enforce() { + Set<Obligation> ageOblgSet = obligationStore.getHandlerObligations(this.getClass()); + Assert.assertEquals(true, ageOblgSet.size() == 1); + Obligation ageOblg = obligationStore.getHandlerObligationById(this.getClass(), + "urn:oasis:names:tc:xacml:2.0:obligation:age-restriction"); + Assert.assertNotNull(ageOblg); + String value = null; + log.info(ageOblg.getId()); + //Enforcement Logic + Map<String, Object[]> attributeMap = ageOblg.getAttributeMap(); + Object[] values = attributeMap.get("urn:oasis:names:tc:xacml:1.0:subject:age"); + if(values != null) { + value = (String)values[0]; + } + return value; + } + + @Override + public boolean match(Obligation obligation) { + return obligation.getId(). + equals("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction"); + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } + + @Override + public String getResult() { + return enforce(); + } +} \ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java new file mode 100755 index 0000000..d717acb --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java
@@ -0,0 +1,44 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationStore; +import org.openliberty.openaz.pepapi.ObligationStoreAware; +import org.openliberty.openaz.pepapi.MatchAnyObligation; + +import java.util.Map.Entry; + +@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction") +public class AnnotatedAccessRestrictionObligationHandler implements ObligationStoreAware { + + private static Log log = LogFactory.getLog(AnnotatedAccessRestrictionObligationHandler.class); + + private ObligationStore obligationStore; + + public void enforce() { + Obligation accessGroupOblg = obligationStore.getHandlerObligationById( + this.getClass(), + "urn:oasis:names:tc:xacml:2.0:obligation:access-restriction"); + Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction", + accessGroupOblg.getId()); + log.info(accessGroupOblg.getId()); + for(Entry<String, Object[]> e: accessGroupOblg.getAttributeMap().entrySet()){ + if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")){ + Assert.assertNotNull(e.getValue()); + } + if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group")){ + Object[] values = e.getValue(); + Assert.assertNotNull(values); + Assert.assertEquals(3, values.length); + } + } + //Enforcement Logic + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java new file mode 100755 index 0000000..9a10cfc --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java
@@ -0,0 +1,46 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationStore; +import org.openliberty.openaz.pepapi.ObligationStoreAware; +import org.openliberty.openaz.pepapi.MatchAnyObligation; +import org.openliberty.openaz.pepapi.std.test.util.HasResult; + +import java.util.Map; + +@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction") +public class AnnotatedAgeRestrictionObligationHandler implements ObligationStoreAware, HasResult { + + private static Log log = LogFactory.getLog(AnnotatedAgeRestrictionObligationHandler.class); + + private ObligationStore obligationStore; + + public String enforce() { + Obligation ageOblg = obligationStore.getHandlerObligationById( + this.getClass(), + "urn:oasis:names:tc:xacml:2.0:obligation:age-restriction"); + String value = null; + Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction", ageOblg.getId()); + log.info(ageOblg.getId()); + //Enforcement Logic + Map<String, Object[]> attributeMap = ageOblg.getAttributeMap(); + Object[] values = attributeMap.get("urn:oasis:names:tc:xacml:1.0:subject:age"); + if(values != null) { + value = (String)values[0]; + } + return value; + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } + + @Override + public String getResult() { + return enforce(); + } +} \ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java new file mode 100755 index 0000000..c7a6780 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java
@@ -0,0 +1,36 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationStore; +import org.openliberty.openaz.pepapi.ObligationStoreAware; +import org.openliberty.openaz.pepapi.MatchAnyObligation; + +import java.util.Set; + +@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:audit") +public class AnnotatedAuditObligationHandler implements ObligationStoreAware { + + private static Log log = LogFactory.getLog(AnnotatedAuditObligationHandler.class); + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass()); + if(obligationSet.size() == 1) { + for(Obligation obligation: obligationSet) { + Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:audit", obligation.getId()); + log.info(obligation.getId()); + } + }else { + Assert.assertFalse(true); + } + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java new file mode 100755 index 0000000..0e74d8d --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java
@@ -0,0 +1,36 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationStore; +import org.openliberty.openaz.pepapi.ObligationStoreAware; +import org.openliberty.openaz.pepapi.MatchAnyObligation; + +import java.util.HashSet; +import java.util.Set; + +@MatchAnyObligation +public class AnnotatedCatchAllObligationHandler implements ObligationStoreAware { + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass()); + if(obligationSet.size() == 2) { + Set<String> obligationIds = new HashSet<String>(); + for(Obligation oblg: obligationSet){ + obligationIds.add(oblg.getId()); + } + Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1")); + Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2")); + }else { + Assert.assertFalse(true); + } + + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java new file mode 100755 index 0000000..29f49a0 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java
@@ -0,0 +1,36 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationStore; +import org.openliberty.openaz.pepapi.ObligationStoreAware; +import org.openliberty.openaz.pepapi.Attribute; +import org.openliberty.openaz.pepapi.MatchAllObligationAttributes; + +import java.util.Set; + +@MatchAllObligationAttributes({ + @Attribute(id="jpmc:obligation:obligation-type", anyValue="Filtering"), + @Attribute(id="urn:oasis:names:tc:xacml:1.0:subject:subject-id") +}) +public class AnnotatedFilteringObligationHandler implements ObligationStoreAware { + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass()); + if(obligationSet.size() == 1) { + for(Obligation obligation: obligationSet) { + Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1", + obligation.getId()); + } + }else { + Assert.assertFalse(true); + } + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java new file mode 100755 index 0000000..57d5adf --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java
@@ -0,0 +1,19 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import org.openliberty.openaz.pepapi.Attribute; +import org.openliberty.openaz.pepapi.MatchAllObligationAttributes; +import org.openliberty.openaz.pepapi.MatchAnyObligation; + +@MatchAnyObligation({"jpmc:obligation:one","jpmc:obligation:two","jpmc:obligation:three"}) +@MatchAllObligationAttributes({ + @Attribute(id="jpmc:obligation:obligation-type", anyValue={"FILTERING","REDACTION"}), + @Attribute(id="jpmc:resource:attribute:resource-type", anyValue={"Card"}), + @Attribute(id="jpmc:obligation:attribute:attribute-1") +}) +public class AnnotatedObligationHandler { + + public void enforce() { + + } + +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java new file mode 100755 index 0000000..780a69e --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java
@@ -0,0 +1,35 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationStore; +import org.openliberty.openaz.pepapi.ObligationStoreAware; +import org.openliberty.openaz.pepapi.Attribute; +import org.openliberty.openaz.pepapi.MatchAllObligationAttributes; + +import java.util.Set; + +@MatchAllObligationAttributes( + @Attribute(id="urn:oasis:names:tc:xacml:1.0:subject:age") +) +public class AnnotatedRedactionObligationHandler implements ObligationStoreAware { + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass()); + if(obligationSet.size() == 1) { + for(Obligation obligation: obligationSet) { + Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2", + obligation.getId()); + } + }else { + Assert.assertFalse(true); + } + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java new file mode 100755 index 0000000..64c6c41 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java
@@ -0,0 +1,37 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationHandler; +import org.openliberty.openaz.pepapi.ObligationStore; + +import java.util.Set; + +public class AuditObligationHandler implements ObligationHandler { + + private static Log log = LogFactory.getLog(AuditObligationHandler.class); + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> auditOblgSet = obligationStore.getHandlerObligations(this.getClass()); + Assert.assertEquals(true, auditOblgSet.size() == 1); + Obligation auditOblg = obligationStore.getHandlerObligationById( + this.getClass(), + "urn:oasis:names:tc:xacml:2.0:obligation:audit"); + Assert.assertNotNull(auditOblg); + log.info(auditOblg.getId()); + } + + @Override + public boolean match(Obligation t) { + return t.getId().equals("urn:oasis:names:tc:xacml:2.0:obligation:audit"); + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java new file mode 100755 index 0000000..68732f3 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java
@@ -0,0 +1,41 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationHandler; +import org.openliberty.openaz.pepapi.ObligationStore; + +import java.util.HashSet; +import java.util.Set; + + +public class CatchAllObligationHandler implements ObligationHandler { + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass()); + if(obligationSet.size() == 2) { + Set<String> obligationIds = new HashSet<String>(); + for(Obligation oblg: obligationSet){ + obligationIds.add(oblg.getId()); + } + Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1")); + Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2")); + }else { + Assert.assertFalse(true); + } + + } + + @Override + public boolean match(Obligation obligation) { + return true; + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } + +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java new file mode 100755 index 0000000..427b1e3 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java
@@ -0,0 +1,45 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationHandler; +import org.openliberty.openaz.pepapi.ObligationStore; + +import java.util.Map; +import java.util.Set; + +public class FilteringObligationHandler implements ObligationHandler { + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass()); + if(obligationSet.size() == 1) { + for(Obligation obligation: obligationSet) { + Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1", + obligation.getId()); + } + }else { + Assert.assertFalse(true); + } + } + + @Override + public boolean match(Obligation obligation) { + Map<String, Object[]> map = obligation.getAttributeMap(); + if(map.containsKey("jpmc:obligation:obligation-type")) { + Object[] values = map.get("jpmc:obligation:obligation-type"); + if(values != null && values.length != 0) { + for(Object value: values) { + return value.equals("Filtering"); + } + } + } + return false; + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java new file mode 100755 index 0000000..7a262b0 --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java
@@ -0,0 +1,37 @@ +package org.openliberty.openaz.pepapi.std.test.obligation; + +import junit.framework.Assert; +import org.openliberty.openaz.pepapi.Obligation; +import org.openliberty.openaz.pepapi.ObligationHandler; +import org.openliberty.openaz.pepapi.ObligationStore; + +import java.util.Map; +import java.util.Set; + +public class RedactionObligationHandler implements ObligationHandler { + + private ObligationStore obligationStore; + + public void enforce() { + Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass()); + if(obligationSet.size() == 1) { + for(Obligation obligation: obligationSet) { + Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2", + obligation.getId()); + } + }else { + Assert.assertFalse(true); + } + } + + @Override + public boolean match(Obligation obligation) { + Map<String, Object[]> map = obligation.getAttributeMap(); + return map.containsKey("urn:oasis:names:tc:xacml:1.0:subject:age"); + } + + @Override + public void setObligationStore(ObligationStore obligationStore) { + this.obligationStore = obligationStore; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java new file mode 100755 index 0000000..e6b524a --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java
@@ -0,0 +1,53 @@ +package org.openliberty.openaz.pepapi.std.test.util; + +import org.openliberty.openaz.pepapi.PepAgent; +import org.openliberty.openaz.pepapi.PepResponse; + +import java.util.concurrent.Callable; + + +public class AzInvoker implements Callable<String> { + + private final PepAgent pepAgent; + + private final Object subject; + + private final Object action; + + private final Object resource; + + private final long sleepDuration; + + private final HasResult handler; + + public AzInvoker(PepAgent pepAgent, Object subject, Object action, + Object resource, HasResult handler, long sleepDuration) { + this.pepAgent = pepAgent; + this.subject = subject; + this.action = action; + this.resource = resource; + this.handler = handler; + this.sleepDuration = sleepDuration; + } + + private String invoke()throws InterruptedException{ + PepResponse response = pepAgent.decide(subject, action, resource); + if(response != null){ + response.allowed(); + } + Thread.sleep(this.sleepDuration); + return handler.getResult(); + } + + public String call() throws Exception { + return invoke(); + } + + public long getSleepDuration() { + return sleepDuration; + } + + public HasResult getPep() { + return handler; + } +}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java new file mode 100755 index 0000000..c22258f --- /dev/null +++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java
@@ -0,0 +1,7 @@ +package org.openliberty.openaz.pepapi.std.test.util; + +public interface HasResult { + + public String getResult(); + +}
diff --git a/openaz-pep/src/test/resources/log4j.xml b/openaz-pep/src/test/resources/log4j.xml new file mode 100755 index 0000000..ff481f9 --- /dev/null +++ b/openaz-pep/src/test/resources/log4j.xml
@@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> +<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> + + <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender"> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/> + </layout> + </appender> + + <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender"> + <param name="append" value="false"/> + <param name="file" value="target/openaz-junit-tests.log"/> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/> + </layout> + </appender> + + <logger name="org.openliberty.openaz"> + <level value="debug"/> + </logger> + + <logger name="org.springframework"> + <level value="error"/> + </logger> + + <root> + <level value="debug"/> + <appender-ref ref="consoleAppender"/> + <!-- <appender-ref ref="fileAppender"/> --> + </root> + +</log4j:configuration> \ No newline at end of file
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy001.xml b/openaz-pep/src/test/resources/policies/TestPolicy001.xml new file mode 100755 index 0000000..4f2a711 --- /dev/null +++ b/openaz-pep/src/test/resources/policies/TestPolicy001.xml
@@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test001:policy" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd"> + <Description></Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:1.0:test001:rule-1" Effect="Permit"> + <Description> + Julius Hibbert can read or write Bart Simpson's medical record. + </Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Julius Hibbert</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> +</Policy>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy002.xml b/openaz-pep/src/test/resources/policies/TestPolicy002.xml new file mode 100755 index 0000000..d0308c9 --- /dev/null +++ b/openaz-pep/src/test/resources/policies/TestPolicy002.xml
@@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Policy + xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + PolicyId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA2:policy" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides"> + <Description> + Policy for Conformance Test IIA001. + </Description> + <Target/> + <Rule + RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-1" + Effect="Permit"> + <Description> + Physicians can read or write Bart Simpson's medical record. + </Description> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Rule + RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-2" + Effect="Permit"> + <Description> + Patient is allowed to read his/her medical record. + </Description> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-owner" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" + SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" /> + </Apply> + </Apply> + </Condition> + </Rule> +</Policy>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy003.xml b/openaz-pep/src/test/resources/policies/TestPolicy003.xml new file mode 100755 index 0000000..f730e34 --- /dev/null +++ b/openaz-pep/src/test/resources/policies/TestPolicy003.xml
@@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test003:policy" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd"> + <Description></Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule1" Effect="Permit"> + <Target> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/abc</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule2" Effect="Permit"> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/xyz</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> + <Rule RuleId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA3:rule3" Effect="Permit"> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:integer-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#integer">101</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> +</Policy>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy004.xml b/openaz-pep/src/test/resources/policies/TestPolicy004.xml new file mode 100755 index 0000000..83ec917 --- /dev/null +++ b/openaz-pep/src/test/resources/policies/TestPolicy004.xml
@@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test004:policy" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd"> + <Description></Description> + <Target/> + <Rule + RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule1" + Effect="Permit"> + <Description></Description> + <Target> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_WRITER</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="jpmc:document:document-owner" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + </Apply> + </Condition> + </Rule> + <Rule + RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule2" + Effect="Permit"> + <Description></Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_READER</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator AttributeId="jpmc:client:country-of-domicile" + Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator AttributeId="jpmc:request-context:country" + Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + </Apply> + </Condition> + </Rule> +</Policy>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy005.xml b/openaz-pep/src/test/resources/policies/TestPolicy005.xml new file mode 100755 index 0000000..e8d43b5 --- /dev/null +++ b/openaz-pep/src/test/resources/policies/TestPolicy005.xml
@@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="UTF-8"?> +<PolicySet + xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os + access_control-xacml-2.0-policy-schema-os.xsd" + PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset" + PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"> + <Description> + PolicySet for Test 005. + </Description> + <Target/> + <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description> + Policy for Test 005. + </Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1" + Effect="Permit"> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Obligations> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:simpletest" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + </Obligations> + </Policy> + <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy2" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description> + Policy for Test 005. + </Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule2" + Effect="Permit"> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Obligations> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:age-restriction" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:audit" + FulfillOn="Permit"/> + </Obligations> + </Policy> + <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy3" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description> + Policy for Test 005. + </Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule3" + Effect="Permit"> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">InsuranceAgent</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Obligations> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:access-restriction" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-access-group" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_RESOURCE_ATTRIBUTE</AttributeAssignment> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + </Obligations> + </Policy> +</PolicySet>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy006.xml b/openaz-pep/src/test/resources/policies/TestPolicy006.xml new file mode 100755 index 0000000..d609e58 --- /dev/null +++ b/openaz-pep/src/test/resources/policies/TestPolicy006.xml
@@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<PolicySet + xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os + access_control-xacml-2.0-policy-schema-os.xsd" + PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset" + PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"> + <Description> + PolicySet for Test 005. + </Description> + <Target/> + <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description> + Policy for Test 005. + </Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1" + Effect="Permit"> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">resource1</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Obligations> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-1" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="jpmc:obligation:obligation-type" + DataType="http://www.w3.org/2001/XMLSchema#string">Filtering</AttributeAssignment> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-2" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + </Obligations> + </Policy> +</PolicySet>
diff --git a/openaz-pep/src/test/resources/properties/testapi.xacml.properties b/openaz-pep/src/test/resources/properties/testapi.xacml.properties new file mode 100755 index 0000000..b45d2c1 --- /dev/null +++ b/openaz-pep/src/test/resources/properties/testapi.xacml.properties
@@ -0,0 +1,20 @@ +# Default XACML Properties File +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory + +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +xacml.rootPolicies=testPolicy +testPolicy.file=src/test/resources/policies/TestPolicy001.xml + +# If there is a standard policy for the engine: +# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties b/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties new file mode 100755 index 0000000..cb6d77b --- /dev/null +++ b/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties
@@ -0,0 +1,20 @@ +# Default XACML Properties File +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory + +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +xacml.rootPolicies=testPolicy +testPolicy.file=src/test/resources/policies/TestPolicy003.xml + +# If there is a standard policy for the engine: +# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/src/test/resources/properties/testmapper.xacml.properties b/openaz-pep/src/test/resources/properties/testmapper.xacml.properties new file mode 100755 index 0000000..12e1754 --- /dev/null +++ b/openaz-pep/src/test/resources/properties/testmapper.xacml.properties
@@ -0,0 +1,24 @@ +# Default XACML Properties File +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory + +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +xacml.rootPolicies=testPolicy +testPolicy.file=src/test/resources/policies/TestPolicy004.xml + +#pep properties +pep.issuer=test +pep.mapper.classes=org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContextMapper,\ + org.openliberty.openaz.pepapi.std.test.mapper.DocumentMapper, \ + org.openliberty.openaz.pepapi.std.test.mapper.ClientMapper, \ + org.openliberty.openaz.pepapi.std.test.mapper.MedicalRecordMapper
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class new file mode 100644 index 0000000..2337848 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class new file mode 100644 index 0000000..4ed0074 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class new file mode 100644 index 0000000..5663013 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class new file mode 100644 index 0000000..3ca8211 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class new file mode 100644 index 0000000..55f44fa --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class new file mode 100644 index 0000000..2c2d853 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class new file mode 100644 index 0000000..3c8156c --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class new file mode 100644 index 0000000..c90e3dc --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class new file mode 100644 index 0000000..559631e --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class new file mode 100644 index 0000000..b177a57 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class new file mode 100644 index 0000000..e68def5 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class new file mode 100644 index 0000000..f734523 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class new file mode 100644 index 0000000..58100f3 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class new file mode 100644 index 0000000..380ef97 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class new file mode 100644 index 0000000..c00f13b --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class new file mode 100644 index 0000000..7f340b4 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class new file mode 100644 index 0000000..2d7c325 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class new file mode 100644 index 0000000..d028684 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class new file mode 100644 index 0000000..867d637 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class new file mode 100644 index 0000000..ad8c396 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class new file mode 100644 index 0000000..b99e517 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class new file mode 100644 index 0000000..bbf8f9f --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class new file mode 100644 index 0000000..17b60d9 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class new file mode 100644 index 0000000..a883e56 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class new file mode 100644 index 0000000..528ae1c --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class new file mode 100644 index 0000000..5ca7518 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class new file mode 100644 index 0000000..ffae897 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class new file mode 100644 index 0000000..4e8444f --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class new file mode 100644 index 0000000..f29a013 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class new file mode 100644 index 0000000..42a8847 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class new file mode 100644 index 0000000..f063d54 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class new file mode 100644 index 0000000..ed02ad2 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class new file mode 100644 index 0000000..4bc1534 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class new file mode 100644 index 0000000..28d8c6f --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class new file mode 100644 index 0000000..289d996 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class new file mode 100644 index 0000000..137c003 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class new file mode 100644 index 0000000..e1d5084 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class new file mode 100644 index 0000000..bdc1594 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class new file mode 100644 index 0000000..886b01e --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class new file mode 100644 index 0000000..0d05e93 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class new file mode 100644 index 0000000..c78308b --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class new file mode 100644 index 0000000..46edec4 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class new file mode 100644 index 0000000..b43d1d2 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class new file mode 100644 index 0000000..e36b451 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class new file mode 100644 index 0000000..4f89184 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class new file mode 100644 index 0000000..3bed007 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class new file mode 100644 index 0000000..25f293f --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class new file mode 100644 index 0000000..08ab7f2 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class new file mode 100644 index 0000000..5f14c38 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class new file mode 100644 index 0000000..12702eb --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class new file mode 100644 index 0000000..eae5972 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class new file mode 100644 index 0000000..992a93c --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class new file mode 100644 index 0000000..e4e7054 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class new file mode 100644 index 0000000..835bd43 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class new file mode 100644 index 0000000..8a81c8c --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class new file mode 100644 index 0000000..d3ffc48 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class new file mode 100644 index 0000000..a7d9bbc --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class new file mode 100644 index 0000000..465fabf --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class new file mode 100644 index 0000000..076c058 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class new file mode 100644 index 0000000..f1db827 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class new file mode 100644 index 0000000..e5998e5 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class new file mode 100644 index 0000000..b03a334 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class new file mode 100644 index 0000000..f759572 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class new file mode 100644 index 0000000..7a718e2 --- /dev/null +++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class Binary files differ
diff --git a/openaz-pep/target/maven-archiver/pom.properties b/openaz-pep/target/maven-archiver/pom.properties new file mode 100644 index 0000000..3c34336 --- /dev/null +++ b/openaz-pep/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@ +#Generated by Maven +#Tue Apr 07 07:45:26 EDT 2015 +version=0.0.1-SNAPSHOT +groupId=org.openliberty.openaz +artifactId=openaz-pep
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..7e4a8f3 --- /dev/null +++ b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,64 @@ +org/openliberty/openaz/pepapi/ActionResourcePair.class +org/openliberty/openaz/pepapi/PepConfig.class +org/openliberty/openaz/pepapi/std/ResourceMapper.class +org/openliberty/openaz/pepapi/PepResponseType.class +org/openliberty/openaz/pepapi/std/SubjectMapper.class +org/openliberty/openaz/pepapi/std/StdObligation.class +org/openliberty/openaz/pepapi/Subject.class +org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class +org/openliberty/openaz/pepapi/std/StdPepConfig.class +org/openliberty/openaz/pepapi/InvalidAnnotationException.class +org/openliberty/openaz/pepapi/PepAgent.class +org/openliberty/openaz/pepapi/PostDecisionHandler.class +org/openliberty/openaz/pepapi/std/StdObligationRouter.class +org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class +org/openliberty/openaz/pepapi/std/PepUtils.class +org/openliberty/openaz/pepapi/PreDecisionHandler.class +org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class +org/openliberty/openaz/pepapi/PepResponse.class +org/openliberty/openaz/pepapi/PepAgentFactory.class +org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class +org/openliberty/openaz/pepapi/ObligationHandler.class +org/openliberty/openaz/pepapi/ObligationStore.class +org/openliberty/openaz/pepapi/std/StdPepAgent.class +org/openliberty/openaz/pepapi/PepResponseFactory.class +org/openliberty/openaz/pepapi/UnhandleableObligationException.class +org/openliberty/openaz/pepapi/PepRequestAttributes.class +org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class +org/openliberty/openaz/pepapi/ObligationStoreAware.class +org/openliberty/openaz/pepapi/PepResponseBehavior.class +org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class +org/openliberty/openaz/pepapi/std/StdPepRequest.class +org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class +org/openliberty/openaz/pepapi/Environment.class +org/openliberty/openaz/pepapi/ObjectMapper.class +org/openliberty/openaz/pepapi/std/ObligationCriterion.class +org/openliberty/openaz/pepapi/Resource.class +org/openliberty/openaz/pepapi/Obligation.class +org/openliberty/openaz/pepapi/std/StdPepResponse$1.class +org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class +org/openliberty/openaz/pepapi/MapperRegistry.class +org/openliberty/openaz/pepapi/std/CollectionMapper.class +org/openliberty/openaz/pepapi/Matchable.class +org/openliberty/openaz/pepapi/std/ActionMapper.class +org/openliberty/openaz/pepapi/Action.class +org/openliberty/openaz/pepapi/Advice.class +org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class +org/openliberty/openaz/pepapi/Attribute.class +org/openliberty/openaz/pepapi/std/StdPepResponse.class +org/openliberty/openaz/pepapi/std/ArrayMapper.class +org/openliberty/openaz/pepapi/std/StdAdvice.class +org/openliberty/openaz/pepapi/ObligationRouter.class +org/openliberty/openaz/pepapi/std/ObligationCriteria.class +org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class +org/openliberty/openaz/pepapi/PepRequest.class +org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class +org/openliberty/openaz/pepapi/std/StdMapperRegistry.class +org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class +org/openliberty/openaz/pepapi/PepRequestFactory.class +org/openliberty/openaz/pepapi/PepException.class +org/openliberty/openaz/pepapi/std/MultiRequest.class +org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class +org/openliberty/openaz/pepapi/MatchAnyObligation.class +org/openliberty/openaz/pepapi/CategoryContainer.class +org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..dafd73c --- /dev/null +++ b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,63 @@ +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000..25cd122 --- /dev/null +++ b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
@@ -0,0 +1,28 @@ +org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class +org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class +org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class +org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class +org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class +org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class +org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class +org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class +org/openliberty/openaz/pepapi/std/test/util/HasResult.class +org/openliberty/openaz/pepapi/std/test/mapper/Client.class +org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class +org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class +org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class +org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class +org/openliberty/openaz/pepapi/std/test/mapper/Document.class +org/openliberty/openaz/pepapi/std/test/TestAPI.class +org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class +org/openliberty/openaz/pepapi/std/test/TestMapper.class +org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class +org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class +org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class +org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class +org/openliberty/openaz/pepapi/std/test/TestDataTypes.class +org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class +org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class +org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class +org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class +org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..571d370 --- /dev/null +++ b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
@@ -0,0 +1,28 @@ +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java +/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java
diff --git a/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar b/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..b7949c2 --- /dev/null +++ b/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar Binary files differ
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml new file mode 100644 index 0000000..67ca2a1 --- /dev/null +++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml
@@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.662" tests="4" errors="0" skipped="0" failures="0"> + <properties> + <property name="idea.version" value="14.0.3"/> + <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/> + <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/> + <property name="java.vm.version" value="24.75-b04"/> + <property name="gopherProxySet" value="false"/> + <property name="java.vm.vendor" value="Oracle Corporation"/> + <property name="java.vendor.url" value="http://java.oracle.com/"/> + <property name="path.separator" value=":"/> + <property name="guice.disable.misplaced.annotation.check" value="true"/> + <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/> + <property name="file.encoding.pkg" value="sun.io"/> + <property name="idea.launcher.port" value="7534"/> + <property name="user.country" value="US"/> + <property name="sun.java.launcher" value="SUN_STANDARD"/> + <property name="sun.os.patch.level" value="unknown"/> + <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/> + <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/> + <property name="java.runtime.version" value="1.7.0_75-b13"/> + <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/> + <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/> + <property name="os.arch" value="x86_64"/> + <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/> + <property name="line.separator" value=" "/> + <property name="java.vm.specification.vendor" value="Oracle Corporation"/> + <property name="os.name" value="Mac OS X"/> + <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/> + <property name="sun.jnu.encoding" value="UTF-8"/> + <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/> + <property name="java.specification.name" value="Java Platform API Specification"/> + <property name="java.class.version" value="51.0"/> + <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/> + <property name="os.version" value="10.10.2"/> + <property name="user.home" value="/Users/ajith"/> + <property name="user.timezone" value="America/New_York"/> + <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/> + <property name="java.specification.version" value="1.7"/> + <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/> + <property name="file.encoding" value="UTF-8"/> + <property name="user.name" value="ajith"/> + <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/> + <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/> + <property name="java.vm.specification.version" value="1.7"/> + <property name="sun.arch.data.model" value="64"/> + <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/> + <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/> + <property name="java.specification.vendor" value="Oracle Corporation"/> + <property name="user.language" value="en"/> + <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/> + <property name="java.vm.info" value="mixed mode"/> + <property name="java.version" value="1.7.0_75"/> + <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/> + <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/> + <property name="java.vendor" value="Oracle Corporation"/> + <property name="maven.home" value="/Applications/apache-maven-3.1.1"/> + <property name="file.separator" value="/"/> + <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/> + <property name="sun.cpu.endian" value="little"/> + <property name="sun.io.unicode.encoding" value="UnicodeBig"/> + <property name="sun.cpu.isalist" value=""/> + </properties> + <testcase name="testMultiRequest" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.629"/> + <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.017"/> + <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.001"/> + <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.015"/> +</testsuite> \ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml new file mode 100644 index 0000000..160982b --- /dev/null +++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml
@@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0" tests="4" errors="0" skipped="4" failures="0"> + <properties> + <property name="idea.version" value="14.0.3"/> + <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/> + <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/> + <property name="java.vm.version" value="24.75-b04"/> + <property name="gopherProxySet" value="false"/> + <property name="java.vm.vendor" value="Oracle Corporation"/> + <property name="java.vendor.url" value="http://java.oracle.com/"/> + <property name="path.separator" value=":"/> + <property name="guice.disable.misplaced.annotation.check" value="true"/> + <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/> + <property name="file.encoding.pkg" value="sun.io"/> + <property name="idea.launcher.port" value="7534"/> + <property name="user.country" value="US"/> + <property name="sun.java.launcher" value="SUN_STANDARD"/> + <property name="sun.os.patch.level" value="unknown"/> + <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/> + <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/> + <property name="java.runtime.version" value="1.7.0_75-b13"/> + <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/> + <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/> + <property name="os.arch" value="x86_64"/> + <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/> + <property name="line.separator" value=" "/> + <property name="java.vm.specification.vendor" value="Oracle Corporation"/> + <property name="os.name" value="Mac OS X"/> + <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/> + <property name="sun.jnu.encoding" value="UTF-8"/> + <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/> + <property name="java.specification.name" value="Java Platform API Specification"/> + <property name="java.class.version" value="51.0"/> + <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/> + <property name="os.version" value="10.10.2"/> + <property name="user.home" value="/Users/ajith"/> + <property name="user.timezone" value="America/New_York"/> + <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/> + <property name="java.specification.version" value="1.7"/> + <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/> + <property name="file.encoding" value="UTF-8"/> + <property name="user.name" value="ajith"/> + <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/> + <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/> + <property name="java.vm.specification.version" value="1.7"/> + <property name="sun.arch.data.model" value="64"/> + <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/> + <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/> + <property name="java.specification.vendor" value="Oracle Corporation"/> + <property name="user.language" value="en"/> + <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/> + <property name="java.vm.info" value="mixed mode"/> + <property name="java.version" value="1.7.0_75"/> + <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/> + <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/> + <property name="java.vendor" value="Oracle Corporation"/> + <property name="maven.home" value="/Applications/apache-maven-3.1.1"/> + <property name="file.separator" value="/"/> + <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/> + <property name="sun.cpu.endian" value="little"/> + <property name="sun.io.unicode.encoding" value="UnicodeBig"/> + <property name="sun.cpu.isalist" value=""/> + </properties> + <testcase name="testMultiRequest" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0"> + <skipped/> + </testcase> + <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0"> + <skipped/> + </testcase> + <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0"> + <skipped/> + </testcase> + <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0"> + <skipped/> + </testcase> +</testsuite> \ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml new file mode 100644 index 0000000..fea22f8 --- /dev/null +++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml
@@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0" tests="2" errors="0" skipped="2" failures="0"> + <properties> + <property name="idea.version" value="14.0.3"/> + <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/> + <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/> + <property name="java.vm.version" value="24.75-b04"/> + <property name="gopherProxySet" value="false"/> + <property name="java.vm.vendor" value="Oracle Corporation"/> + <property name="java.vendor.url" value="http://java.oracle.com/"/> + <property name="path.separator" value=":"/> + <property name="guice.disable.misplaced.annotation.check" value="true"/> + <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/> + <property name="file.encoding.pkg" value="sun.io"/> + <property name="idea.launcher.port" value="7534"/> + <property name="user.country" value="US"/> + <property name="sun.java.launcher" value="SUN_STANDARD"/> + <property name="sun.os.patch.level" value="unknown"/> + <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/> + <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/> + <property name="java.runtime.version" value="1.7.0_75-b13"/> + <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/> + <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/> + <property name="os.arch" value="x86_64"/> + <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/> + <property name="line.separator" value=" "/> + <property name="java.vm.specification.vendor" value="Oracle Corporation"/> + <property name="os.name" value="Mac OS X"/> + <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/> + <property name="sun.jnu.encoding" value="UTF-8"/> + <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/> + <property name="java.specification.name" value="Java Platform API Specification"/> + <property name="java.class.version" value="51.0"/> + <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/> + <property name="os.version" value="10.10.2"/> + <property name="user.home" value="/Users/ajith"/> + <property name="user.timezone" value="America/New_York"/> + <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/> + <property name="java.specification.version" value="1.7"/> + <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/> + <property name="file.encoding" value="UTF-8"/> + <property name="user.name" value="ajith"/> + <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/> + <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/> + <property name="java.vm.specification.version" value="1.7"/> + <property name="sun.arch.data.model" value="64"/> + <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/> + <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/> + <property name="java.specification.vendor" value="Oracle Corporation"/> + <property name="user.language" value="en"/> + <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/> + <property name="java.vm.info" value="mixed mode"/> + <property name="java.version" value="1.7.0_75"/> + <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/> + <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/> + <property name="java.vendor" value="Oracle Corporation"/> + <property name="maven.home" value="/Applications/apache-maven-3.1.1"/> + <property name="file.separator" value="/"/> + <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/> + <property name="sun.cpu.endian" value="little"/> + <property name="sun.io.unicode.encoding" value="UnicodeBig"/> + <property name="sun.cpu.isalist" value=""/> + </properties> + <testcase name="testRegistration" classname="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0"> + <skipped/> + </testcase> + <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0"> + <skipped/> + </testcase> +</testsuite> \ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml new file mode 100644 index 0000000..5c7ae2e --- /dev/null +++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml
@@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<testsuite name="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.556" tests="4" errors="0" skipped="0" failures="0"> + <properties> + <property name="idea.version" value="14.0.3"/> + <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/> + <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/> + <property name="java.vm.version" value="24.75-b04"/> + <property name="gopherProxySet" value="false"/> + <property name="java.vm.vendor" value="Oracle Corporation"/> + <property name="java.vendor.url" value="http://java.oracle.com/"/> + <property name="path.separator" value=":"/> + <property name="guice.disable.misplaced.annotation.check" value="true"/> + <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/> + <property name="file.encoding.pkg" value="sun.io"/> + <property name="idea.launcher.port" value="7534"/> + <property name="user.country" value="US"/> + <property name="sun.java.launcher" value="SUN_STANDARD"/> + <property name="sun.os.patch.level" value="unknown"/> + <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/> + <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/> + <property name="java.runtime.version" value="1.7.0_75-b13"/> + <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/> + <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/> + <property name="os.arch" value="x86_64"/> + <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/> + <property name="line.separator" value=" "/> + <property name="java.vm.specification.vendor" value="Oracle Corporation"/> + <property name="os.name" value="Mac OS X"/> + <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/> + <property name="sun.jnu.encoding" value="UTF-8"/> + <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/> + <property name="java.specification.name" value="Java Platform API Specification"/> + <property name="java.class.version" value="51.0"/> + <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/> + <property name="os.version" value="10.10.2"/> + <property name="user.home" value="/Users/ajith"/> + <property name="user.timezone" value="America/New_York"/> + <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/> + <property name="java.specification.version" value="1.7"/> + <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/> + <property name="file.encoding" value="UTF-8"/> + <property name="user.name" value="ajith"/> + <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/> + <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/> + <property name="java.vm.specification.version" value="1.7"/> + <property name="sun.arch.data.model" value="64"/> + <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/> + <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/> + <property name="java.specification.vendor" value="Oracle Corporation"/> + <property name="user.language" value="en"/> + <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/> + <property name="java.vm.info" value="mixed mode"/> + <property name="java.version" value="1.7.0_75"/> + <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/> + <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/> + <property name="java.vendor" value="Oracle Corporation"/> + <property name="maven.home" value="/Applications/apache-maven-3.1.1"/> + <property name="file.separator" value="/"/> + <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/> + <property name="sun.cpu.endian" value="little"/> + <property name="sun.io.unicode.encoding" value="UnicodeBig"/> + <property name="sun.cpu.isalist" value=""/> + </properties> + <testcase name="testMultiRequestWithURI" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.511"/> + <testcase name="testPermitWithURIResource" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.022"/> + <testcase name="testPermitWithIntegerResource" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.022"/> + <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.001"/> +</testsuite> \ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml new file mode 100644 index 0000000..4c652e2 --- /dev/null +++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml
@@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<testsuite name="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.515" tests="6" errors="0" skipped="0" failures="0"> + <properties> + <property name="idea.version" value="14.0.3"/> + <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/> + <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/> + <property name="java.vm.version" value="24.75-b04"/> + <property name="gopherProxySet" value="false"/> + <property name="java.vm.vendor" value="Oracle Corporation"/> + <property name="java.vendor.url" value="http://java.oracle.com/"/> + <property name="path.separator" value=":"/> + <property name="guice.disable.misplaced.annotation.check" value="true"/> + <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/> + <property name="file.encoding.pkg" value="sun.io"/> + <property name="idea.launcher.port" value="7534"/> + <property name="user.country" value="US"/> + <property name="sun.java.launcher" value="SUN_STANDARD"/> + <property name="sun.os.patch.level" value="unknown"/> + <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/> + <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/> + <property name="java.runtime.version" value="1.7.0_75-b13"/> + <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/> + <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/> + <property name="os.arch" value="x86_64"/> + <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/> + <property name="line.separator" value=" "/> + <property name="java.vm.specification.vendor" value="Oracle Corporation"/> + <property name="os.name" value="Mac OS X"/> + <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/> + <property name="sun.jnu.encoding" value="UTF-8"/> + <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/> + <property name="java.specification.name" value="Java Platform API Specification"/> + <property name="java.class.version" value="51.0"/> + <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/> + <property name="os.version" value="10.10.2"/> + <property name="user.home" value="/Users/ajith"/> + <property name="user.timezone" value="America/New_York"/> + <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/> + <property name="java.specification.version" value="1.7"/> + <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/> + <property name="file.encoding" value="UTF-8"/> + <property name="user.name" value="ajith"/> + <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/> + <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/> + <property name="java.vm.specification.version" value="1.7"/> + <property name="sun.arch.data.model" value="64"/> + <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/> + <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/> + <property name="java.specification.vendor" value="Oracle Corporation"/> + <property name="user.language" value="en"/> + <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/> + <property name="java.vm.info" value="mixed mode"/> + <property name="java.version" value="1.7.0_75"/> + <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/> + <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/> + <property name="java.vendor" value="Oracle Corporation"/> + <property name="maven.home" value="/Applications/apache-maven-3.1.1"/> + <property name="file.separator" value="/"/> + <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/> + <property name="sun.cpu.endian" value="little"/> + <property name="sun.io.unicode.encoding" value="UnicodeBig"/> + <property name="sun.cpu.isalist" value=""/> + </properties> + <testcase name="testMix" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.441"/> + <testcase name="testVarArgsDeny" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.02"/> + <testcase name="testVarArgsPermit" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.018"/> + <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.016"/> + <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.001"/> + <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.019"/> +</testsuite> \ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt new file mode 100644 index 0000000..3ad938b --- /dev/null +++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt
@@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: org.openliberty.openaz.pepapi.std.test.TestAPI +------------------------------------------------------------------------------- +Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.736 sec - in org.openliberty.openaz.pepapi.std.test.TestAPI
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt new file mode 100644 index 0000000..b725ae3 --- /dev/null +++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt
@@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP +------------------------------------------------------------------------------- +Tests run: 4, Failures: 0, Errors: 0, Skipped: 4, Time elapsed: 0.058 sec - in org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt new file mode 100644 index 0000000..23471ca --- /dev/null +++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt
@@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration +------------------------------------------------------------------------------- +Tests run: 2, Failures: 0, Errors: 0, Skipped: 2, Time elapsed: 0.066 sec - in org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt new file mode 100644 index 0000000..d07c3f4 --- /dev/null +++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt
@@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: org.openliberty.openaz.pepapi.std.test.TestDataTypes +------------------------------------------------------------------------------- +Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.631 sec - in org.openliberty.openaz.pepapi.std.test.TestDataTypes
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt new file mode 100644 index 0000000..3457155 --- /dev/null +++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt
@@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: org.openliberty.openaz.pepapi.std.test.TestMapper +------------------------------------------------------------------------------- +Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.675 sec - in org.openliberty.openaz.pepapi.std.test.TestMapper
diff --git a/openaz-pep/target/test-classes/log4j.xml b/openaz-pep/target/test-classes/log4j.xml new file mode 100644 index 0000000..ff481f9 --- /dev/null +++ b/openaz-pep/target/test-classes/log4j.xml
@@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> +<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> + + <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender"> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/> + </layout> + </appender> + + <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender"> + <param name="append" value="false"/> + <param name="file" value="target/openaz-junit-tests.log"/> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/> + </layout> + </appender> + + <logger name="org.openliberty.openaz"> + <level value="debug"/> + </logger> + + <logger name="org.springframework"> + <level value="error"/> + </logger> + + <root> + <level value="debug"/> + <appender-ref ref="consoleAppender"/> + <!-- <appender-ref ref="fileAppender"/> --> + </root> + +</log4j:configuration> \ No newline at end of file
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class new file mode 100644 index 0000000..3aff1fb --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class new file mode 100644 index 0000000..4884fbf --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class new file mode 100644 index 0000000..c8aac30 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class new file mode 100644 index 0000000..a1b1126 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class new file mode 100644 index 0000000..918799c --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class new file mode 100644 index 0000000..0d80c1f --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class new file mode 100644 index 0000000..7681006 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class new file mode 100644 index 0000000..2dc35b6 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class new file mode 100644 index 0000000..a65c689 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class new file mode 100644 index 0000000..9bb4d24 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class new file mode 100644 index 0000000..4a12f1c --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class new file mode 100644 index 0000000..62cf6e2 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class new file mode 100644 index 0000000..b0d1fec --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class new file mode 100644 index 0000000..e3f3659 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class new file mode 100644 index 0000000..9ea4d49 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class new file mode 100644 index 0000000..a239d16 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class new file mode 100644 index 0000000..f5e751d --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class new file mode 100644 index 0000000..26ac39e --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class new file mode 100644 index 0000000..b07bf19 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class new file mode 100644 index 0000000..e5ac144 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class new file mode 100644 index 0000000..04017a5 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class new file mode 100644 index 0000000..b2dbde5 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class new file mode 100644 index 0000000..9d3ccbf --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class new file mode 100644 index 0000000..070c920 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class new file mode 100644 index 0000000..867f3df --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class new file mode 100644 index 0000000..387f894 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class new file mode 100644 index 0000000..4fb49b6 --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class new file mode 100644 index 0000000..a82a6fd --- /dev/null +++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class Binary files differ
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy001.xml b/openaz-pep/target/test-classes/policies/TestPolicy001.xml new file mode 100644 index 0000000..4f2a711 --- /dev/null +++ b/openaz-pep/target/test-classes/policies/TestPolicy001.xml
@@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test001:policy" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd"> + <Description></Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:1.0:test001:rule-1" Effect="Permit"> + <Description> + Julius Hibbert can read or write Bart Simpson's medical record. + </Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Julius Hibbert</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> +</Policy>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy002.xml b/openaz-pep/target/test-classes/policies/TestPolicy002.xml new file mode 100644 index 0000000..d0308c9 --- /dev/null +++ b/openaz-pep/target/test-classes/policies/TestPolicy002.xml
@@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Policy + xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + PolicyId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA2:policy" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides"> + <Description> + Policy for Conformance Test IIA001. + </Description> + <Target/> + <Rule + RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-1" + Effect="Permit"> + <Description> + Physicians can read or write Bart Simpson's medical record. + </Description> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Rule + RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-2" + Effect="Permit"> + <Description> + Patient is allowed to read his/her medical record. + </Description> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-owner" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" + SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" /> + </Apply> + </Apply> + </Condition> + </Rule> +</Policy>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy003.xml b/openaz-pep/target/test-classes/policies/TestPolicy003.xml new file mode 100644 index 0000000..f730e34 --- /dev/null +++ b/openaz-pep/target/test-classes/policies/TestPolicy003.xml
@@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test003:policy" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd"> + <Description></Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule1" Effect="Permit"> + <Target> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/abc</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule2" Effect="Permit"> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/xyz</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> + <Rule RuleId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA3:rule3" Effect="Permit"> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:integer-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#integer">101</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> +</Policy>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy004.xml b/openaz-pep/target/test-classes/policies/TestPolicy004.xml new file mode 100644 index 0000000..83ec917 --- /dev/null +++ b/openaz-pep/target/test-classes/policies/TestPolicy004.xml
@@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test004:policy" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd"> + <Description></Description> + <Target/> + <Rule + RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule1" + Effect="Permit"> + <Description></Description> + <Target> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_WRITER</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="jpmc:document:document-owner" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + </Apply> + </Condition> + </Rule> + <Rule + RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule2" + Effect="Permit"> + <Description></Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_READER</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator AttributeId="jpmc:client:country-of-domicile" + Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator AttributeId="jpmc:request-context:country" + Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" + DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> + </Apply> + </Apply> + </Condition> + </Rule> +</Policy>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy005.xml b/openaz-pep/target/test-classes/policies/TestPolicy005.xml new file mode 100644 index 0000000..e8d43b5 --- /dev/null +++ b/openaz-pep/target/test-classes/policies/TestPolicy005.xml
@@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="UTF-8"?> +<PolicySet + xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os + access_control-xacml-2.0-policy-schema-os.xsd" + PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset" + PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"> + <Description> + PolicySet for Test 005. + </Description> + <Target/> + <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description> + Policy for Test 005. + </Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1" + Effect="Permit"> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Obligations> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:simpletest" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + </Obligations> + </Policy> + <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy2" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description> + Policy for Test 005. + </Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule2" + Effect="Permit"> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Obligations> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:age-restriction" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:audit" + FulfillOn="Permit"/> + </Obligations> + </Policy> + <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy3" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description> + Policy for Test 005. + </Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule3" + Effect="Permit"> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">InsuranceAgent</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Obligations> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:access-restriction" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-access-group" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_RESOURCE_ATTRIBUTE</AttributeAssignment> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + </Obligations> + </Policy> +</PolicySet>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy006.xml b/openaz-pep/target/test-classes/policies/TestPolicy006.xml new file mode 100644 index 0000000..d609e58 --- /dev/null +++ b/openaz-pep/target/test-classes/policies/TestPolicy006.xml
@@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<PolicySet + xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os + access_control-xacml-2.0-policy-schema-os.xsd" + PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset" + PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"> + <Description> + PolicySet for Test 005. + </Description> + <Target/> + <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1" + RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description> + Policy for Test 005. + </Description> + <Target/> + <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1" + Effect="Permit"> + <Target> + <Subjects> + <Subject> + <SubjectMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue> + <SubjectAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </SubjectMatch> + </Subject> + </Subjects> + <Resources> + <Resource> + <ResourceMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">resource1</AttributeValue> + <ResourceAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ResourceMatch> + </Resource> + </Resources> + <Actions> + <Action> + <ActionMatch + MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue + DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue> + <ActionAttributeDesignator + AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"/> + </ActionMatch> + </Action> + </Actions> + </Target> + </Rule> + <Obligations> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-1" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="jpmc:obligation:obligation-type" + DataType="http://www.w3.org/2001/XMLSchema#string">Filtering</AttributeAssignment> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + <Obligation + ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-2" + FulfillOn="Permit"> + <AttributeAssignment + AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age" + DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment> + </Obligation> + </Obligations> + </Policy> +</PolicySet>
diff --git a/openaz-pep/target/test-classes/properties/testapi.xacml.properties b/openaz-pep/target/test-classes/properties/testapi.xacml.properties new file mode 100644 index 0000000..b45d2c1 --- /dev/null +++ b/openaz-pep/target/test-classes/properties/testapi.xacml.properties
@@ -0,0 +1,20 @@ +# Default XACML Properties File +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory + +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +xacml.rootPolicies=testPolicy +testPolicy.file=src/test/resources/policies/TestPolicy001.xml + +# If there is a standard policy for the engine: +# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties b/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties new file mode 100644 index 0000000..cb6d77b --- /dev/null +++ b/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties
@@ -0,0 +1,20 @@ +# Default XACML Properties File +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory + +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +xacml.rootPolicies=testPolicy +testPolicy.file=src/test/resources/policies/TestPolicy003.xml + +# If there is a standard policy for the engine: +# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/target/test-classes/properties/testmapper.xacml.properties b/openaz-pep/target/test-classes/properties/testmapper.xacml.properties new file mode 100644 index 0000000..12e1754 --- /dev/null +++ b/openaz-pep/target/test-classes/properties/testmapper.xacml.properties
@@ -0,0 +1,24 @@ +# Default XACML Properties File +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory + +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +xacml.rootPolicies=testPolicy +testPolicy.file=src/test/resources/policies/TestPolicy004.xml + +#pep properties +pep.issuer=test +pep.mapper.classes=org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContextMapper,\ + org.openliberty.openaz.pepapi.std.test.mapper.DocumentMapper, \ + org.openliberty.openaz.pepapi.std.test.mapper.ClientMapper, \ + org.openliberty.openaz.pepapi.std.test.mapper.MedicalRecordMapper
diff --git a/openaz-xacml-pap-admin/pom.xml b/openaz-xacml-pap-admin/pom.xml new file mode 100755 index 0000000..78f7817 --- /dev/null +++ b/openaz-xacml-pap-admin/pom.xml
@@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>openaz</artifactId> + <groupId>org.openliberty.openaz</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>openaz-xacml-pap-admin</artifactId> + + +</project> \ No newline at end of file
diff --git a/openaz-xacml-pap-admin/target/maven-archiver/pom.properties b/openaz-xacml-pap-admin/target/maven-archiver/pom.properties new file mode 100644 index 0000000..d531585 --- /dev/null +++ b/openaz-xacml-pap-admin/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@ +#Generated by Maven +#Tue Apr 07 07:42:37 EDT 2015 +version=0.0.1-SNAPSHOT +groupId=org.openliberty.openaz +artifactId=openaz-xacml-pap-admin
diff --git a/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
diff --git a/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar b/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..00bbf9f --- /dev/null +++ b/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar Binary files differ
diff --git a/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF b/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF new file mode 100755 index 0000000..58630c0 --- /dev/null +++ b/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +
diff --git a/openaz-xacml-pap-rest/WebContent/README.txt b/openaz-xacml-pap-rest/WebContent/README.txt new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/openaz-xacml-pap-rest/WebContent/README.txt
diff --git a/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml b/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml new file mode 100755 index 0000000..ae838f4 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml
@@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:5b82db34-1613-4108-8973-93074182dd94" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>A sample policy to demonstrate use of annotations in a Java class.</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">www.mywebsite.com</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Rule RuleId="urn:com:att:xacml:rule:id:8b257f30-4e06-4c8e-8fb7-691b9534d55c" Effect="Permit"> + <Description>PERMIT - John can access it</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">John</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESS</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:4fe7c147-7811-4e30-a463-9135afb1cfc2" Effect="Deny"> + <Description>DENY - Ringo cannot</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Ringo</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> +</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties new file mode 100755 index 0000000..999c160 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties
@@ -0,0 +1,3 @@ +# PIP Engine Definition +# +xacml.pip.engines=
diff --git a/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties new file mode 100755 index 0000000..1e6bf8a --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties
@@ -0,0 +1,5 @@ +xacml.rootPolicies=AnnotationPolicy.v1.xml +xacml.referencedPolicies= + + +AnnotationPolicy.v1.xml.url=http://localhost:9090/pap/?id=AnnotationPolicy.v1.xml
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml new file mode 100755 index 0000000..68c7783 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides"> + <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction. + +http://baseballhall.org/hall-famers/rules-election/bbwaa +</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Match> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>Active Timeframe: + +A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description> + <Target/> + <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit"> + <Description>Player's debut date >= (today's date - 20 years) AND final date <= (today's date - 5 years).</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>debut within 20 years AND final game more than 5 years ago.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal"> + <Description>Debut date <= (today's date - 20 years)</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> + <Description>UN-bag player's debut date.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration"> + <Description>Subtract 20 years from today's date.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> +<Description>UN-bag today's date.</Description> +<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal"> + <Description>Final Game <= (today's date - 5 years)</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> + <Description>UN-bag final game date</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration"> + <Description>Subtract 5 years from today's date.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> +<Description>UN-bag today's date.</Description> +<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue> + </Apply> + </Apply> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny"> + <Description>DENY - Default</Description> + <Target/> + </Rule> + </Policy> + <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description> + <Target/> + <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit"> + <Description>There should be >= 10 years of appearance(s) values.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal"> + <Description>The number of years a player appeared.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size"> + <Description>Count the number.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny"> + <Description>DENY - Default</Description> + <Target/> + </Rule> + </Policy> +</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml new file mode 100755 index 0000000..15e25ed --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides"> + <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit"> + <Description>Checks the subject. </Description> + <Target/> + <VariableDefinition VariableId="isSubjectFemale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>sex=Female</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="isSubjectMale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>subject sex=Male</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesSubjectNeedParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or"> + <Description>Is the subject a female OR male?</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is female AND does not need parental consent.</Description> + <VariableReference VariableId="isSubjectFemale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is subject male AND age >= male consent age.</Description> + <VariableReference VariableId="isSubjectMale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= legal age of consent for male.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesSubjectHaveParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </VariableDefinition> + <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit"> + <Description>If the subject does NOT need consent, then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit"> + <Description>If the subject needs consent AND has parental consent, then Permit.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectHaveParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </Apply> + </Condition> + </Rule> + </Policy> + <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit"> + <Description>Check the resource.</Description> + <Target/> + <VariableDefinition VariableId="isResourceFemale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>sex=Female</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="isResourceMale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>subject sex=Male</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesResourceNeedParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or"> + <Description>Is resource female OR male?</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is female AND does not need parental consent.</Description> + <VariableReference VariableId="isResourceFemale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age for female.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>un-bag attribute</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is male and AND does not need parental consent.</Description> + <VariableReference VariableId="isResourceMale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age for male.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesResourceHaveParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </VariableDefinition> + <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit"> + <Description>If the resource does NOT need consent, then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit"> + <Description>The resources needs parental consent and has parental consent then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceHaveParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </Apply> + </Condition> + </Rule> + </Policy> +</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties new file mode 100755 index 0000000..17ec3a2 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties
@@ -0,0 +1,227 @@ +# PIP Engine Definition +# +xacml.pip.engines=csv1,csv2,hyper1 + +ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone +CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie +CSO.mode=DEVL + +csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv1.name=Master +csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info +csv1.issuer=com:att:research:xacml:test:csv +csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt +csv1.maxsize=500000 +csv1.delimiter=, +csv1.quote=" +csv1.skip=0 + +csv1.resolvers=data + +csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv1.resolver.data.name=Player Resolver +csv1.resolver.data.description=This resolver finds player information in the Master table. +csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame +csv1.resolver.data.field.firstname.column=16 +csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname +csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.lastname.column=17 +csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname +csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathyear.column=10 +csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear +csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathmonth.column=11 +csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth +csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathday.column=12 +csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday +csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.debut.column=25 +csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut +csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.finalgame.column=26 +csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame +csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.parameters=playerid +csv1.resolver.data.parameter.playerid.column=1 +csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv2.name=Appearances +csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year. +#csv2.issuer= +csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt +csv2.maxsize=500000 +csv2.delimiter=, +csv2.quote=" +csv2.skip=0 + +csv2.resolvers=data + +csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv2.resolver.data.name=Appearance Resolver +csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table. +csv2.resolver.data.fields=appearance +csv2.resolver.data.field.appearance.column=0 +csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance +csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer +csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv + +csv2.resolver.data.parameters=playerid +csv2.resolver.data.parameter.playerid.column=3 +csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#csv1.resolver.data.parameter.playerid.issuer= + +hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine +hyper1.name=World Marriage Age Limits +hyper1.description=Minimum age for female/male marriages with or without their parental consent. +hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv +hyper1.target=marriage +hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20) + +hyper1.resolvers=age_consent + +hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +hyper1.resolver.age_consent.name=Ages +hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country. +hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=? +hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale + +hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female +hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male +hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female +hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male +hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.parameters=country +hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name +hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string +hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country +#hyper1.resolver.age_consent.parameter.country.issuer= + +sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine +sql1.name=World +sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures. +# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine. +sql1.issuer=com:att:research:xacml:test:sql +# +# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to +# create the tables and load the data. +# +sql1.type=jdbc +sql1.jdbc.driver=org.postgresql.Driver +#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world +#sql1.jdbc.conn.user=sa +#sql1.jdbc.conn.password= +sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world +sql1.jdbc.conn.user=pip +sql1.jdbc.conn.password=p1pUs3r +# +# This is the configuration for JNDI datasource. +# +#sql1.type=jndi +#sql1.datasource=jdbc/xacml + +sql1.resolvers=langer + +sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +sql1.resolver.langer.name=Language +sql1.resolver.langer.description=This returns the language for a city. +sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=? +sql1.resolver.langer.fields=language +sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language +sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +#You can override the default issuer that is set in the JDBCEngine definition if you want. +#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql +sql1.resolver.langer.parameters=name +sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id +sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource + + +ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine +ldap1.name=LDAP PIP +ldap1.description=The LDAP containing the seven seas sample LDIF data. +ldap1.issuer=com:att:research:xacml:test:ldap +ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory +# +# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before +# this example will work. +# +#ldap1.java.naming.provider.url=ldap://localhost:10389 +ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389 +#ldap.java.naming.security.principal= +#ldap.java.naming.security.credentials= +ldap1.scope=subtree + +ldap1.resolvers=dn,ship + +ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.dn.name=Domain Names +ldap1.resolver.dn.description=Find all the dn's for the subject id +ldap1.resolver.dn.base=o=sevenseas +ldap1.resolver.dn.base.parameters= +ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid})) +ldap1.resolver.dn.filter.parameters=uid +ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.dn.filter.view=dn +ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap + +ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.ship.name=Ship Resolver +ldap1.resolver.ship.description=This resolves a subject's dn to a ship. +ldap1.resolver.ship.base=o=sevenseas +ldap1.resolver.ship.base.parameters= +ldap1.resolver.ship.filter=uniquemember=${dn} +ldap1.resolver.ship.filter.parameters=dn +ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.ship.filter.view=cn +ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship +ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap +
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties new file mode 100755 index 0000000..6c2cb20 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties
@@ -0,0 +1,8 @@ +xacml.rootPolicies=CSV-Baseball-Hall-Of-Fame-v1.xml,CSV-Legal-Age-Marriage-v1.xml +xacml.referencedPolicies= + + +CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml + +CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml +
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml new file mode 100755 index 0000000..15e25ed --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides"> + <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit"> + <Description>Checks the subject. </Description> + <Target/> + <VariableDefinition VariableId="isSubjectFemale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>sex=Female</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="isSubjectMale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>subject sex=Male</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesSubjectNeedParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or"> + <Description>Is the subject a female OR male?</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is female AND does not need parental consent.</Description> + <VariableReference VariableId="isSubjectFemale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is subject male AND age >= male consent age.</Description> + <VariableReference VariableId="isSubjectMale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= legal age of consent for male.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesSubjectHaveParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </VariableDefinition> + <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit"> + <Description>If the subject does NOT need consent, then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit"> + <Description>If the subject needs consent AND has parental consent, then Permit.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectHaveParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </Apply> + </Condition> + </Rule> + </Policy> + <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit"> + <Description>Check the resource.</Description> + <Target/> + <VariableDefinition VariableId="isResourceFemale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>sex=Female</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="isResourceMale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>subject sex=Male</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesResourceNeedParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or"> + <Description>Is resource female OR male?</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is female AND does not need parental consent.</Description> + <VariableReference VariableId="isResourceFemale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age for female.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>un-bag attribute</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is male and AND does not need parental consent.</Description> + <VariableReference VariableId="isResourceMale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age for male.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesResourceHaveParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </VariableDefinition> + <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit"> + <Description>If the resource does NOT need consent, then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit"> + <Description>The resources needs parental consent and has parental consent then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceHaveParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </Apply> + </Condition> + </Rule> + </Policy> +</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties new file mode 100755 index 0000000..5f66428 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties
@@ -0,0 +1,227 @@ +# PIP Engine Definition +# +xacml.pip.engines=hyper1 + +ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone +CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie +CSO.mode=DEVL + +csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv1.name=Master +csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info +csv1.issuer=com:att:research:xacml:test:csv +csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt +csv1.maxsize=500000 +csv1.delimiter=, +csv1.quote=" +csv1.skip=0 + +csv1.resolvers=data + +csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv1.resolver.data.name=Player Resolver +csv1.resolver.data.description=This resolver finds player information in the Master table. +csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame +csv1.resolver.data.field.firstname.column=16 +csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname +csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.lastname.column=17 +csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname +csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathyear.column=10 +csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear +csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathmonth.column=11 +csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth +csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathday.column=12 +csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday +csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.debut.column=25 +csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut +csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.finalgame.column=26 +csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame +csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.parameters=playerid +csv1.resolver.data.parameter.playerid.column=1 +csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv2.name=Appearances +csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year. +#csv2.issuer= +csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt +csv2.maxsize=500000 +csv2.delimiter=, +csv2.quote=" +csv2.skip=0 + +csv2.resolvers=data + +csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv2.resolver.data.name=Appearance Resolver +csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table. +csv2.resolver.data.fields=appearance +csv2.resolver.data.field.appearance.column=0 +csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance +csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer +csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv + +csv2.resolver.data.parameters=playerid +csv2.resolver.data.parameter.playerid.column=3 +csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#csv1.resolver.data.parameter.playerid.issuer= + +hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine +hyper1.name=World Marriage Age Limits +hyper1.description=Minimum age for female/male marriages with or without their parental consent. +hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv +hyper1.target=marriage +hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20) + +hyper1.resolvers=age_consent + +hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +hyper1.resolver.age_consent.name=Ages +hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country. +hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=? +hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale + +hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female +hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male +hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female +hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male +hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.parameters=country +hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name +hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string +hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country +#hyper1.resolver.age_consent.parameter.country.issuer= + +sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine +sql1.name=World +sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures. +# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine. +sql1.issuer=com:att:research:xacml:test:sql +# +# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to +# create the tables and load the data. +# +sql1.type=jdbc +sql1.jdbc.driver=org.postgresql.Driver +#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world +#sql1.jdbc.conn.user=sa +#sql1.jdbc.conn.password= +sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world +sql1.jdbc.conn.user=pip +sql1.jdbc.conn.password=p1pUs3r +# +# This is the configuration for JNDI datasource. +# +#sql1.type=jndi +#sql1.datasource=jdbc/xacml + +sql1.resolvers=langer + +sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +sql1.resolver.langer.name=Language +sql1.resolver.langer.description=This returns the language for a city. +sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=? +sql1.resolver.langer.fields=language +sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language +sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +#You can override the default issuer that is set in the JDBCEngine definition if you want. +#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql +sql1.resolver.langer.parameters=name +sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id +sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource + + +ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine +ldap1.name=LDAP PIP +ldap1.description=The LDAP containing the seven seas sample LDIF data. +ldap1.issuer=com:att:research:xacml:test:ldap +ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory +# +# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before +# this example will work. +# +#ldap1.java.naming.provider.url=ldap://localhost:10389 +ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389 +#ldap.java.naming.security.principal= +#ldap.java.naming.security.credentials= +ldap1.scope=subtree + +ldap1.resolvers=dn,ship + +ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.dn.name=Domain Names +ldap1.resolver.dn.description=Find all the dn's for the subject id +ldap1.resolver.dn.base=o=sevenseas +ldap1.resolver.dn.base.parameters= +ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid})) +ldap1.resolver.dn.filter.parameters=uid +ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.dn.filter.view=dn +ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap + +ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.ship.name=Ship Resolver +ldap1.resolver.ship.description=This resolves a subject's dn to a ship. +ldap1.resolver.ship.base=o=sevenseas +ldap1.resolver.ship.base.parameters= +ldap1.resolver.ship.filter=uniquemember=${dn} +ldap1.resolver.ship.filter.parameters=dn +ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.ship.filter.view=cn +ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship +ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap +
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties new file mode 100755 index 0000000..273f36d --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties
@@ -0,0 +1,6 @@ +xacml.rootPolicies=CSV-Legal-Age-Marriage-v1.xml +xacml.referencedPolicies= + + +CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml +
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml new file mode 100755 index 0000000..68c7783 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides"> + <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction. + +http://baseballhall.org/hall-famers/rules-election/bbwaa +</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Match> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>Active Timeframe: + +A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description> + <Target/> + <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit"> + <Description>Player's debut date >= (today's date - 20 years) AND final date <= (today's date - 5 years).</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>debut within 20 years AND final game more than 5 years ago.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal"> + <Description>Debut date <= (today's date - 20 years)</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> + <Description>UN-bag player's debut date.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration"> + <Description>Subtract 20 years from today's date.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> +<Description>UN-bag today's date.</Description> +<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal"> + <Description>Final Game <= (today's date - 5 years)</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> + <Description>UN-bag final game date</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration"> + <Description>Subtract 5 years from today's date.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> +<Description>UN-bag today's date.</Description> +<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue> + </Apply> + </Apply> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny"> + <Description>DENY - Default</Description> + <Target/> + </Rule> + </Policy> + <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description> + <Target/> + <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit"> + <Description>There should be >= 10 years of appearance(s) values.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal"> + <Description>The number of years a player appeared.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size"> + <Description>Count the number.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny"> + <Description>DENY - Default</Description> + <Target/> + </Rule> + </Policy> +</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties new file mode 100755 index 0000000..ebd0904 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties
@@ -0,0 +1,227 @@ +# PIP Engine Definition +# +xacml.pip.engines=csv1,csv2 + +ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone +CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie +CSO.mode=DEVL + +csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv1.name=Master +csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info +csv1.issuer=com:att:research:xacml:test:csv +csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt +csv1.maxsize=500000 +csv1.delimiter=, +csv1.quote=" +csv1.skip=0 + +csv1.resolvers=data + +csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv1.resolver.data.name=Player Resolver +csv1.resolver.data.description=This resolver finds player information in the Master table. +csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame +csv1.resolver.data.field.firstname.column=16 +csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname +csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.lastname.column=17 +csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname +csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathyear.column=10 +csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear +csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathmonth.column=11 +csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth +csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathday.column=12 +csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday +csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.debut.column=25 +csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut +csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.finalgame.column=26 +csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame +csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.parameters=playerid +csv1.resolver.data.parameter.playerid.column=1 +csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv2.name=Appearances +csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year. +#csv2.issuer= +csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt +csv2.maxsize=500000 +csv2.delimiter=, +csv2.quote=" +csv2.skip=0 + +csv2.resolvers=data + +csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv2.resolver.data.name=Appearance Resolver +csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table. +csv2.resolver.data.fields=appearance +csv2.resolver.data.field.appearance.column=0 +csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance +csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer +csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv + +csv2.resolver.data.parameters=playerid +csv2.resolver.data.parameter.playerid.column=3 +csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#csv1.resolver.data.parameter.playerid.issuer= + +hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine +hyper1.name=World Marriage Age Limits +hyper1.description=Minimum age for female/male marriages with or without their parental consent. +hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv +hyper1.target=marriage +hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20) + +hyper1.resolvers=age_consent + +hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +hyper1.resolver.age_consent.name=Ages +hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country. +hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=? +hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale + +hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female +hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male +hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female +hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male +hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.parameters=country +hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name +hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string +hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country +#hyper1.resolver.age_consent.parameter.country.issuer= + +sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine +sql1.name=World +sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures. +# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine. +sql1.issuer=com:att:research:xacml:test:sql +# +# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to +# create the tables and load the data. +# +sql1.type=jdbc +sql1.jdbc.driver=org.postgresql.Driver +#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world +#sql1.jdbc.conn.user=sa +#sql1.jdbc.conn.password= +sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world +sql1.jdbc.conn.user=pip +sql1.jdbc.conn.password=p1pUs3r +# +# This is the configuration for JNDI datasource. +# +#sql1.type=jndi +#sql1.datasource=jdbc/xacml + +sql1.resolvers=langer + +sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +sql1.resolver.langer.name=Language +sql1.resolver.langer.description=This returns the language for a city. +sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=? +sql1.resolver.langer.fields=language +sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language +sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +#You can override the default issuer that is set in the JDBCEngine definition if you want. +#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql +sql1.resolver.langer.parameters=name +sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id +sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource + + +ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine +ldap1.name=LDAP PIP +ldap1.description=The LDAP containing the seven seas sample LDIF data. +ldap1.issuer=com:att:research:xacml:test:ldap +ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory +# +# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before +# this example will work. +# +#ldap1.java.naming.provider.url=ldap://localhost:10389 +ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389 +#ldap.java.naming.security.principal= +#ldap.java.naming.security.credentials= +ldap1.scope=subtree + +ldap1.resolvers=dn,ship + +ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.dn.name=Domain Names +ldap1.resolver.dn.description=Find all the dn's for the subject id +ldap1.resolver.dn.base=o=sevenseas +ldap1.resolver.dn.base.parameters= +ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid})) +ldap1.resolver.dn.filter.parameters=uid +ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.dn.filter.view=dn +ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap + +ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.ship.name=Ship Resolver +ldap1.resolver.ship.description=This resolves a subject's dn to a ship. +ldap1.resolver.ship.base=o=sevenseas +ldap1.resolver.ship.base.parameters= +ldap1.resolver.ship.filter=uniquemember=${dn} +ldap1.resolver.ship.filter.parameters=dn +ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.ship.filter.view=cn +ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship +ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap +
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties new file mode 100755 index 0000000..59a8dd7 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties
@@ -0,0 +1,6 @@ +xacml.rootPolicies=CSV-Baseball-Hall-Of-Fame-v1.xml +xacml.referencedPolicies= + + +CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml +
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml new file mode 100755 index 0000000..9e36f68 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml
@@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:94378f81-6810-408f-a072-a1a8a7585a24" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>Sample policy that demonstrates use of Configurable LDAP Resolver with sample data. + +The PEP Request should provide the following attributes: +action-id=board +subject-id-qualifer=uid|mail +subject-id=hnelson|hnelson@royalnavy.mod.uk +resource-id=HMS Lydia|HMS Victory|HMS Bounty + </Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">board</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Rule RuleId="urn:com:att:xacml:rule:id:bf241671-54de-404c-ac59-bb17b919783f" Effect="Permit"> + <Description>This sailor is a member of the crew for the ship.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:ldap:subject:ship" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:ldap" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:490228ea-98ee-48d8-84c9-da07334726fd" Effect="Deny"> + <Description>Default is to DENY.</Description> + <Target/> + </Rule> +</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties new file mode 100755 index 0000000..deb58b4 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties
@@ -0,0 +1,227 @@ +# PIP Engine Definition +# +xacml.pip.engines=ldap1 + +ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone +CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie +CSO.mode=DEVL + +csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv1.name=Master +csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info +csv1.issuer=com:att:research:xacml:test:csv +csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt +csv1.maxsize=4000000 +csv1.delimiter=, +csv1.quote=" +csv1.skip=0 + +csv1.resolvers=data + +csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv1.resolver.data.name=Player Resolver +csv1.resolver.data.description=This resolver finds player information in the Master table. +csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame +csv1.resolver.data.field.firstname.column=16 +csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname +csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.lastname.column=17 +csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname +csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathyear.column=10 +csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear +csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathmonth.column=11 +csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth +csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathday.column=12 +csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday +csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.debut.column=25 +csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut +csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.finalgame.column=26 +csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame +csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.parameters=playerid +csv1.resolver.data.parameter.playerid.column=1 +csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv2.name=Appearances +csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year. +#csv2.issuer= +csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt +csv2.maxsize=4000000 +csv2.delimiter=, +csv2.quote=" +csv2.skip=0 + +csv2.resolvers=data + +csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv2.resolver.data.name=Appearance Resolver +csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table. +csv2.resolver.data.fields=appearance +csv2.resolver.data.field.appearance.column=0 +csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance +csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer +csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv + +csv2.resolver.data.parameters=playerid +csv2.resolver.data.parameter.playerid.column=3 +csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#csv1.resolver.data.parameter.playerid.issuer= + +hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine +hyper1.name=World Marriage Age Limits +hyper1.description=Minimum age for female/male marriages with or without their parental consent. +hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv +hyper1.target=marriage +hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20) + +hyper1.resolvers=age_consent + +hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +hyper1.resolver.age_consent.name=Ages +hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country. +hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=? +hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale + +hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female +hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male +hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female +hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male +hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.parameters=country +hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name +hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string +hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country +#hyper1.resolver.age_consent.parameter.country.issuer= + +sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine +sql1.name=World +sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures. +# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine. +sql1.issuer=com:att:research:xacml:test:sql +# +# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to +# create the tables and load the data. +# +sql1.type=jdbc +sql1.jdbc.driver=org.postgresql.Driver +#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world +#sql1.jdbc.conn.user=sa +#sql1.jdbc.conn.password= +sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world +sql1.jdbc.conn.user=pip +sql1.jdbc.conn.password=p1pUs3r +# +# This is the configuration for JNDI datasource. +# +#sql1.type=jndi +#sql1.datasource=jdbc/xacml + +sql1.resolvers=langer + +sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +sql1.resolver.langer.name=Language +sql1.resolver.langer.description=This returns the language for a city. +sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=? +sql1.resolver.langer.fields=language +sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language +sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +#You can override the default issuer that is set in the JDBCEngine definition if you want. +#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql +sql1.resolver.langer.parameters=name +sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id +sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource + + +ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine +ldap1.name=LDAP PIP +ldap1.description=The LDAP containing the seven seas sample LDIF data. +ldap1.issuer=com:att:research:xacml:test:ldap +ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory +# +# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before +# this example will work. +# +#ldap1.java.naming.provider.url=ldap://localhost:10389 +ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389 +#ldap.java.naming.security.principal= +#ldap.java.naming.security.credentials= +ldap1.scope=subtree + +ldap1.resolvers=dn,ship + +ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.dn.name=Domain Names +ldap1.resolver.dn.description=Find all the dn's for the subject id +ldap1.resolver.dn.base=o=sevenseas +ldap1.resolver.dn.base.parameters= +ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid})) +ldap1.resolver.dn.filter.parameters=uid +ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.dn.filter.view=dn +ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap + +ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.ship.name=Ship Resolver +ldap1.resolver.ship.description=This resolves a subject's dn to a ship. +ldap1.resolver.ship.base=o=sevenseas +ldap1.resolver.ship.base.parameters= +ldap1.resolver.ship.filter=uniquemember=${dn} +ldap1.resolver.ship.filter.parameters=dn +ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.ship.filter.view=cn +ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship +ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap +
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties new file mode 100755 index 0000000..df57627 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties
@@ -0,0 +1,5 @@ +xacml.rootPolicies=LDAP-Seven-Seas-v1.xml +xacml.referencedPolicies= + + +LDAP-Seven-Seas-v1.xml.url=http://localhost:9090/pap/?id=LDAP-Seven-Seas-v1.xml
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml new file mode 100755 index 0000000..85443dc --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml
@@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>Policy for speaking a language in a city.</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">speak</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit"> + <Description>PERMIT - People in this city speak my language.</Description> + <Target/> + <Condition> + <VariableReference VariableId="cityLanguage"/> + </Condition> + </Rule> + <VariableDefinition VariableId="cityLanguage"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in"> + <Description>The city's language must match exactly the subject's language.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:city:language" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:sql" MustBePresent="false"/> + </Apply> + </VariableDefinition> + <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny"> + <Description>DENY - default.</Description> + <Target/> + </Rule> +</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties new file mode 100755 index 0000000..dcfd4c8 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties
@@ -0,0 +1,227 @@ +# PIP Engine Definition +# +xacml.pip.engines=sql1 + +ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone +CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie +CSO.mode=DEVL + +csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv1.name=Master +csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info +csv1.issuer=com:att:research:xacml:test:csv +csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt +csv1.maxsize=4000000 +csv1.delimiter=, +csv1.quote=" +csv1.skip=0 + +csv1.resolvers=data + +csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv1.resolver.data.name=Player Resolver +csv1.resolver.data.description=This resolver finds player information in the Master table. +csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame +csv1.resolver.data.field.firstname.column=16 +csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname +csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.lastname.column=17 +csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname +csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathyear.column=10 +csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear +csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathmonth.column=11 +csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth +csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathday.column=12 +csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday +csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.debut.column=25 +csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut +csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.finalgame.column=26 +csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame +csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.parameters=playerid +csv1.resolver.data.parameter.playerid.column=1 +csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv2.name=Appearances +csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year. +#csv2.issuer= +csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt +csv2.maxsize=4000000 +csv2.delimiter=, +csv2.quote=" +csv2.skip=0 + +csv2.resolvers=data + +csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv2.resolver.data.name=Appearance Resolver +csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table. +csv2.resolver.data.fields=appearance +csv2.resolver.data.field.appearance.column=0 +csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance +csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer +csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv + +csv2.resolver.data.parameters=playerid +csv2.resolver.data.parameter.playerid.column=3 +csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#csv1.resolver.data.parameter.playerid.issuer= + +hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine +hyper1.name=World Marriage Age Limits +hyper1.description=Minimum age for female/male marriages with or without their parental consent. +hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv +hyper1.target=marriage +hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20) + +hyper1.resolvers=age_consent + +hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +hyper1.resolver.age_consent.name=Ages +hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country. +hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=? +hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale + +hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female +hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male +hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female +hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male +hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.parameters=country +hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name +hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string +hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country +#hyper1.resolver.age_consent.parameter.country.issuer= + +sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine +sql1.name=World +sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures. +# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine. +sql1.issuer=com:att:research:xacml:test:sql +# +# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to +# create the tables and load the data. +# +sql1.type=jdbc +sql1.jdbc.driver=org.postgresql.Driver +#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world +#sql1.jdbc.conn.user=sa +#sql1.jdbc.conn.password= +sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world +sql1.jdbc.conn.user=pip +sql1.jdbc.conn.password=p1pUs3r +# +# This is the configuration for JNDI datasource. +# +#sql1.type=jndi +#sql1.datasource=jdbc/xacml + +sql1.resolvers=langer + +sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +sql1.resolver.langer.name=Language +sql1.resolver.langer.description=This returns the language for a city. +sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=? +sql1.resolver.langer.fields=language +sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language +sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +#You can override the default issuer that is set in the JDBCEngine definition if you want. +#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql +sql1.resolver.langer.parameters=name +sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id +sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource + + +ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine +ldap1.name=LDAP PIP +ldap1.description=The LDAP containing the seven seas sample LDIF data. +ldap1.issuer=com:att:research:xacml:test:ldap +ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory +# +# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before +# this example will work. +# +#ldap1.java.naming.provider.url=ldap://localhost:10389 +ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389 +#ldap.java.naming.security.principal= +#ldap.java.naming.security.credentials= +ldap1.scope=subtree + +ldap1.resolvers=dn,ship + +ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.dn.name=Domain Names +ldap1.resolver.dn.description=Find all the dn's for the subject id +ldap1.resolver.dn.base=o=sevenseas +ldap1.resolver.dn.base.parameters= +ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid})) +ldap1.resolver.dn.filter.parameters=uid +ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.dn.filter.view=dn +ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap + +ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.ship.name=Ship Resolver +ldap1.resolver.ship.description=This resolves a subject's dn to a ship. +ldap1.resolver.ship.base=o=sevenseas +ldap1.resolver.ship.base.parameters= +ldap1.resolver.ship.filter=uniquemember=${dn} +ldap1.resolver.ship.filter.parameters=dn +ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.ship.filter.view=cn +ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship +ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap +
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties new file mode 100755 index 0000000..ed296ed --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties
@@ -0,0 +1,6 @@ +xacml.rootPolicies=SQL-World-Languages-v1.xml +xacml.referencedPolicies= + + +SQL-World-Languages-v1.xml.url=http://localhost:9090/pap/?id=SQL-World-Languages-v1.xml +
diff --git a/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml b/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml new file mode 100755 index 0000000..ae838f4 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml
@@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:5b82db34-1613-4108-8973-93074182dd94" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>A sample policy to demonstrate use of annotations in a Java class.</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">www.mywebsite.com</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Rule RuleId="urn:com:att:xacml:rule:id:8b257f30-4e06-4c8e-8fb7-691b9534d55c" Effect="Permit"> + <Description>PERMIT - John can access it</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">John</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESS</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:4fe7c147-7811-4e30-a463-9135afb1cfc2" Effect="Deny"> + <Description>DENY - Ringo cannot</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Ringo</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + </Rule> +</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml new file mode 100755 index 0000000..68c7783 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides"> + <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction. + +http://baseballhall.org/hall-famers/rules-election/bbwaa +</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Match> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>Active Timeframe: + +A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description> + <Target/> + <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit"> + <Description>Player's debut date >= (today's date - 20 years) AND final date <= (today's date - 5 years).</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>debut within 20 years AND final game more than 5 years ago.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal"> + <Description>Debut date <= (today's date - 20 years)</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> + <Description>UN-bag player's debut date.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration"> + <Description>Subtract 20 years from today's date.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> +<Description>UN-bag today's date.</Description> +<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal"> + <Description>Final Game <= (today's date - 5 years)</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> + <Description>UN-bag final game date</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration"> + <Description>Subtract 5 years from today's date.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only"> +<Description>UN-bag today's date.</Description> +<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue> + </Apply> + </Apply> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny"> + <Description>DENY - Default</Description> + <Target/> + </Rule> + </Policy> + <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description> + <Target/> + <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit"> + <Description>There should be >= 10 years of appearance(s) values.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal"> + <Description>The number of years a player appeared.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size"> + <Description>Count the number.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny"> + <Description>DENY - Default</Description> + <Target/> + </Rule> + </Policy> +</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml new file mode 100755 index 0000000..15e25ed --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides"> + <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit"> + <Description>Checks the subject. </Description> + <Target/> + <VariableDefinition VariableId="isSubjectFemale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>sex=Female</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="isSubjectMale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>subject sex=Male</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesSubjectNeedParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or"> + <Description>Is the subject a female OR male?</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is female AND does not need parental consent.</Description> + <VariableReference VariableId="isSubjectFemale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is subject male AND age >= male consent age.</Description> + <VariableReference VariableId="isSubjectMale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= legal age of consent for male.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute.</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesSubjectHaveParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </VariableDefinition> + <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit"> + <Description>If the subject does NOT need consent, then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit"> + <Description>If the subject needs consent AND has parental consent, then Permit.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesSubjectHaveParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </Apply> + </Condition> + </Rule> + </Policy> + <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit"> + <Description>Check the resource.</Description> + <Target/> + <VariableDefinition VariableId="isResourceFemale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>sex=Female</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="isResourceMale"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <Description>subject sex=Male</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesResourceNeedParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or"> + <Description>Is resource female OR male?</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is female AND does not need parental consent.</Description> + <VariableReference VariableId="isResourceFemale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age for female.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag attribute</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>un-bag attribute</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Description>Is male and AND does not need parental consent.</Description> + <VariableReference VariableId="isResourceMale"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than"> + <Description>age >= consent age for male.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <Description>Un-bag</Description> + <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/> + </Apply> + </Apply> + </Apply> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="doesResourceHaveParentalConsent"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </VariableDefinition> + <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit"> + <Description>If the resource does NOT need consent, then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit"> + <Description>The resources needs parental consent and has parental consent then PERMIT.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceNeedParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"> + <VariableReference VariableId="doesResourceHaveParentalConsent"/> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue> + </Apply> + </Apply> + </Condition> + </Rule> + </Policy> +</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml b/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml new file mode 100755 index 0000000..9e36f68 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml
@@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:94378f81-6810-408f-a072-a1a8a7585a24" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>Sample policy that demonstrates use of Configurable LDAP Resolver with sample data. + +The PEP Request should provide the following attributes: +action-id=board +subject-id-qualifer=uid|mail +subject-id=hnelson|hnelson@royalnavy.mod.uk +resource-id=HMS Lydia|HMS Victory|HMS Bounty + </Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">board</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Rule RuleId="urn:com:att:xacml:rule:id:bf241671-54de-404c-ac59-bb17b919783f" Effect="Permit"> + <Description>This sailor is a member of the crew for the ship.</Description> + <Target/> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:ldap:subject:ship" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:ldap" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + </Apply> + </Condition> + </Rule> + <Rule RuleId="urn:com:att:xacml:rule:id:490228ea-98ee-48d8-84c9-da07334726fd" Effect="Deny"> + <Description>Default is to DENY.</Description> + <Target/> + </Rule> +</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml b/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml new file mode 100755 index 0000000..85443dc --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml
@@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"> + <Description>Policy for speaking a language in a city.</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">speak</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit"> + <Description>PERMIT - People in this city speak my language.</Description> + <Target/> + <Condition> + <VariableReference VariableId="cityLanguage"/> + </Condition> + </Rule> + <VariableDefinition VariableId="cityLanguage"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in"> + <Description>The city's language must match exactly the subject's language.</Description> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/> + </Apply> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:city:language" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:sql" MustBePresent="false"/> + </Apply> + </VariableDefinition> + <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny"> + <Description>DENY - default.</Description> + <Target/> + </Rule> +</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties new file mode 100755 index 0000000..4d49be1 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties
@@ -0,0 +1,219 @@ +# PIP Engine Definition +# +xacml.pip.engines=csv1,csv2,hyper1,sql1,ldap1 + +csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv1.name=Master +csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info +csv1.issuer=com:att:research:xacml:test:csv +csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt +csv1.maxsize=500000 +csv1.delimiter=, +csv1.quote=" +csv1.skip=0 + +csv1.resolvers=data + +csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv1.resolver.data.name=Player Resolver +csv1.resolver.data.description=This resolver finds player information in the Master table. +csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame +csv1.resolver.data.field.firstname.column=16 +csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname +csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.lastname.column=17 +csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname +csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathyear.column=10 +csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear +csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathmonth.column=11 +csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth +csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathday.column=12 +csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday +csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.debut.column=25 +csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut +csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.finalgame.column=26 +csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame +csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.parameters=playerid +csv1.resolver.data.parameter.playerid.column=1 +csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv2.name=Appearances +csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year. +#csv2.issuer= +csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt +csv2.maxsize=500000 +csv2.delimiter=, +csv2.quote=" +csv2.skip=0 + +csv2.resolvers=data + +csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv2.resolver.data.name=Appearance Resolver +csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table. +csv2.resolver.data.fields=appearance +csv2.resolver.data.field.appearance.column=0 +csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance +csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer +csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv + +csv2.resolver.data.parameters=playerid +csv2.resolver.data.parameter.playerid.column=3 +csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#csv1.resolver.data.parameter.playerid.issuer= + +hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine +hyper1.name=World Marriage Age Limits +hyper1.description=Minimum age for female/male marriages with or without their parental consent. +hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv +hyper1.target=marriage +hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20) + +hyper1.resolvers=age_consent + +hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +hyper1.resolver.age_consent.name=Ages +hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country. +hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=? +hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale + +hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female +hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male +hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female +hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male +hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.parameters=country +hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name +hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string +hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country +#hyper1.resolver.age_consent.parameter.country.issuer= + +sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine +sql1.name=World +sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures. +# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine. +sql1.issuer=com:att:research:xacml:test:sql +# +# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to +# create the tables and load the data. +# +sql1.type=jdbc +sql1.jdbc.driver=org.postgresql.Driver +sql1.jdbc.url=jdbc:postgresql://localhost:5432/world +sql1.jdbc.conn.user=sa +sql1.jdbc.conn.password= +# +# This is the configuration for JNDI datasource. +# +#sql1.type=jndi +#sql1.datasource=jdbc/xacml + +sql1.resolvers=langer + +sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +sql1.resolver.langer.name=Language +sql1.resolver.langer.description=This returns the language for a city. +sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=? +sql1.resolver.langer.fields=language +sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language +sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +#You can override the default issuer that is set in the JDBCEngine definition if you want. +#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql +sql1.resolver.langer.parameters=name +sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id +sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource + + +ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine +ldap1.name=LDAP PIP +ldap1.description=The LDAP containing the seven seas sample LDIF data. +ldap1.issuer=com:att:research:xacml:test:ldap +ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory +# +# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before +# this example will work. +# +ldap1.java.naming.provider.url=ldap://localhost:10389 +#ldap.java.naming.security.principal= +#ldap.java.naming.security.credentials= +ldap1.scope=subtree + +ldap1.resolvers=dn,ship + +ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.dn.name=Domain Names +ldap1.resolver.dn.description=Find all the dn's for the subject id +ldap1.resolver.dn.base=o=sevenseas +ldap1.resolver.dn.base.parameters= +ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid})) +ldap1.resolver.dn.filter.parameters=uid +ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.dn.filter.view=dn +ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap + +ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.ship.name=Ship Resolver +ldap1.resolver.ship.description=This resolves a subject's dn to a ship. +ldap1.resolver.ship.base=o=sevenseas +ldap1.resolver.ship.base.parameters= +ldap1.resolver.ship.filter=uniquemember=${dn} +ldap1.resolver.ship.filter.parameters=dn +ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.ship.filter.view=cn +ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship +ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap +
diff --git a/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties new file mode 100755 index 0000000..78c4a85 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties
@@ -0,0 +1,14 @@ +xacml.rootPolicies=AnnotationPolicy.v1.xml,LDAP-Seven-Seas-v1.xml,CSV-Baseball-Hall-Of-Fame-v1.xml,CSV-Legal-Age-Marriage-v1.xml,SQL-World-Languages-v1.xml +xacml.referencedPolicies= + +AnnotationPolicy.v1.xml.url=http://localhost:9090/pap/?id=AnnotationPolicy.v1.xml + +LDAP-Seven-Seas-v1.xml.url=http://localhost:9090/pap/?id=LDAP-Seven-Seas-v1.xml + +CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml + +CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml + +SQL-World-Languages-v1.xml.url=http://localhost:9090/pap/?id=SQL-World-Languages-v1.xml + +
diff --git a/openaz-xacml-pap-rest/pdps/xacml.properties b/openaz-xacml-pap-rest/pdps/xacml.properties new file mode 100755 index 0000000..8429c20 --- /dev/null +++ b/openaz-xacml-pap-rest/pdps/xacml.properties
@@ -0,0 +1,27 @@ +# +#Mon Apr 21 11:22:57 EDT 2014 +xacml.pap.groups=default,configurable-csv,configurable-csv-hyper,configurable-ldap,configurable-sql,configurable-csv-and-hyper + +default.description=The default group where new PDP's are put. +default.name=default +default.pdps= + +configurable-csv.description=A group whose policies only serve configurable-csv requests. +configurable-csv.name=configurable-csv +configurable-csv.pdps= + +configurable-csv-hyper.description=A group whose policies only serve configurable-csv-hyper requests. +configurable-csv-hyper.name=configurable-csv-hyper +configurable-csv-hyper.pdps= + +configurable-ldap.description=A group whose policies only serve configurable-ldap requests. +configurable-ldap.name=configurable-ldap +configurable-ldap.pdps= + +configurable-sql.description=A group whose policies only serve configurable-sql requests. +configurable-sql.name=configurable-sql +configurable-sql.pdps= + +configurable-csv-and-hyper.description=A group whose policies serve both configurable-csv and configurable-csv-hyper requests but not others. +configurable-csv-and-hyper.name=configurable-csv-and-hyper +configurable-csv-and-hyper.pdps= \ No newline at end of file
diff --git a/openaz-xacml-pap-rest/pom.xml b/openaz-xacml-pap-rest/pom.xml new file mode 100755 index 0000000..d86600c --- /dev/null +++ b/openaz-xacml-pap-rest/pom.xml
@@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>openaz</artifactId> + <groupId>org.openliberty.openaz</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>openaz-xacml-pap-rest</artifactId> + + <dependencies> + <dependency> + <groupId>org.openliberty.openaz</groupId> + <artifactId>openaz-xacml</artifactId> + </dependency> + <dependency> + <groupId>org.openliberty.openaz</groupId> + <artifactId>openaz-xacml-rest</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + </dependencies> + +</project> \ No newline at end of file
diff --git a/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java b/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java new file mode 100755 index 0000000..e57a36b --- /dev/null +++ b/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java
@@ -0,0 +1,1529 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + + +import com.att.research.xacml.api.pap.*; +import com.att.research.xacml.std.pap.StdPDP; +import com.att.research.xacml.std.pap.StdPDPGroup; +import com.att.research.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChangeListener; +import com.att.research.xacml.std.pap.StdPDPStatus; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Splitter; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebInitParam; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Servlet implementation class XacmlPapServlet + * + * + * @author pameladragosh + */ +@WebServlet( + description = "Implements the XACML PAP RESTful API.", + urlPatterns = { "/" }, + loadOnStartup=1, + initParams = { + @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pap.properties", description = "The location of the properties file holding configuration information.") + }) + +public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeListener, Runnable { + private static final long serialVersionUID = 1L; + private static final Log logger = LogFactory.getLog(XACMLPapServlet.class); + + /* + * + * papEngine - This is our engine workhorse that manages the PDP Groups and Nodes. + */ + private PAPEngine papEngine = null; + + /* + * This PAP instance's own URL. + * + * Need this when creating URLs to send to the PDPs so they can GET the Policy files from this process. + */ + private static String papURL = null; + + /* + * List of Admin Console URLs. + * Used to send notifications when configuration changes. + * + * The CopyOnWriteArrayList *should* protect from concurrency errors. + * This list is seldom changed but often read, so the costs of this approach make sense. + */ + private static final CopyOnWriteArrayList<String> adminConsoleURLStringList = new CopyOnWriteArrayList<String>(); + + /* + * This thread may be invoked upon startup to initiate sending PDP policy/pip configuration when + * this servlet starts. Its configurable by the admin. + */ + private Thread initiateThread = null; + + /* + // The heartbeat thread. + */ + private static Heartbeat heartbeat = null; + private static Thread heartbeatThread = null; + + /** + * @see HttpServlet#HttpServlet() + */ + public XACMLPapServlet() { + super(); + } + + /** + * @see Servlet#init(ServletConfig) + */ + public void init(ServletConfig config) throws ServletException { + try { + // + // Initialize + // + XACMLRest.xacmlInit(config); + // + // Load the properties + // + XACMLRest.loadXacmlProperties(null, null); + // + // Load our PAP engine, first create a factory + // + PAPEngineFactory factory = PAPEngineFactory.newInstance(XACMLProperties.getProperty(XACMLProperties.PROP_PAP_PAPENGINEFACTORY)); + // + // The factory knows how to go about creating a PAP Engine + // + this.papEngine = factory.newEngine(); + // + // we are about to call the PDPs and give them their configuration. + // To do that we need to have the URL of this PAP so we can construct the Policy file URLs + // + XACMLPapServlet.papURL = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL); + // + // Sanity check that a URL was defined somewhere, its essential. + // + // How to check that its valid? We can validate the form, but since we are in the init() method we + // are not fully loaded yet so we really couldn't ping ourself to see if the URL will work. One + // will have to look for errors in the PDP logs to determine if they are failing to initiate a + // request to this servlet. + // + if (XACMLPapServlet.papURL == null) { + throw new PAPException("The property " + XACMLRestProperties.PROP_PAP_URL + " is not valid: " + XACMLPapServlet.papURL); + } + // + // Configurable - have the PAP servlet initiate sending the latest PDP policy/pip configuration + // to all its known PDP nodes. + // + // Note: parseBoolean will return false if there is no property defined. This is fine for a default. + // + if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INITIATE_PDP_CONFIG))) { + this.initiateThread = new Thread(this); + this.initiateThread.start(); + } + // + // After startup, the PAP does Heartbeats to each of the PDPs periodically + // + XACMLPapServlet.heartbeat = new Heartbeat(this.papEngine); + XACMLPapServlet.heartbeatThread = new Thread(XACMLPapServlet.heartbeat); + XACMLPapServlet.heartbeatThread.start(); + } catch (FactoryException | PAPException e) { + logger.error("Failed to create engine", e); + throw new ServletException ("PAP not initialized; error: "+e); + } catch (Exception e) { + logger.error("Failed to create engine - unexpected error: ", e); + throw new ServletException ("PAP not initialized; unexpected error: "+e); } + } + + /** + * Thread used only during PAP startup to initiate change messages to all known PDPs. + * This must be on a separate thread so that any GET requests from the PDPs during this update can be serviced. + */ + @Override + public void run() { + // + // send the current configuration to all the PDPs that we know about + // + changed(); + } + + + /** + * @see Servlet#destroy() + * + * Depending on how this servlet is run, we may or may not care about cleaning up the resources. + * For now we assume that we do care. + */ + public void destroy() { + // + // Make sure our threads are destroyed + // + if (XACMLPapServlet.heartbeatThread != null) { + // + // stop the heartbeat + // + try { + if (XACMLPapServlet.heartbeat != null) { + XACMLPapServlet.heartbeat.terminate(); + } + XACMLPapServlet.heartbeatThread.interrupt(); + XACMLPapServlet.heartbeatThread.join(); + } catch (InterruptedException e) { + logger.error(e); + } + } + if (this.initiateThread != null) { + try { + this.initiateThread.interrupt(); + this.initiateThread.join(); + } catch (InterruptedException e) { + logger.error(e); + } + } + } + + /** + * + * Called by: + * - PDP nodes to register themselves with the PAP, and + * - Admin Console to make changes in the PDP Groups. + * + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + + XACMLRest.dumpRequest(request); + + // since getParameter reads the content string, explicitly get the content before doing that. + // Simply getting the inputStream seems to protect it against being consumed by getParameter. + request.getInputStream(); + + // + // Is this from the Admin Console? + // + String groupId = request.getParameter("groupId"); + if (groupId != null) { + // + // this is from the Admin Console, so handle separately + // + doACPost(request, response, groupId); + return; + } + + // + // Request is from a PDP. + // It is coming up and asking for its config + // + + // + // Get the PDP's ID + // + String id = this.getPDPID(request); + logger.info("doPost from: " + id); + // + // Get the PDP Object + // + PDP pdp = this.papEngine.getPDP(id); + // + // Is it known? + // + if (pdp == null) { + logger.info("Unknown PDP: " + id); + try { + this.papEngine.newPDP(id, this.papEngine.getDefaultGroup(), id, "Registered on first startup"); + } catch (NullPointerException | PAPException e) { + logger.error("Failed to create new PDP", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return; + } + // get the PDP we just created + pdp = this.papEngine.getPDP(id); + if (pdp == null) { + String message = "Failed to create new PDP for id: " + id; + logger.error(message); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; + } + } + // + // Get the PDP's Group + // + PDPGroup group = this.papEngine.getPDPGroup(pdp); + if (group == null) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "PDP not associated with any group, even the default"); + return; + } + // + // Determine what group the PDP node is in and get + // its policy/pip properties. + // + Properties policies = group.getPolicyProperties(); + Properties pipconfig = group.getPipConfigProperties(); + // + // Get the current policy/pip configuration that the PDP has + // + Properties pdpProperties = new Properties(); + pdpProperties.load(request.getInputStream()); + logger.info("PDP Current Properties: " + pdpProperties.toString()); + logger.info("Policies: " + (policies != null ? policies.toString() : "null")); + logger.info("Pip config: " + (pipconfig != null ? pipconfig.toString() : "null")); + // + // Validate the node's properties + // + boolean isCurrent = this.isPDPCurrent(policies, pipconfig, pdpProperties); + // + // Send back current configuration + // + if (isCurrent == false) { + // + // Tell the PDP we are sending back the current policies/pip config + // + logger.info("PDP configuration NOT current."); + if (policies != null) { + // + // Put URL's into the properties in case the PDP needs to + // retrieve them. + // + this.populatePolicyURL(request.getRequestURL(), policies); + // + // Copy the properties to the output stream + // + policies.store(response.getOutputStream(), ""); + } + if (pipconfig != null) { + // + // Copy the properties to the output stream + // + pipconfig.store(response.getOutputStream(), ""); + } + // + // We are good - and we are sending them information + // + response.setStatus(HttpServletResponse.SC_OK); +//TODO - Correct? + setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH); + } else { + // + // Tell them they are good + // + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + + //TODO - Correct? + setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE); + + } + // + // tell the AC that something changed + // + notifyAC(); + } catch (PAPException e) { + logger.debug("POST exception: " + e, e); + response.sendError(500, e.getMessage()); + return; + } + } + + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + XACMLRest.dumpRequest(request); + + // Is this from the Admin Console? + String groupId = request.getParameter("groupId"); + if (groupId != null) { + // this is from the Admin Console, so handle separately + doACGet(request, response, groupId); + return; + } + // + // Get the PDP's ID + // + String id = this.getPDPID(request); + logger.info("doGet from: " + id); + // + // Get the PDP Object + // + PDP pdp = this.papEngine.getPDP(id); + // + // Is it known? + // + if (pdp == null) { + // + // Check if request came from localhost + // + String message = "Unknown PDP: " + id + " from " + request.getRemoteHost() + " us: " + request.getLocalAddr(); + logger.info(message); + if (request.getRemoteHost().equals("localhost") || + request.getRemoteHost().equals("127.0.0.1") || + request.getRemoteHost().equals(request.getLocalAddr())) { + // + // Return status information - basically all the groups + // + Set<PDPGroup> groups = papEngine.getPDPGroups(); + + // convert response object to JSON and include in the response + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), groups); + response.setHeader("content-type", "application/json"); + response.setStatus(HttpServletResponse.SC_OK); + return; + } + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message); + return; + } + // + // Get the PDP's Group + // + PDPGroup group = this.papEngine.getPDPGroup(pdp); + if (group == null) { + String message = "No group associated with pdp " + pdp.getId(); + logger.warn(message); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message); + return; + } + // + // Which policy do they want? + // + String policyId = request.getParameter("id"); + if (policyId == null) { + String message = "Did not specify an id for the policy"; + logger.warn(message); + response.sendError(HttpServletResponse.SC_NOT_FOUND, message); + return; + } + PDPPolicy policy = group.getPolicy(policyId); + if (policy == null) { + String message = "Unknown policy: " + policyId; + logger.warn(message); + response.sendError(HttpServletResponse.SC_NOT_FOUND, message); + return; + } + // + // Get its stream + // + try (InputStream is = policy.getStream(); OutputStream os = response.getOutputStream()) { + // + // Send the policy back + // + IOUtils.copy(is, os); + + response.setStatus(HttpServletResponse.SC_OK); + } catch (PAPException e) { + String message = "Failed to open policy id " + policyId; + logger.error(message); + response.sendError(HttpServletResponse.SC_NOT_FOUND, message); + } + } catch (PAPException e) { + logger.error("GET exception: " + e, e); + response.sendError(500, e.getMessage()); + return; + } + } + + protected String getPDPID(HttpServletRequest request) { + String pdpURL = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID); + if (pdpURL == null || pdpURL.isEmpty()) { + // + // Should send back its port for identification + // + logger.warn("PDP did not send custom header"); + pdpURL = ""; + } + return pdpURL; + } + + private boolean isPDPCurrent(Properties policies, Properties pipconfig, Properties pdpProperties) { + String localRootPolicies = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES); + String localReferencedPolicies = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES); + if (localRootPolicies == null || localReferencedPolicies == null) { + logger.warn("Missing property on PAP server: RootPolicies="+localRootPolicies+" ReferencedPolicies="+localReferencedPolicies); + return false; + } + // + // Compare the policies and pipconfig properties to the pdpProperties + // + try { + // + // the policy properties includes only xacml.rootPolicies and + // xacml.referencedPolicies without any .url entries + // + Properties pdpPolicies = XACMLProperties.getPolicyProperties(pdpProperties, false); + Properties pdpPipConfig = XACMLProperties.getPipProperties(pdpProperties); + if (localRootPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_ROOTPOLICIES)) && + localReferencedPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES)) && + pdpPipConfig.equals(pipconfig)) { + // + // The PDP is current + // + return true; + } + } catch (Exception e) { + // we get here if the PDP did not include either xacml.rootPolicies or xacml.pip.engines, + // or if there are policies that do not have a corresponding ".url" property. + // Either of these cases means that the PDP is not up-to-date, so just drop-through to return false. + } + return false; + } + + private void populatePolicyURL(StringBuffer urlPath, Properties policies) { + String lists[] = new String[2]; + lists[0] = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES); + lists[1] = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES); + for (String list : lists) { + if (list != null && list.isEmpty() == false) { + for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(list)) { + String url = urlPath + "?id=" + id; + logger.info("Policy URL for " + id + ": " + url); + policies.setProperty(id + ".url", url); + } + } + } + } + + + /** + * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + XACMLRest.dumpRequest(request); + // + // since getParameter reads the content string, explicitly get the content before doing that. + // Simply getting the inputStream seems to protect it against being consumed by getParameter. + // + request.getInputStream(); + // + // See if this is Admin Console registering itself with us + // + String acURLString = request.getParameter("adminConsoleURL"); + if (acURLString != null) { + // + // remember this Admin Console for future updates + // + if ( ! adminConsoleURLStringList.contains(acURLString)) { + adminConsoleURLStringList.add(acURLString); + } + if (logger.isDebugEnabled()) { + logger.debug("Admin Console registering with URL: " + acURLString); + } + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + return; + } + // + // Is this some other operation from the Admin Console? + // + String groupId = request.getParameter("groupId"); + if (groupId != null) { + // + // this is from the Admin Console, so handle separately + // + doACPut(request, response, groupId); + return; + } + // + // We do not expect anything from anywhere else. + // This method is here in case we ever need to support other operations. + // + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId"); + } + + /** + * @see HttpServlet#doDelete(HttpServletRequest request, HttpServletResponse response) + */ + protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + XACMLRest.dumpRequest(request); + // + // Is this from the Admin Console? + // + String groupId = request.getParameter("groupId"); + if (groupId != null) { + // + // this is from the Admin Console, so handle separately + // + doACDelete(request, response, groupId); + return; + } + // + // We do not expect anything from anywhere else. + // This method is here in case we ever need to support other operations. + // + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId"); + } + // + // Admin Console request handling + // + + /** + * Requests from the Admin Console to GET info about the Groups and PDPs + * + * @param request + * @param response + * @param groupId + * @throws ServletException + * @throws java.io.IOException + */ + private void doACGet(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException { + try { + String parameterDefault = request.getParameter("default"); + String pdpId = request.getParameter("pdpId"); + String pdpGroup = request.getParameter("getPDPGroup"); + if ("".equals(groupId)) { + // request IS from AC but does not identify a group by name + if (parameterDefault != null) { + // Request is for the Default group (whatever its id) + PDPGroup group = papEngine.getDefaultGroup(); + + // convert response object to JSON and include in the response + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), group); + + if (logger.isDebugEnabled()) { + logger.debug("GET Default group req from '" + request.getRequestURL() + "'"); + } + response.setStatus(HttpServletResponse.SC_OK); + response.setHeader("content-type", "application/json"); + response.getOutputStream().close(); + return; + + } else if (pdpId != null) { + // Request is related to a PDP + if (pdpGroup == null) { + // Request is for the PDP itself + // Request is for the (unspecified) group containing a given PDP + PDP pdp = papEngine.getPDP(pdpId); + + // convert response object to JSON and include in the response + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), pdp); + + if (logger.isDebugEnabled()) { + logger.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'"); + } + response.setStatus(HttpServletResponse.SC_OK); + response.setHeader("content-type", "application/json"); + response.getOutputStream().close(); + return; + + } else { + // Request is for the (unspecified) group containing a given PDP + PDP pdp = papEngine.getPDP(pdpId); + PDPGroup group = papEngine.getPDPGroup(pdp); + + // convert response object to JSON and include in the response + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), group); + + if (logger.isDebugEnabled()) { + logger.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'"); + } + response.setStatus(HttpServletResponse.SC_OK); + response.setHeader("content-type", "application/json"); + response.getOutputStream().close(); + return; + } + + } else { + // request is for top-level properties about all groups + Set<PDPGroup> groups = papEngine.getPDPGroups(); + + // convert response object to JSON and include in the response + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), groups); + +//TODO +// In "notification" section, ALSO need to tell AC about other changes (made by other ACs)?' +//TODO add new PDP notification (or just "config changed" notification) in appropriate place + if (logger.isDebugEnabled()) { + logger.debug("GET All groups req"); + } + response.setStatus(HttpServletResponse.SC_OK); + response.setHeader("content-type", "application/json"); + response.getOutputStream().close(); + return; + } + } + + // for all other GET operations the group must exist before the operation can be done + PDPGroup group = papEngine.getGroup(groupId); + if (group == null) { + logger.error("Unknown groupId '" + groupId + "'"); + response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'"); + return; + } + + + // Figure out which request this is based on the parameters + String policyId = request.getParameter("policyId"); + + if (policyId != null) { +// // retrieve a policy +// PDPPolicy policy = papEngine.getPDPPolicy(policyId); +// +// // convert response object to JSON and include in the response +// ObjectMapper mapper = new ObjectMapper(); +// mapper.writeValue(response.getOutputStream(), pdp); +// +// logger.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'"); +// response.setStatus(HttpServletResponse.SC_OK); +// response.setHeader("content-type", "application/json"); +// response.getOutputStream().close(); +// return; + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented"); + + } else { + // No other parameters, so return the identified Group + + // convert response object to JSON and include in the response + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), group); + + if (logger.isDebugEnabled()) { + logger.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'"); + } + response.setStatus(HttpServletResponse.SC_OK); + response.setHeader("content-type", "application/json"); + response.getOutputStream().close(); + return; + } + + // + // Currently there are no other GET calls from the AC. + // The AC uses the "GET All Groups" operation to fill its local cache and uses that cache for all other GETs without calling the PAP. + // Other GETs that could be called: + // Specific Group (groupId=<groupId>) + // A Policy (groupId=<groupId> policyId=<policyId>) + // A PDP (groupId=<groupId> pdpId=<pdpId>) + + //TODO - implement other GET operations if needed + + logger.error("UNIMPLEMENTED "); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); + } catch (PAPException e) { + logger.error("AC Get exception: " + e, e); + response.sendError(500, e.getMessage()); + return; + } + + } + + + /** + * Requests from the Admin Console for operations not on single specific objects + * + * @param request + * @param response + * @param groupId + * @throws ServletException + * @throws java.io.IOException + */ + private void doACPost(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException { + try { + String groupName = request.getParameter("groupName"); + String groupDescription = request.getParameter("groupDescription"); + if (groupName != null && groupDescription != null) { + // Args: group=<groupId> groupName=<name> groupDescription=<description> <= create a new group + String unescapedName = URLDecoder.decode(groupName, "UTF-8"); + String unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8"); + try { + papEngine.newGroup(unescapedName, unescapedDescription); + } catch (Exception e) { + logger.error("Unable to create new group: " + e.getLocalizedMessage()); + response.sendError(500, "Unable to create new group '" + groupId + "'"); + return; + } + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + if (logger.isDebugEnabled()) { + logger.debug("New Group '" + groupId + "' created"); + } + // tell the Admin Consoles there is a change + notifyAC(); + // new group by definition has no PDPs, so no need to notify them of changes + return; + } + + // for all remaining POST operations the group must exist before the operation can be done + PDPGroup group = papEngine.getGroup(groupId); + if (group == null) { + logger.error("Unknown groupId '" + groupId + "'"); + response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'"); + return; + } + + // determine the operation needed based on the parameters in the request + if (request.getParameter("policyId") != null) { + // Args: group=<groupId> policy=<policyId> <= copy file + // copy a policy from the request contents into a file in the group's directory on this machine + String policyId = request.getParameter("policyId"); + try { + ((StdPDPGroup) group).copyPolicyToFile(policyId, request.getInputStream()); + } catch (Exception e) { + String message = "Policy '" + policyId + "' not copied to group '" + groupId +"': " + e; + logger.error(message); + response.sendError(500, message); + return; + } + // policy file copied ok + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + if (logger.isDebugEnabled()) { + logger.debug("policy '" + policyId + "' copied to directory for group '" + groupId + "'"); + } + return; + + } else if (request.getParameter("default") != null) { + // Args: group=<groupId> default=true <= make default + // change the current default group to be the one identified in the request. + // + // This is a POST operation rather than a PUT "update group" because of the side-effect that the current default group is also changed. + // It should never be the case that multiple groups are currently marked as the default, but protect against that anyway. + try { + papEngine.SetDefaultGroup(group); + } catch (Exception e) { + logger.error("Unable to set group: " + e.getLocalizedMessage()); + response.sendError(500, "Unable to set group '" + groupId + "' to default"); + return; + } + + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + if (logger.isDebugEnabled()) { + logger.debug("Group '" + groupId + "' set to be default"); + } + // Notify the Admin Consoles that something changed + // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that +//TODO - Future: FIGURE OUT WHAT LEVEL TO NOTIFY: 2 groups or entire set - currently notify AC to update whole configuration of all groups + notifyAC(); + // This does not affect any PDPs in the existing groups, so no need to notify them of this change + return; + + } else if (request.getParameter("pdpId") != null) { + // Args: group=<groupId> pdpId=<pdpId> <= move PDP to group + String pdpId = request.getParameter("pdpId"); + PDP pdp = papEngine.getPDP(pdpId); + + PDPGroup originalGroup = papEngine.getPDPGroup(pdp); + + papEngine.movePDP(pdp, group); + + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + if (logger.isDebugEnabled()) { + logger.debug("PDP '" + pdp.getId() +"' moved to group '" + group.getId() + "' set to be default"); + } + + // update the status of both the original group and the new one + ((StdPDPGroup)originalGroup).resetStatus(); + ((StdPDPGroup)group).resetStatus(); + + // Notify the Admin Consoles that something changed + // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that + notifyAC(); + // Need to notify the PDP that it's config may have changed + pdpChanged(pdp); + return; + + + } + } catch (PAPException e) { + logger.error("AC POST exception: " + e, e); + response.sendError(500, e.getMessage()); + return; + } + } + + /** + * Requests from the Admin Console to create new items or update existing ones + * + * @param request + * @param response + * @param groupId + * @throws ServletException + * @throws java.io.IOException + */ + private void doACPut(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException { + try { + + + // for PUT operations the group may or may not need to exist before the operation can be done + PDPGroup group = papEngine.getGroup(groupId); + + // determine the operation needed based on the parameters in the request + + // for remaining operations the group must exist before the operation can be done + if (group == null) { + logger.error("Unknown groupId '" + groupId + "'"); + response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'"); + return; + } + if (request.getParameter("policy") != null) { + // group=<groupId> policy=<policyId> contents=policy file <= Create new policy file in group dir, or replace it if it already exists (do not touch properties) + //TODO - currently this is done by the AC, but it should be done here by getting the policy file out of the contents and saving to disk + logger.error("PARTIALLY IMPLEMENTED!!! ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! "); + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + return; + } else if (request.getParameter("pdpId") != null) { + // ARGS: group=<groupId> pdpId=<pdpId/URL> <= create a new PDP or Update an Existing one + + String pdpId = request.getParameter("pdpId"); + + // get the request content into a String + String json = null; + // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file) + java.util.Scanner scanner = new java.util.Scanner(request.getInputStream()); + scanner.useDelimiter("\\A"); + json = scanner.hasNext() ? scanner.next() : ""; + scanner.close(); + logger.info("JSON request from AC: " + json); + + // convert Object sent as JSON into local object + ObjectMapper mapper = new ObjectMapper(); + + Object objectFromJSON = mapper.readValue(json, StdPDP.class); + + if (pdpId == null || + objectFromJSON == null || + ! (objectFromJSON instanceof StdPDP) || + ((StdPDP)objectFromJSON).getId() == null || + ! ((StdPDP)objectFromJSON).getId().equals(pdpId)) { + logger.error("PDP new/update had bad input. pdpId=" + pdpId + " objectFromJSON="+objectFromJSON); + response.sendError(500, "Bad input, pdpid="+pdpId+" object="+objectFromJSON); + } + StdPDP pdp = (StdPDP) objectFromJSON; + + if (papEngine.getPDP(pdpId) == null) { + // this is a request to create a new PDP object + papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription()); + } else { + // this is a request to update the pdp + papEngine.updatePDP(pdp); + } + + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + if (logger.isDebugEnabled()) { + logger.debug("PDP '" + pdpId + "' created/updated"); + } + + // adjust the group's state including the new PDP + ((StdPDPGroup)group).resetStatus(); + + // tell the Admin Consoles there is a change + notifyAC(); + // this might affect the PDP, so notify it of the change + pdpChanged(pdp); + return; + } else if (request.getParameter("pipId") != null) { + // group=<groupId> pipId=<pipEngineId> contents=pip properties <= add a PIP to pip config, or replace it if it already exists (lenient operation) + //TODO + logger.error("UNIMPLEMENTED "); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); + return; + } else { + // Assume that this is an update of an existing PDP Group + // ARGS: group=<groupId> <= Update an Existing Group + + // get the request content into a String + String json = null; + // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file) + java.util.Scanner scanner = new java.util.Scanner(request.getInputStream()); + scanner.useDelimiter("\\A"); + json = scanner.hasNext() ? scanner.next() : ""; + scanner.close(); + logger.info("JSON request from AC: " + json); + + // convert Object sent as JSON into local object + ObjectMapper mapper = new ObjectMapper(); + + Object objectFromJSON = mapper.readValue(json, StdPDPGroup.class); + + if (objectFromJSON == null || + ! (objectFromJSON instanceof StdPDPGroup) || + ! ((StdPDPGroup)objectFromJSON).getId().equals(group.getId())) { + logger.error("Group update had bad input. id=" + group.getId() + " objectFromJSON="+objectFromJSON); + response.sendError(500, "Bad input, id="+group.getId() +" object="+objectFromJSON); + } + + // The Path on the PAP side is not carried on the RESTful interface with the AC + // (because it is local to the PAP) + // so we need to fill that in before submitting the group for update + ((StdPDPGroup)objectFromJSON).setDirectory(((StdPDPGroup)group).getDirectory()); + + papEngine.updateGroup((StdPDPGroup)objectFromJSON); + + + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + if (logger.isDebugEnabled()) { + logger.debug("Group '" + group.getId() + "' updated"); + } + // tell the Admin Consoles there is a change + notifyAC(); + // Group changed, which might include changing the policies + groupChanged(group); + return; + } + } catch (PAPException e) { + logger.error("AC PUT exception: " + e, e); + response.sendError(500, e.getMessage()); + return; + } + } + + /** + * Requests from the Admin Console to delete/remove items + * + * @param request + * @param response + * @param groupId + * @throws ServletException + * @throws java.io.IOException + */ + private void doACDelete(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException { + try { + // for all DELETE operations the group must exist before the operation can be done + PDPGroup group = papEngine.getGroup(groupId); + if (group == null) { + logger.error("Unknown groupId '" + groupId + "'"); + response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'"); + return; + } + // determine the operation needed based on the parameters in the request + if (request.getParameter("policy") != null) { + // group=<groupId> policy=<policyId> [delete=<true|false>] <= delete policy file from group + //TODO + logger.error("UNIMPLEMENTED "); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); + return; + } else if (request.getParameter("pdpId") != null) { + // ARGS: group=<groupId> pdpId=<pdpId> <= delete PDP + String pdpId = request.getParameter("pdpId"); + PDP pdp = papEngine.getPDP(pdpId); + + papEngine.removePDP(pdp); + + // adjust the status of the group, which may have changed when we removed this PDP + ((StdPDPGroup)group).resetStatus(); + + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + notifyAC(); + + // update the PDP and tell it that it has NO Policies (which prevents it from serving PEP Requests) + pdpChanged(pdp); + return; + } else if (request.getParameter("pipId") != null) { + // group=<groupId> pipId=<pipEngineId> <= delete PIP config for given engine + //TODO + logger.error("UNIMPLEMENTED "); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); + return; + } else { + // ARGS: group=<groupId> movePDPsToGroupId=<movePDPsToGroupId> <= delete a group and move all its PDPs to the given group + String moveToGroupId = request.getParameter("movePDPsToGroupId"); + PDPGroup moveToGroup = null; + if (moveToGroupId != null) { + moveToGroup = papEngine.getGroup(moveToGroupId); + } + + // get list of PDPs in the group being deleted so we can notify them that they got changed + Set<PDP> movedPDPs = new HashSet<PDP>(); + movedPDPs.addAll(group.getPdps()); + + // do the move/remove + papEngine.removeGroup(group, moveToGroup); + + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + notifyAC(); + // notify any PDPs in the removed set that their config may have changed + for (PDP pdp : movedPDPs) { + pdpChanged(pdp); + } + return; + } + + } catch (PAPException e) { + logger.error("AC DELETE exception: " + e, e); + response.sendError(500, e.getMessage()); + return; + } + } + + // + // Heartbeat thread - periodically check on PDPs' status + // + + /** + * Heartbeat with all known PDPs. + * + * Implementation note: + * + * The PDPs are contacted Sequentially, not in Parallel. + * + * If we did this in parallel using multiple threads we would simultaneously use + * - 1 thread and + * - 1 connection + * for EACH PDP. + * This could become a resource problem since we already use multiple threads and connections for updating the PDPs + * when user changes occur. + * Using separate threads can also make it tricky dealing with timeouts on PDPs that are non-responsive. + * + * The Sequential operation does a heartbeat request to each PDP one at a time. + * This has the flaw that any PDPs that do not respond will hold up the entire heartbeat sequence until they timeout. + * If there are a lot of non-responsive PDPs and the timeout is large-ish (the default is 20 seconds) + * it could take a long time to cycle through all of the PDPs. + * That means that this may not notice a PDP being down in a predictable time. + * + * @author glenngriffin + * + */ + private class Heartbeat implements Runnable { + private PAPEngine papEngine; + private Set<PDP> pdps = new HashSet<PDP>(); + private int heartbeatInterval; + private int heartbeatTimeout; + + public volatile boolean isRunning = false; + + public synchronized boolean isRunning() { + return this.isRunning; + } + + public synchronized void terminate() { + this.isRunning = false; + } + + public Heartbeat(PAPEngine engine) { + this.papEngine = engine; + this.heartbeatInterval = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_INTERVAL, "10000")); + this.heartbeatTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_TIMEOUT, "10000")); + } + + @Override + public void run() { + // + // Set ourselves as running + // + synchronized(this) { + this.isRunning = true; + } + HashMap<String, URL> idToURLMap = new HashMap<String, URL>(); + try { + while (this.isRunning()) { + // Wait the given time + Thread.sleep(heartbeatInterval); + + // get the list of PDPs (may have changed since last time) + pdps.clear(); + synchronized(papEngine) { + try { + for (PDPGroup g : papEngine.getPDPGroups()) { + for (PDP p : g.getPdps()) { + pdps.add(p); + } + } + } catch (PAPException e) { + logger.error("Heartbeat unable to read PDPs from PAPEngine: " + e.getMessage(), e); + } + } + // + // Check for shutdown + // + if (this.isRunning() == false) { + logger.info("isRunning is false, getting out of loop."); + break; + } + + // try to get the summary status from each PDP + boolean changeSeen = false; + for (PDP pdp : pdps) { + // + // Check for shutdown + // + if (this.isRunning() == false) { + logger.info("isRunning is false, getting out of loop."); + break; + } + // the id of the PDP is its url (though we add a query parameter) + URL pdpURL = idToURLMap.get(pdp.getId()); + if (pdpURL == null) { + // haven't seen this PDP before + String fullURLString = null; + try { + fullURLString = pdp.getId() + "?type=hb"; + pdpURL = new URL(fullURLString); + idToURLMap.put(pdp.getId(), pdpURL); + } catch (MalformedURLException e) { + logger.error("PDP id '" + fullURLString + "' is not a valid URL: " + e, e); + continue; + } + } + + // Do a GET with type HeartBeat + String newStatus = ""; + + HttpURLConnection connection = null; + try { + + // + // Open up the connection + // + connection = (HttpURLConnection)pdpURL.openConnection(); + // + // Setup our method and headers + // + connection.setRequestMethod("GET"); + connection.setConnectTimeout(heartbeatTimeout); + // + // Do the connect + // + connection.connect(); + if (connection.getResponseCode() == 204) { + newStatus = connection.getHeaderField(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB); + if (logger.isDebugEnabled()) { + logger.debug("Heartbeat '" + pdp.getId() + "' status='" + newStatus + "'"); + } + } else { + // anything else is an unexpected result + newStatus = PDPStatus.Status.UNKNOWN.toString(); + logger.error("Heartbeat connect response code " + connection.getResponseCode() + ": " + pdp.getId()); + } + } catch (UnknownHostException e) { + newStatus = PDPStatus.Status.NO_SUCH_HOST.toString(); + logger.error("Heartbeat '" + pdp.getId() + "' NO_SUCH_HOST"); + } catch (SocketTimeoutException e) { + newStatus = PDPStatus.Status.CANNOT_CONNECT.toString(); + logger.error("Heartbeat '" + pdp.getId() + "' connection timeout: " + e ); + } catch (ConnectException e) { + newStatus = PDPStatus.Status.CANNOT_CONNECT.toString(); + logger.error("Heartbeat '" + pdp.getId() + "' cannot connect: " + e ); + } catch (Exception e) { + newStatus = PDPStatus.Status.UNKNOWN.toString(); + logger.error("Heartbeat '" + pdp.getId() + "' connect exception: " + e, e); + } finally { + // cleanup the connection + connection.disconnect(); + } + + if ( ! pdp.getStatus().getStatus().toString().equals(newStatus)) { + if (logger.isDebugEnabled()) { + logger.debug("previous status='" + pdp.getStatus().getStatus()+"' new Status='" + newStatus + "'"); + } + try { + setPDPSummaryStatus(pdp, newStatus); + } catch (PAPException e) { + logger.error("Unable to set state for PDP '" + pdp.getId() + "': " + e, e); + } + changeSeen = true; + } + + } + // + // Check for shutdown + // + if (this.isRunning() == false) { + logger.info("isRunning is false, getting out of loop."); + break; + } + + // if any of the PDPs changed state, tell the ACs to update + if (changeSeen) { + notifyAC(); + } + + } + } catch (InterruptedException e) { + logger.error("Heartbeat interrupted. Shutting down"); + this.terminate(); + } + } + } + + + // + // HELPER to change Group status when PDP status is changed + // + // (Must NOT be called from a method that is synchronized on the papEngine or it may deadlock) + // + + private void setPDPSummaryStatus(PDP pdp, PDPStatus.Status newStatus) throws PAPException { + setPDPSummaryStatus(pdp, newStatus.toString()); + } + + private void setPDPSummaryStatus(PDP pdp, String newStatus) throws PAPException { + synchronized(papEngine) { + StdPDPStatus status = (StdPDPStatus)pdp.getStatus(); + status.setStatus(PDPStatus.Status.valueOf(newStatus)); + ((StdPDP)pdp).setStatus(status); + + // now adjust the group + StdPDPGroup group = (StdPDPGroup)papEngine.getPDPGroup(pdp); + // if the PDP was just deleted it may transiently exist but not be in a group + if (group != null) { + group.resetStatus(); + } + } + } + + + // + // Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine + // in the PDP group directories + // + + @Override + public void changed() { + // all PDPs in all groups need to be updated/sync'd + Set<PDPGroup> groups; + try { + groups = papEngine.getPDPGroups(); + } catch (PAPException e) { + logger.error("getPDPGroups failed: " + e.getLocalizedMessage()); + throw new RuntimeException("Unable to get Groups: " + e); + } + for (PDPGroup group : groups) { + groupChanged(group); + } + } + + @Override + public void groupChanged(PDPGroup group) { + // all PDPs within one group need to be updated/sync'd + for (PDP pdp : group.getPdps()) { + pdpChanged(pdp); + } + } + + @Override + public void pdpChanged(PDP pdp) { + // kick off a thread to do an event notification for each PDP. + // This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc) + // do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or time-out. + Thread t = new Thread(new UpdatePDPThread(pdp)); + t.start(); + } + + private class UpdatePDPThread implements Runnable { + private PDP pdp; + + // remember which PDP to notify + public UpdatePDPThread(PDP pdp) { + this.pdp = pdp; + } + + public void run() { + // send the current configuration to one PDP + HttpURLConnection connection = null; + try { + + // + // the Id of the PDP is its URL + // + if (logger.isDebugEnabled()) { + logger.debug("creating url for id '" + pdp.getId() + "'"); + } + //TODO - currently always send both policies and pips. Do we care enough to add code to allow sending just one or the other? + //TODO (need to change "cache=", implying getting some input saying which to change) + URL url = new URL(pdp.getId() + "?cache=all"); + + // + // Open up the connection + // + connection = (HttpURLConnection)url.openConnection(); + // + // Setup our method and headers + // + connection.setRequestMethod("PUT"); + // connection.setRequestProperty("Accept", "text/x-java-properties"); + connection.setRequestProperty("Content-Type", "text/x-java-properties"); + // connection.setUseCaches(false); + // + // Adding this in. It seems the HttpUrlConnection class does NOT + // properly forward our headers for POST re-direction. It does so + // for a GET re-direction. + // + // So we need to handle this ourselves. + // + //TODO - is this needed for a PUT? seems better to leave in for now? +// connection.setInstanceFollowRedirects(false); + // + // PLD - MUST be able to handle re-directs. + // + connection.setInstanceFollowRedirects(true); + connection.setDoOutput(true); + // connection.setDoInput(true); + try (OutputStream os = connection.getOutputStream()) { + + PDPGroup group = papEngine.getPDPGroup(pdp); + // if the PDP was just deleted, there is no group, but we want to send an update anyway + if (group == null) { + // create blank properties files + Properties policyProperties = new Properties(); + policyProperties.put(XACMLProperties.PROP_ROOTPOLICIES, ""); + policyProperties.put(XACMLProperties.PROP_REFERENCEDPOLICIES, ""); + policyProperties.store(os, ""); + + Properties pipProps = new Properties(); + pipProps.setProperty(XACMLProperties.PROP_PIP_ENGINES, ""); + pipProps.store(os, ""); + + } else { + // send properties from the current group + group.getPolicyProperties().store(os, ""); + Properties policyLocations = new Properties(); + for (PDPPolicy policy : group.getPolicies()) { + policyLocations.put(policy.getId() + ".url", XACMLPapServlet.papURL + "?id=" + policy.getId()); + } + policyLocations.store(os, ""); + group.getPipConfigProperties().store(os, ""); + } + + } catch (Exception e) { + logger.error("Failed to send property file to " + pdp.getId(), e); + // Since this is a server-side error, it probably does not reflect a problem on the client, + // so do not change the PDP status. + return; + } + // + // Do the connect + // + connection.connect(); + if (connection.getResponseCode() == 204) { + logger.info("Success. We are configured correctly."); + setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE); + } else if (connection.getResponseCode() == 200) { + logger.info("Success. PDP needs to update its configuration."); + setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH); + } else { + logger.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage()); + setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN); + } + } catch (Exception e) { + logger.error("Unable to sync config with PDP '" + pdp.getId() + "': " + e, e); + try { + setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN); + } catch (PAPException e1) { + logger.error("Unable to set status of PDP '" + pdp.getId() + "' to UNKNOWN: " + e, e); + } + } finally { + // cleanup the connection + connection.disconnect(); + + // tell the AC to update it's status info + notifyAC(); + } + + } + } + + // + // RESTful Interface from PAP to ACs notifying them of changes + // + + private void notifyAC() { + // kick off a thread to do one event notification for all registered ACs + // This needs to be on a separate thread so that ACs can make calls back to PAP to get the updated Group data + // as part of processing this message on their end. + Thread t = new Thread(new NotifyACThread()); + t.start(); + } + + private class NotifyACThread implements Runnable { + + public void run() { + List<String> disconnectedACs = new ArrayList<String>(); +// logger.debug("LIST SIZE="+adminConsoleURLStringList.size()); + + // There should be no Concurrent exception here because the list is a CopyOnWriteArrayList. + // The "for each" loop uses the collection's iterator under the covers, so it should be correct. + for (String acURL : adminConsoleURLStringList) { + HttpURLConnection connection = null; + try { + + acURL += "?PAPNotification=true"; + +//TODO - Currently we just tell AC that "Something changed" without being specific. Do we want to tell it which group/pdp changed? +//TODO - If so, put correct parameters into the Query string here + acURL += "&objectType=all" + "&action=update"; + + if (logger.isDebugEnabled()) { + logger.debug("creating url for id '" + acURL + "'"); + } +//TODO - currently always send both policies and pips. Do we care enough to add code to allow sending just one or the other? +//TODO (need to change "cache=", implying getting some input saying which to change) + + URL url = new URL(acURL ); + + // + // Open up the connection + // + connection = (HttpURLConnection)url.openConnection(); + // + // Setup our method and headers + // + connection.setRequestMethod("PUT"); + connection.setRequestProperty("Content-Type", "text/x-java-properties"); + // + // Adding this in. It seems the HttpUrlConnection class does NOT + // properly forward our headers for POST re-direction. It does so + // for a GET re-direction. + // + // So we need to handle this ourselves. + // + //TODO - is this needed for a PUT? seems better to leave in for now? + connection.setInstanceFollowRedirects(false); + // + // Do not include any data in the PUT because this is just a + // notification to the AC. + // The AC will use GETs back to the PAP to get what it needs + // to fill in the screens. + // + + // + // Do the connect + // + connection.connect(); + if (connection.getResponseCode() == 204) { + logger.info("Success. We updated correctly."); + } else { + logger.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage()); + } + + } catch (Exception e) { + logger.error("Unable to sync config AC '" + acURL + "': " + e, e); + disconnectedACs.add(acURL); + } finally { + // cleanup the connection + connection.disconnect(); + } + } + + // remove any ACs that are no longer connected + if (disconnectedACs.size() > 0) { + adminConsoleURLStringList.removeAll(disconnectedACs); + } + + } + } + +}
diff --git a/openaz-xacml-pap-rest/src/main/resources/log4j.properties b/openaz-xacml-pap-rest/src/main/resources/log4j.properties new file mode 100755 index 0000000..b45fa2f --- /dev/null +++ b/openaz-xacml-pap-rest/src/main/resources/log4j.properties
@@ -0,0 +1,22 @@ +# +# Use this properties for debugging and development. +# +# +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, MAIN_LOG + +# A1 is set to be a ConsoleAppender. +log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n + +# +# This is specifically for Xacml request/response logging +# +log4j.logger.xacml.request=INFO, REQUEST_LOG + +log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender +log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n \ No newline at end of file
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class new file mode 100644 index 0000000..352e4c6 --- /dev/null +++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class new file mode 100644 index 0000000..aac4b91 --- /dev/null +++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class new file mode 100644 index 0000000..3d756fd --- /dev/null +++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class new file mode 100644 index 0000000..ffd1592 --- /dev/null +++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class new file mode 100644 index 0000000..d8d63b5 --- /dev/null +++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/log4j.properties b/openaz-xacml-pap-rest/target/classes/log4j.properties new file mode 100644 index 0000000..b45fa2f --- /dev/null +++ b/openaz-xacml-pap-rest/target/classes/log4j.properties
@@ -0,0 +1,22 @@ +# +# Use this properties for debugging and development. +# +# +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, MAIN_LOG + +# A1 is set to be a ConsoleAppender. +log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n + +# +# This is specifically for Xacml request/response logging +# +log4j.logger.xacml.request=INFO, REQUEST_LOG + +log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender +log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n \ No newline at end of file
diff --git a/openaz-xacml-pap-rest/target/maven-archiver/pom.properties b/openaz-xacml-pap-rest/target/maven-archiver/pom.properties new file mode 100644 index 0000000..022f696 --- /dev/null +++ b/openaz-xacml-pap-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@ +#Generated by Maven +#Tue Apr 07 07:42:37 EDT 2015 +version=0.0.1-SNAPSHOT +groupId=org.openliberty.openaz +artifactId=openaz-xacml-pap-rest
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..4cfb3ef --- /dev/null +++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,5 @@ +com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class +com/att/research/xacml/rest/XACMLPapServlet$1.class +com/att/research/xacml/rest/XACMLPapServlet.class +com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class +com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..9a51391 --- /dev/null +++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1 @@ +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..d8cdce7 --- /dev/null +++ b/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar Binary files differ
diff --git a/openaz-xacml-pap-rest/xacml.pap.properties b/openaz-xacml-pap-rest/xacml.pap.properties new file mode 100755 index 0000000..05fc0c5 --- /dev/null +++ b/openaz-xacml-pap-rest/xacml.pap.properties
@@ -0,0 +1,35 @@ +# +# This is our factory that will create our engine +# +xacml.PAP.papEngineFactory=com.att.research.xacml.std.pap.StdEngineFactory + +# +# Where we store our PAP PDP Group/Node information +# +xacml.pap.pdps=pdps +# +# Need the PAP's url (how PDPs will reach it) configured here +# because we need it to generate the URLs of the Policy Files +# sent to the PDPs in the configuration when the PAP is first brought up. +# (In other cases, such as the PDP calling the PAP, we could generate this URL, +# but for startup there is no other way to get it.) +# +# +xacml.rest.pap.url=http://localhost:9090/pap/ + +# +# Upon startup, have the PAP servlet send latest configuration information to all +# the PDP nodes it knows about. +# +xacml.rest.pap.initiate.pdp=true +# +# Heartbeat from PAP to PDPs +# +# How much time (in milliseconds) between heartbeats +# (i.e. the time between completing the heartbeat with all PDPs and starting the next cycle) +# +xacml.rest.pap.heartbeat.interval=10000 +# +# Heartbeat connection timeout (in milliseconds) +# +xacml.rest.pap.heartbeat.timeout=10000 \ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF b/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF new file mode 100755 index 0000000..58630c0 --- /dev/null +++ b/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +
diff --git a/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar b/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar new file mode 100755 index 0000000..d6b7f6d --- /dev/null +++ b/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar Binary files differ
diff --git a/openaz-xacml-pdp-rest/config/xacml.pip.properties b/openaz-xacml-pdp-rest/config/xacml.pip.properties new file mode 100755 index 0000000..0c16eb3 --- /dev/null +++ b/openaz-xacml-pdp-rest/config/xacml.pip.properties
@@ -0,0 +1,219 @@ +# PIP Engine Definition +# +xacml.pip.engines=csv1,csv2,hyper1,sql1,ldap1 + +csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv1.name=Master +csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info +csv1.issuer=com:att:research:xacml:test:csv +csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt +csv1.maxsize=4000000 +csv1.delimiter=, +csv1.quote=" +csv1.skip=0 + +csv1.resolvers=data + +csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv1.resolver.data.name=Player Resolver +csv1.resolver.data.description=This resolver finds player information in the Master table. +csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame +csv1.resolver.data.field.firstname.column=16 +csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname +csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.lastname.column=17 +csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname +csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathyear.column=10 +csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear +csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathmonth.column=11 +csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth +csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.deathday.column=12 +csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday +csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer +csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.debut.column=25 +csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut +csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.field.finalgame.column=26 +csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame +csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date +csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv1.resolver.data.parameters=playerid +csv1.resolver.data.parameter.playerid.column=1 +csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject + +csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine +csv2.name=Appearances +csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year. +#csv2.issuer= +csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt +csv2.maxsize=4000000 +csv2.delimiter=, +csv2.quote=" +csv2.skip=0 + +csv2.resolvers=data + +csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver +csv2.resolver.data.name=Appearance Resolver +csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table. +csv2.resolver.data.fields=appearance +csv2.resolver.data.field.appearance.column=0 +csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance +csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer +csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv + +csv2.resolver.data.parameters=playerid +csv2.resolver.data.parameter.playerid.column=3 +csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string +csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#csv1.resolver.data.parameter.playerid.issuer= + +hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine +hyper1.name=World Marriage Age Limits +hyper1.description=Minimum age for female/male marriages with or without their parental consent. +hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv +hyper1.target=marriage +hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20) + +hyper1.resolvers=age_consent + +hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +hyper1.resolver.age_consent.name=Ages +hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country. +hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=? +hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale + +hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female +hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male +hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female +hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male +hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer +hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country +hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv + +hyper1.resolver.age_consent.parameters=country +hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name +hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string +hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country +#hyper1.resolver.age_consent.parameter.country.issuer= + +sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine +sql1.name=World +sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures. +# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine. +sql1.issuer=com:att:research:xacml:test:sql +# +# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to +# create the tables and load the data. +# +sql1.type=jdbc +sql1.jdbc.driver=org.postgresql.Driver +sql1.jdbc.url=jdbc:postgresql://localhost:5432/world +sql1.jdbc.conn.user=sa +sql1.jdbc.conn.password= +# +# This is the configuration for JNDI datasource. +# +#sql1.type=jndi +#sql1.datasource=jdbc/xacml + +sql1.resolvers=langer + +sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver +sql1.resolver.langer.name=Language +sql1.resolver.langer.description=This returns the language for a city. +sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=? +sql1.resolver.langer.fields=language +sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language +sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +#You can override the default issuer that is set in the JDBCEngine definition if you want. +#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql +sql1.resolver.langer.parameters=name +sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id +sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string +sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource + + +ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine +ldap1.name=LDAP PIP +ldap1.description=The LDAP containing the seven seas sample LDIF data. +ldap1.issuer=com:att:research:xacml:test:ldap +ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory +# +# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before +# this example will work. +# +ldap1.java.naming.provider.url=ldap://localhost:10389 +#ldap.java.naming.security.principal= +#ldap.java.naming.security.credentials= +ldap1.scope=subtree + +ldap1.resolvers=dn,ship + +ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.dn.name=Domain Names +ldap1.resolver.dn.description=Find all the dn's for the subject id +ldap1.resolver.dn.base=o=sevenseas +ldap1.resolver.dn.base.parameters= +ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid})) +ldap1.resolver.dn.filter.parameters=uid +ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id +ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.dn.filter.view=dn +ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap + +ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver +ldap1.resolver.ship.name=Ship Resolver +ldap1.resolver.ship.description=This resolves a subject's dn to a ship. +ldap1.resolver.ship.base=o=sevenseas +ldap1.resolver.ship.base.parameters= +ldap1.resolver.ship.filter=uniquemember=${dn} +ldap1.resolver.ship.filter.parameters=dn +ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn +ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap +ldap1.resolver.ship.filter.view=cn +ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship +ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string +ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource +ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap +
diff --git a/openaz-xacml-pdp-rest/config/xacml.policy.properties b/openaz-xacml-pdp-rest/config/xacml.policy.properties new file mode 100755 index 0000000..d42c84c --- /dev/null +++ b/openaz-xacml-pdp-rest/config/xacml.policy.properties
@@ -0,0 +1,8 @@ +xacml.rootPolicies=annotation,ldap,csv,csvhyper,sql +xacml.referencedPolicies= + +annotation.file=../XACML-TEST/testsets/annotation/AnnotationPolicy.v1.xml +ldap.file=../XACML-TEST/testsets/pip/configurable-ldap/LDAP-Seven-Seas-v1.xml +csv.file=../XACML-TEST/testsets/pip/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml +csvhyper.file=../XACML-TEST/testsets/pip/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml +sql.file=../XACML-TEST/testsets/pip/configurable-sql/SQL-World-Languages-v1.xml
diff --git a/openaz-xacml-pdp-rest/pom.xml b/openaz-xacml-pdp-rest/pom.xml new file mode 100755 index 0000000..edb97b4 --- /dev/null +++ b/openaz-xacml-pdp-rest/pom.xml
@@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>openaz</artifactId> + <groupId>org.openliberty.openaz</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>openaz-xacml-pdp-rest</artifactId> + + <dependencies> + <dependency> + <groupId>org.openliberty.openaz</groupId> + <artifactId>openaz-xacml</artifactId> + </dependency> + <dependency> + <groupId>org.openliberty.openaz</groupId> + <artifactId>openaz-xacml-rest</artifactId> + </dependency> + <dependency> + <groupId>org.openliberty.openaz</groupId> + <artifactId>openaz-xacml-pdp</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + </dependency> + <dependency> + <groupId>postgresql</groupId> + <artifactId>postgresql</artifactId> + </dependency> + <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + </dependency> + </dependencies> + +</project> \ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java new file mode 100755 index 0000000..6b44cda --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java
@@ -0,0 +1,470 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2014 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; +import java.util.Set; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPStatus; +import com.att.research.xacml.api.pap.PDPStatus.Status; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPEngineFactory; +import com.att.research.xacml.api.pip.PIPEngine; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPFinderFactory; +import com.att.research.xacml.std.pap.StdPDPPIPConfig; +import com.att.research.xacml.std.pap.StdPDPPolicy; +import com.att.research.xacml.std.pap.StdPDPStatus; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLProperties; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef; +import com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory; +import com.google.common.base.Splitter; + +/** + * Does the work for loading policy and PIP configurations sent from the PAP servlet. + * + * + * @author pameladragosh + * + */ +public class XACMLPdpLoader { + private static final Log logger = LogFactory.getLog(XACMLPdpLoader.class); + + public static synchronized PDPEngine loadEngine(StdPDPStatus status, Properties policyProperties, Properties pipProperties) { + logger.info("loadEngine: " + policyProperties + " "+ pipProperties); + // + // First load our policies + // + try { + // + // Were we given some properties? + // + if (policyProperties == null) { + // + // On init we have no incoming configuration, so just + // Load our current saved configuration + // + policyProperties = new Properties(); + try (InputStream is = Files.newInputStream(getPDPPolicyCache())) { + policyProperties.load(is); + } + } + + // + // Get our policy cache up-to-date + // + // Side effects of this include: + // - downloading of policies from remote locations, and + // - creating new "<PolicyId>.file" properties for files existing local + // + XACMLPdpLoader.cachePolicies(policyProperties); + // + // Validate the policies + // + XACMLPdpLoader.validatePolicies(policyProperties, status); + if (logger.isDebugEnabled()) { + logger.debug("Status: " + status); + } + } catch (Exception e) { + String error = "Failed to load Policy Cache properties file: " + e.getMessage(); + logger.error(error, e); + status.addLoadError(error); + status.setStatus(PDPStatus.Status.LOAD_ERRORS); + } + // + // Load our PIP configuration + // + try { + // + // Were we given some properties to use? + // + if (pipProperties == null) { + // + // Load our current saved configuration + // + pipProperties = new Properties(); + try (InputStream is = Files.newInputStream(getPIPConfig())) { + pipProperties.load(is); + } + } + // + // Validate our PIP configurations + // + XACMLPdpLoader.validatePipConfiguration(pipProperties, status); + if (logger.isDebugEnabled()) { + logger.debug("Status: " + status); + } + } catch (Exception e) { + String error = "Failed to load/validate Pip Config properties file: " + e.getMessage(); + logger.error(error, e); + status.addLoadError(error); + status.setStatus(PDPStatus.Status.LOAD_ERRORS); + } + // + // Were they validated? + // + if (status.getStatus() == Status.LOAD_ERRORS) { + logger.error("there were load errors"); + return null; + } + // + // Reset our official properties the PDP factory + // uses to configure the PDP engine. + // + XACMLRest.loadXacmlProperties(policyProperties, pipProperties); + // + // Dump ALL our properties that we are trying to load + // + try { + logger.info(XACMLProperties.getProperties().toString()); + } catch (IOException e) { + logger.error("Failed to get XACML Properties", e); + } + // + // Now load the PDP engine + // + PDPEngineFactory factory = null; + PDPEngine engine = null; + try { + factory = PDPEngineFactory.newInstance(); + engine = factory.newEngine(); + logger.info("Loaded new PDP engine."); + status.setStatus(Status.UP_TO_DATE); + } catch (FactoryException e) { + String error = "Failed to create new PDP Engine"; + logger.error(error, e); + status.addLoadError(error); + } + return engine; + } + + public static synchronized void validatePolicies(Properties properties, StdPDPStatus status) throws PAPException { + Set<String> rootPolicies = XACMLProperties.getRootPolicyIDs(properties); + Set<String> refPolicies = XACMLProperties.getReferencedPolicyIDs(properties); + + for (String id : rootPolicies) { + loadPolicy(properties, status, id, true); + } + // remember which policies were root policies + status.addAllLoadedRootPolicies(status.getLoadedPolicies()); + + for (String id : refPolicies) { + loadPolicy(properties, status, id, false); + } + + logger.info("Loaded " + status.getLoadedPolicies().size() + " policies, failed to load " + status.getFailedPolicies().size() + " policies, " + + status.getLoadedRootPolicies().size() + " root policies"); + if (status.getLoadedRootPolicies().size() == 0) { + logger.warn("NO ROOT POLICIES LOADED!!! Cannot serve PEP Requests."); + status.addLoadWarning("NO ROOT POLICIES LOADED!!! Cannot serve PEP Requests."); + } + } + + public static synchronized void loadPolicy(Properties properties, StdPDPStatus status, String id, boolean isRoot) throws PAPException { + PolicyDef policy = null; + String location = null; + URI locationURI = null; + boolean isFile = false; + try { + location = properties.getProperty(id + ".file"); + if (location == null) { + location = properties.getProperty(id + ".url"); + if (location != null) { + // + // Construct the URL + // + locationURI = URI.create(location); + URL url = locationURI.toURL(); + URLConnection urlConnection = url.openConnection(); + urlConnection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID)); + // + // Now construct the output file name + // + Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), id); + // + // Copy it to disk + // + try (FileOutputStream fos = new FileOutputStream(outFile.toFile())) { + IOUtils.copy(urlConnection.getInputStream(), fos); + } + // + // Now try to load + // + isFile = true; + try (InputStream fis = Files.newInputStream(outFile)) { + policy = DOMPolicyDef.load(fis); + } + // + // Save it + // + properties.setProperty(id + ".file", outFile.toAbsolutePath().toString()); + } + } else { + isFile = true; + locationURI = Paths.get(location).toUri(); + try (InputStream is = Files.newInputStream(Paths.get(location))) { + policy = DOMPolicyDef.load(is); + } + } + if (policy != null) { + status.addLoadedPolicy(new StdPDPPolicy(id, isRoot, locationURI, properties)); + logger.info("Loaded policy: " + policy.getIdentifier() + " version: " + policy.getVersion().stringValue()); + } else { + String error = "Failed to load policy " + location; + logger.error(error); + status.setStatus(PDPStatus.Status.LOAD_ERRORS); + status.addLoadError(error); + status.addFailedPolicy(new StdPDPPolicy(id, isRoot)); + } + } catch (Exception e) { + logger.error("Failed to load policy '" + id + "' from location '" + location + "'", e); + status.setStatus(PDPStatus.Status.LOAD_ERRORS); + status.addFailedPolicy(new StdPDPPolicy(id, isRoot)); + // + // Is it a file? + // + if (isFile) { + // + // Let's remove it + // + try { + logger.error("Corrupted policy file, deleting: " + location); + Files.delete(Paths.get(location)); + } catch (IOException e1) { + logger.error(e1); + } + } + throw new PAPException("Failed to load policy '" + id + "' from location '" + location + "'"); + } + } + + public static synchronized void validatePipConfiguration(Properties properties, StdPDPStatus status) throws PAPException { + try { + PIPFinderFactory factory = PIPFinderFactory.newInstance(properties); + if (factory == null) { + throw new FactoryException("Could not create PIP Finder Factory: " + properties.getProperty(XACMLProperties.PROP_PIPFINDERFACTORY)); + } + PIPFinder finder = factory.getFinder(properties); + // + // Check for this, although it should always return something + // + if (finder == null) { + logger.error("pip finder factory returned a null engine."); + throw new PIPException("Could not create PIP Finder"); + } else { + logger.info("Loaded PIP finder"); + } + for (PIPEngine engine : finder.getPIPEngines()) { + logger.info("Configured PIP Engine: " + engine.getName()); + StdPDPPIPConfig config = new StdPDPPIPConfig(); + config.setName(engine.getName()); + status.addLoadedPipConfig(config); + } + } catch (FactoryException | PIPException e) { + logger.error("validate PIP configuration failed: " + e.getLocalizedMessage()); + status.addLoadError(e.getLocalizedMessage()); + status.setStatus(Status.LOAD_ERRORS); + throw new PAPException(e); + } + } + + /** + * Iterates the policies defined in the props object to ensure they are loaded locally. + * Policies are searched for in the following order: + * - see if the current properties has a "<PolicyID>.file" entry and that file exists in the local directory + * - if not, see if the file exists in the local directory; if so create a ".file" property for it. + * - if not, get the "<PolicyID>.url" property and try to GET the policy from that location (and set the ".file" property) + * + * If the ".file" property is created, then true is returned to tell the caller that the props object changed. + * + * @param props + * @return true/false if anything was changed in the props object + * @throws PAPException + */ + public static synchronized boolean cachePolicies(Properties props) throws PAPException { + boolean changed = false; + String[] lists = new String[2]; + lists[0] = props.getProperty(XACMLProperties.PROP_ROOTPOLICIES); + lists[1] = props.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES); + for (String list : lists) { + // + // Check for a null or empty parameter + // + if (list == null || list.length() == 0) { + continue; + } + Iterable<String> policies = Splitter.on(',').trimResults().omitEmptyStrings().split(list); + for (String policy : policies) { + boolean policyExists = false; + + // First look for ".file" property and verify the file exists + String propLocation = props.getProperty(policy + StdPolicyFinderFactory.PROP_FILE); + if (propLocation != null) { + // + // Does it exist? + // + policyExists = Files.exists(Paths.get(propLocation)); + if (policyExists == false) { + logger.warn("Policy file " + policy + " expected at " + propLocation + " does NOT exist."); + } + } + + // If ".file" property does not exist, try looking for the local file anyway + // (it might exist without having a ".file" property set for it) + if (policyExists == false) { + // + // Now construct the output file name + // + Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), policy); + // + // Double check to see if we pulled it at some point + // + policyExists = Files.exists(outFile); + if (policyExists) { + // + // Set the property so the PDP engine doesn't have + // to pull it from the URL but rather the FILE. + // + logger.info("Policy does exist: " + outFile.toAbsolutePath().toString()); + props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE, outFile.toAbsolutePath().toString()); + // + // Indicate that there were changes made to the properties + // + changed = true; + } else { + + // File does not exist locally, so we need to get it from the location given in the ".url" property (which MUST exist) + + // + // There better be a URL to retrieve it + // + propLocation = props.getProperty(policy + StdPolicyFinderFactory.PROP_URL); + if (propLocation != null) { + // + // Get it + // + URL url = null; + try { + // + // Create the URL + // + url = new URL(propLocation); + logger.info("Pulling " + url.toString()); + // + // Open the connection + // + URLConnection urlConnection = url.openConnection(); + urlConnection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID)); + // + // Copy it to disk + // + try (InputStream is = urlConnection.getInputStream(); OutputStream os = new FileOutputStream(outFile.toFile())) { + IOUtils.copy(is, os); + } + // + // Now save it in the properties as a .file + // + logger.info("Pulled policy: " + outFile.toAbsolutePath().toString()); + props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE, outFile.toAbsolutePath().toString()); + // + // Indicate that there were changes made to the properties + // + changed = true; + } catch (Exception e) { + if (e instanceof MalformedURLException) { + logger.error("Policy '" + policy + "' had bad URL in new configuration, URL='" + propLocation + "'"); + } else { + logger.error("Error while retrieving policy " + policy + " from URL " + url.toString() + ", e="+e); + } + } + } else { + logger.error("Policy " + policy + " does NOT exist and does NOT have a URL"); + } + } + } + } + } + return changed; + } + + public static synchronized Path getPDPPolicyCache() throws PAPException { + Path config = getPDPConfig(); + Path policyProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.policy.properties"); + if (Files.notExists(policyProperties)) { + logger.warn(policyProperties.toAbsolutePath().toString() + " does NOT exist."); + // + // Try to create the file + // + try { + Files.createFile(policyProperties); + } catch (IOException e) { + logger.error("Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString()); + throw new PAPException("Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString()); + } + } + return policyProperties; + } + + public static synchronized Path getPIPConfig() throws PAPException { + Path config = getPDPConfig(); + Path pipConfigProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.pip.properties"); + if (Files.notExists(pipConfigProperties)) { + logger.warn(pipConfigProperties.toAbsolutePath().toString() + " does NOT exist."); + // + // Try to create the file + // + try { + Files.createFile(pipConfigProperties); + } catch (IOException e) { + logger.error("Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString()); + throw new PAPException("Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString()); + } + } + return pipConfigProperties; + } + + public static synchronized Path getPDPConfig() throws PAPException { + Path config = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_CONFIG)); + if (Files.notExists(config)) { + logger.warn(config.toAbsolutePath().toString() + " does NOT exist."); + // + // Try to create the directory + // + try { + Files.createDirectories(config); + } catch (IOException e) { + logger.error("Failed to create config directory: " + config.toAbsolutePath().toString(), e); + throw new PAPException("Failed to create config directory: " + config.toAbsolutePath().toString()); + } + } + return config; + } + +}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java new file mode 100755 index 0000000..3d232cf --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java
@@ -0,0 +1,210 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2014 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.file.Files; +import java.util.Properties; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.rest.XACMLPdpServlet.PutRequest; +import com.att.research.xacml.util.XACMLProperties; + +public class XACMLPdpRegisterThread implements Runnable { + private static final Log logger = LogFactory.getLog(XACMLPdpRegisterThread.class); + + public volatile boolean isRunning = false; + + public synchronized boolean isRunning() { + return this.isRunning; + } + + public synchronized void terminate() { + this.isRunning = false; + } + + /** + * + * This is our thread that runs on startup to tell the PAP server we are up-and-running. + * + */ + @Override + public void run() { + synchronized(this) { + this.isRunning = true; + } + boolean registered = false; + boolean interrupted = false; + int seconds; + try { + seconds = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_SLEEP)); + } catch (NumberFormatException e) { + logger.error("REGISTER_SLEEP: ", e); + seconds = 5; + } + if (seconds < 5) { + seconds = 5; + } + int retries; + try { + retries = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_RETRIES)); + } catch (NumberFormatException e) { + logger.error("REGISTER_SLEEP: ", e); + retries = -1; + } + while (! registered && ! interrupted && this.isRunning()) { + HttpURLConnection connection = null; + try { + // + // Get the PAP Servlet URL + // + URL url = new URL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL)); + logger.info("Registering with " + url.toString()); + boolean finished = false; + while (! finished) { + // + // Open up the connection + // + connection = (HttpURLConnection)url.openConnection(); + // + // Setup our method and headers + // + connection.setRequestMethod("POST"); + connection.setRequestProperty("Accept", "text/x-java-properties"); + connection.setRequestProperty("Content-Type", "text/x-java-properties"); + connection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID)); + connection.setUseCaches(false); + // + // Adding this in. It seems the HttpUrlConnection class does NOT + // properly forward our headers for POST re-direction. It does so + // for a GET re-direction. + // + // So we need to handle this ourselves. + // + connection.setInstanceFollowRedirects(false); + connection.setDoOutput(true); + connection.setDoInput(true); + try { + // + // Send our current policy configuration + // + String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES); + lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES) + "\n"; + try (InputStream listsInputStream = new ByteArrayInputStream(lists.getBytes()); + InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig()); + OutputStream os = connection.getOutputStream()) { + IOUtils.copy(listsInputStream, os); + + // + // Send our current PIP configuration + // + IOUtils.copy(pipInputStream, os); + } + } catch (Exception e) { + logger.error("Failed to send property file", e); + } + // + // Do the connect + // + connection.connect(); + if (connection.getResponseCode() == 204) { + logger.info("Success. We are configured correctly."); + finished = true; + registered = true; + } else if (connection.getResponseCode() == 200) { + logger.info("Success. We have a new configuration."); + Properties properties = new Properties(); + properties.load(connection.getInputStream()); + logger.info("New properties: " + properties.toString()); + // + // Queue it + // + // The incoming properties does NOT include urls + PutRequest req = new PutRequest(XACMLProperties.getPolicyProperties(properties, false), XACMLProperties.getPipProperties(properties)); + XACMLPdpServlet.queue.offer(req); + // + // We are now registered + // + finished = true; + registered=true; + } else if (connection.getResponseCode() >= 300 && connection.getResponseCode() <= 399) { + // + // Re-direction + // + String newLocation = connection.getHeaderField("Location"); + if (newLocation == null || newLocation.isEmpty()) { + logger.warn("Did not receive a valid re-direction location"); + finished = true; + } else { + logger.info("New Location: " + newLocation); + url = new URL(newLocation); + } + } else { + logger.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage()); + finished = true; + } + } + } catch (Exception e) { + logger.error(e); + } finally { + // cleanup the connection + if (connection != null) { + try { + // For some reason trying to get the inputStream from the connection + // throws an exception rather than returning null when the InputStream does not exist. + InputStream is = null; + try { + is = connection.getInputStream(); + } catch (Exception e1) { + // ignore this + } + if (is != null) { + is.close(); + } + + } catch (IOException ex) { + logger.error("Failed to close connection: " + ex, ex); + } + connection.disconnect(); + } + } + // + // Wait a little while to try again + // + try { + if (registered == false) { + if (retries > 0) { + retries--; + } else if (retries == 0) { + break; + } + Thread.sleep(seconds * 1000); + } + } catch (InterruptedException e) { + interrupted = true; + this.terminate(); + } + } + synchronized(this) { + this.isRunning = false; + } + logger.info("Thread exiting...(registered=" + registered + ", interrupted=" + interrupted + ", isRunning=" + this.isRunning() + ", retries=" + retries + ")"); + } + +}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java new file mode 100755 index 0000000..f670579 --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java
@@ -0,0 +1,690 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.Properties; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebInitParam; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.entity.ContentType; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.pap.PDPStatus.Status; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPException; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacml.std.dom.DOMResponse; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONResponse; +import com.att.research.xacml.std.pap.StdPDPStatus; +import com.att.research.xacml.util.XACMLProperties; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Servlet implementation class XacmlPdpServlet + * + * This is an implementation of the XACML 3.0 RESTful Interface with added features to support + * simple PAP RESTful API for policy publishing and PIP configuration changes. + * + * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file. + * This properties file has all the default parameter settings. If you are running the servlet as is, + * then we recommend setting up you're container to run it on port 8080 with context "/pdp". Wherever + * the default working directory is set to, a "config" directory will be created that holds the policy + * and pip cache. This setting is located in the xacml.pdp.properties file. + * + * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file + * system and setup the parameters as you wish. Just set the Java VM System variable to point to that file: + * + * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties + * + * Or if you only want to change one or two properties, simply set the Java VM System variable for that property. + * + * -Dxacml.rest.pdp.register=false + * + * @author pameladragosh + * + */ +@WebServlet( + description = "Implements the XACML PDP RESTful API and client PAP API.", + urlPatterns = { "/" }, + loadOnStartup=1, + initParams = { + @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties", description = "The location of the PDP xacml.pdp.properties file holding configuration information.") + }) +public class XACMLPdpServlet extends HttpServlet implements Runnable { + private static final long serialVersionUID = 1L; + // + // Our application debug log + // + private static final Log logger = LogFactory.getLog(XACMLPdpServlet.class); + // + // This logger is specifically only for Xacml requests and their corresponding response. + // It's output ideally should be sent to a separate file from the application logger. + // + private static final Log requestLogger = LogFactory.getLog("xacml.request"); + // + // This thread may getting invoked on startup, to let the PAP know + // that we are up and running. + // + private Thread registerThread = null; + private XACMLPdpRegisterThread registerRunnable = null; + // + // This is our PDP engine pointer. There is a synchronized lock used + // for access to the pointer. In case we are servicing PEP requests while + // an update is occurring from the PAP. + // + private PDPEngine pdpEngine = null; + private static final Object pdpEngineLock = new Object(); + // + // This is our PDP's status. What policies are loaded (or not) and + // what PIP configurations are loaded (or not). + // There is a synchronized lock used for access to the object. + // + private static volatile StdPDPStatus status = new StdPDPStatus(); + private static final Object pdpStatusLock = new Object(); + // + // Queue of PUT requests + // + public static class PutRequest { + public Properties policyProperties = null; + public Properties pipConfigProperties = null; + + PutRequest(Properties policies, Properties pips) { + this.policyProperties = policies; + this.pipConfigProperties = pips; + } + } + public static volatile BlockingQueue<PutRequest> queue = new LinkedBlockingQueue<PutRequest>(2); + // + // This is our configuration thread that attempts to load + // a new configuration request. + // + private Thread configThread = null; + private volatile boolean configThreadTerminate = false; + + /** + * Default constructor. + */ + public XACMLPdpServlet() { + } + + /** + * @see Servlet#init(ServletConfig) + */ + public void init(ServletConfig config) throws ServletException { + // + // Initialize + // + XACMLRest.xacmlInit(config); + // + // Load our engine - this will use the latest configuration + // that was saved to disk and set our initial status object. + // + PDPEngine engine = XACMLPdpLoader.loadEngine(XACMLPdpServlet.status, null, null); + if (engine != null) { + synchronized(pdpEngineLock) { + pdpEngine = engine; + } + } + // + // Kick off our thread to register with the PAP servlet. + // + if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) { + this.registerRunnable = new XACMLPdpRegisterThread(); + this.registerThread = new Thread(this.registerRunnable); + this.registerThread.start(); + } + // + // This is our thread that manages incoming configuration + // changes. + // + this.configThread = new Thread(this); + this.configThread.start(); + } + + /** + * @see Servlet#destroy() + */ + public void destroy() { + super.destroy(); + logger.info("Destroying...."); + // + // Make sure the register thread is not running + // + if (this.registerRunnable != null) { + try { + this.registerRunnable.terminate(); + if (this.registerThread != null) { + this.registerThread.interrupt(); + this.registerThread.join(); + } + } catch (InterruptedException e) { + logger.error(e); + } + } + // + // Make sure the configure thread is not running + // + this.configThreadTerminate = true; + try { + this.configThread.interrupt(); + this.configThread.join(); + } catch (InterruptedException e) { + logger.error(e); + } + logger.info("Destroyed."); + } + + /** + * PUT - The PAP engine sends configuration information using HTTP PUT request. + * + * One parameter is expected: + * + * config=[policy|pip|all] + * + * policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP should + * be using for PEP requests. + * + * Specifically should AT LEAST contain the following properties: + * xacml.rootPolicies + * xacml.referencedPolicies + * + * In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache. + * + * EXAMPLE: + * xacml.rootPolicies=PolicyA.1, PolicyB.1 + * + * PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1 + * PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1 + * + * xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1 + * + * RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1 + * RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1 + * + * pip - Expect a properties file that contain PIP engine configuration properties. + * + * Specifically should AT LEAST the following property: + * xacml.pip.engines + * + * In addition, any relevant information needed by the PDP to load and configure the PIPs. + * + * EXAMPLE: + * xacml.pip.engines=foo,bar + * + * foo.classname=com.foo + * foo.sample=abc + * foo.example=xyz + * ...... + * + * bar.classname=com.bar + * ...... + * + * all - Expect ALL new configuration properties for the PDP + * + * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // + // Dump our request out + // + if (logger.isDebugEnabled()) { + XACMLRest.dumpRequest(request); + } + // + // What is being PUT? + // + String cache = request.getParameter("cache"); + // + // Should be a list of policy and pip configurations in Java properties format + // + if (cache != null && request.getContentType().equals("text/x-java-properties")) { + if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) { + String message = "Content-Length larger than server will accept."; + logger.info(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + this.doPutConfig(cache, request, response); + } else { + String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'"; + logger.error(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + } + + protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + // prevent multiple configuration changes from stacking up + if (XACMLPdpServlet.queue.remainingCapacity() <= 0) { + logger.error("Queue capacity reached"); + response.sendError(HttpServletResponse.SC_CONFLICT, "Multiple configuration changes waiting processing."); + return; + } + // + // Read the properties data into an object. + // + Properties newProperties = new Properties(); + newProperties.load(request.getInputStream()); + // should have something in the request + if (newProperties.size() == 0) { + logger.error("No properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property"); + return; + } + // + // Which set of properties are they sending us? Whatever they send gets + // put on the queue (if there is room). + // + if (config.equals("policies")) { + newProperties = XACMLProperties.getPolicyProperties(newProperties, true); + if (newProperties.size() == 0) { + logger.error("No policy properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=policies must contain at least one policy property"); + return; + } + XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null)); + } else if (config.equals("pips")) { + newProperties = XACMLProperties.getPipProperties(newProperties); + if (newProperties.size() == 0) { + logger.error("No pips properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=pips must contain at least one pip property"); + return; + } + XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties)); + } else if (config.equals("all")) { + Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true); + if (newPolicyProperties.size() == 0) { + logger.error("No policy properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one policy property"); + return; + } + Properties newPipProperties = XACMLProperties.getPipProperties(newProperties); + if (newPipProperties.size() == 0) { + logger.error("No pips properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one pip property"); + return; + } + XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties)); + } else { + // + // Invalid value + // + logger.error("Invalid config value: " + config); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Config must be one of 'policies', 'pips', 'all'"); + return; + } + } catch (Exception e) { + logger.error("Failed to process new configuration.", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return; + } + } + + /** + * Parameters: type=hb|config|Status + * + * 1. HeartBeat Status + * HeartBeat + * OK - All Policies are Loaded, All PIPs are Loaded + * LOADING_IN_PROGRESS - Currently loading a new policy set/pip configuration + * LAST_UPDATE_FAILED - Need to track the items that failed during last update + * LOAD_FAILURE - ??? Need to determine what information is sent and how + * 2. Configuration + * 3. Status + * return the StdPDPStatus object in the Response content + * + * + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + XACMLRest.dumpRequest(request); + // + // What are they requesting? + // + boolean returnHB = false; + response.setHeader("Cache-Control", "no-cache"); + String type = request.getParameter("type"); + // type might be null, so use equals on string constants + if ("config".equals(type)) { + response.setContentType("text/x-java-properties"); + try { + String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, ""); + lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n"; + try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes()); + InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig()); + OutputStream os = response.getOutputStream()) { + IOUtils.copy(listInputStream, os); + IOUtils.copy(pipInputStream, os); + } + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception e) { + logger.error("Failed to copy property file", e); + response.sendError(400, "Failed to copy Property file"); + } + + } else if ("hb".equals(type)) { + returnHB = true; + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + + } else if ("Status".equals(type)) { + // convert response object to JSON and include in the response + synchronized(pdpStatusLock) { + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), status); + } + response.setStatus(HttpServletResponse.SC_OK); + + } else { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'"); + } + if (returnHB) { + synchronized(pdpStatusLock) { + response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString()); + } + } + } + + /** + * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON according + * to the XACML 3.0 Specifications for both. + * + * + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // + // no point in doing any work if we know from the get-go that we cannot do anything with the request + // + if (status.getLoadedRootPolicies().size() == 0) { + logger.warn("Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded"); + response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); + return; + } + + XACMLRest.dumpRequest(request); + // + // Set our no-cache header + // + response.setHeader("Cache-Control", "no-cache"); + // + // They must send a Content-Type + // + if (request.getContentType() == null) { + logger.warn("Must specify a Content-Type"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given"); + return; + } + // + // Limit the Content-Length to something reasonable + // + if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) { + String message = "Content-Length larger than server will accept."; + logger.info(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + if (request.getContentLength() <= 0) { + String message = "Content-Length is negative"; + logger.info(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + ContentType contentType = null; + try { + contentType = ContentType.parse(request.getContentType()); + } + catch (Exception e) { + String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage(); + logger.error(message, e); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + // + // What exactly did they send us? + // + String incomingRequestString = null; + Request pdpRequest = null; + if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) { + // + // Read in the string + // + StringBuilder buffer = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream())); + String line; + while((line = reader.readLine()) != null){ + buffer.append(line); + } + incomingRequestString = buffer.toString(); + logger.info(incomingRequestString); + // + // Parse into a request + // + try { + if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) { + pdpRequest = JSONRequest.load(incomingRequestString); + } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) { + pdpRequest = DOMRequest.load(incomingRequestString); + } + } + catch(Exception e) { + logger.error("Could not parse request", e); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); + return; + } + } else { + String message = "unsupported content type" + request.getContentType(); + logger.error(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + // + // Did we successfully get and parse a request? + // + if (pdpRequest == null || pdpRequest.getRequestAttributes() == null || pdpRequest.getRequestAttributes().size() <= 0) { + String message = "Zero Attributes found in the request"; + logger.error(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + // + // Run it + // + try { + // + // Get the pointer to the PDP Engine + // + PDPEngine myEngine = null; + synchronized(pdpEngineLock) { + myEngine = this.pdpEngine; + } + if (myEngine == null) { + String message = "No engine loaded."; + logger.error(message); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; + } + // + // Send the request and save the response + // + long lTimeStart, lTimeEnd; + Response pdpResponse = null; + +//TODO - Make this unnecessary +//TODO It seems that the PDP Engine is not thread-safe, so when a configuration change occurs in the middle of processing +//TODO a PEP Request, that Request fails (it throws a NullPointerException in the decide() method). +//TODO Using synchronize will slow down processing of PEP requests, possibly by a significant amount. +//TODO Since configuration changes are rare, it would be A Very Good Thing if we could eliminate this sychronized block. +//TODO +//TODO This problem was found by starting one PDP then +//TODO RestLoadTest switching between 2 configurations, 1 second apart +//TODO both configurations contain the datarouter policy +//TODO both configurations already have all policies cached in the PDPs config directory +//TODO RestLoadTest started with the Datarouter test requests, 5 threads, no interval +//TODO With that configuration this code (without the synchronized) throws a NullPointerException +//TODO within a few seconds. +// +synchronized(pdpEngineLock) { + myEngine = this.pdpEngine; + try { + lTimeStart = System.currentTimeMillis(); + pdpResponse = myEngine.decide(pdpRequest); + lTimeEnd = System.currentTimeMillis(); + } catch (PDPException e) { + String message = "Exception during decide: " + e.getMessage(); + logger.error(message); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; + } +} + requestLogger.info(lTimeStart + "=" + incomingRequestString); + if (logger.isDebugEnabled()) { + logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms"); + } + // + // Convert Response to appropriate Content-Type + // + if (pdpResponse == null) { + requestLogger.info(lTimeStart + "=" + "{}"); + throw new Exception("Failed to get response from PDP engine."); + } + // + // Set our content-type + // + response.setContentType(contentType.getMimeType()); + // + // Convert the PDP response object to a String to + // return to our caller as well as dump to our loggers. + // + String outgoingResponseString = ""; + if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) { + // + // Get it as a String. This is not very efficient but we need to log our + // results for auditing. + // + outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled()); + if (logger.isDebugEnabled()) { + logger.debug(outgoingResponseString); + // + // Get rid of whitespace + // + outgoingResponseString = JSONResponse.toString(pdpResponse, false); + } + } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) { + // + // Get it as a String. This is not very efficient but we need to log our + // results for auditing. + // + outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled()); + if (logger.isDebugEnabled()) { + logger.debug(outgoingResponseString); + // + // Get rid of whitespace + // + outgoingResponseString = DOMResponse.toString(pdpResponse, false); + } + } + // + // lTimeStart is used as an ID within the requestLogger to match up + // request's with responses. + // + requestLogger.info(lTimeStart + "=" + outgoingResponseString); + response.getWriter().print(outgoingResponseString); + } + catch (Exception e) { + String message = "Exception executing request: " + e; + logger.error(message, e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; + } + response.setStatus(HttpServletResponse.SC_OK); + } + + @Override + public void run() { + // + // Keep running until we are told to terminate + // + try { + while (! this.configThreadTerminate) { + PutRequest request = XACMLPdpServlet.queue.take(); + StdPDPStatus newStatus = new StdPDPStatus(); + +//TODO - This is related to the problem discussed in the doPost() method about the PDPEngine not being thread-safe. +//TODO See that discussion, and when the PDPEngine is made thread-safe it should be ok to move the loadEngine out of +//TODO the synchronized block. +//TODO However, since configuration changes should be rare we may not care about changing this. +PDPEngine newEngine = null; + synchronized(pdpStatusLock) { + XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION); +newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties); + } +// PDPEngine newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties); + if (newEngine != null) { + synchronized(XACMLPdpServlet.pdpEngineLock) { + this.pdpEngine = newEngine; + try { + logger.info("Saving configuration."); + if (request.policyProperties != null) { + try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) { + request.policyProperties.store(os, ""); + } + } + if (request.pipConfigProperties != null) { + try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) { + request.pipConfigProperties.store(os, ""); + } + } + newStatus.setStatus(Status.UP_TO_DATE); + + } catch (Exception e) { + logger.error("Failed to store new properties."); + newStatus.setStatus(Status.LOAD_ERRORS); + newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage()); + } + } + } else { + newStatus.setStatus(Status.LAST_UPDATE_FAILED); + } + synchronized(pdpStatusLock) { + XACMLPdpServlet.status.set(newStatus); + } + } + } catch (InterruptedException e) { + logger.error("interrupted"); + } + } +}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java new file mode 100755 index 0000000..550d1b2 --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java
@@ -0,0 +1,75 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2014 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest.impl; + +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPFinderFactory; +import com.att.research.xacml.std.pip.finders.ConfigurableEngineFinder; +import com.att.research.xacml.util.XACMLProperties; + +public class XACMLPdpPIPFinderFactory extends PIPFinderFactory { + private ConfigurableEngineFinder pipFinder; + + private static Log logger = LogFactory.getLog(XACMLPdpPIPFinderFactory.class); + + public XACMLPdpPIPFinderFactory() { + } + + public XACMLPdpPIPFinderFactory(Properties properties) { + } + + @Override + public PIPFinder getFinder() throws PIPException { + if (pipFinder == null) { + synchronized(this) { + if (pipFinder == null) { + if (logger.isDebugEnabled()) { + logger.debug("Creating default configurable engine finder"); + } + pipFinder = new ConfigurableEngineFinder(); + Properties xacmlProperties = null; + try { + xacmlProperties = XACMLProperties.getProperties(); + } catch (Exception ex) { + logger.error("Exception getting XACML properties: " + ex.getMessage(), ex); + return null; + } + if (xacmlProperties != null) { + ((ConfigurableEngineFinder)pipFinder).configure(xacmlProperties); + } + } + } + } + return pipFinder; + } + + @Override + public PIPFinder getFinder(Properties properties) throws PIPException { + if (pipFinder == null) { + synchronized(this) { + if (pipFinder == null) { + if (logger.isDebugEnabled()) { + logger.debug("Creating configurable engine finder using: " + properties); + } + pipFinder = new ConfigurableEngineFinder(); + ((ConfigurableEngineFinder)pipFinder).configure(properties); + } + } + } + return this.pipFinder; + } +}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java new file mode 100755 index 0000000..421839a --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java
@@ -0,0 +1,197 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2014 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest.impl; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLProperties; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.PolicyFinder; +import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory; +import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef; +import com.att.research.xacmlatt.pdp.std.StdPolicyFinder; +import com.google.common.base.Splitter; + +public class XACMLPdpPolicyFinderFactory extends PolicyFinderFactory { + public static final String PROP_FILE = ".file"; + public static final String PROP_URL = ".url"; + + private static Log logger = LogFactory.getLog(XACMLPdpPolicyFinderFactory.class); + private List<PolicyDef> rootPolicies; + private List<PolicyDef> referencedPolicies; + private boolean needsInit = true; + + private Properties properties = null; + + public XACMLPdpPolicyFinderFactory() { + // + // Here we differ from the StdPolicyFinderFactory in that we initialize right away. + // We do not wait for a policy request to happen to look for and load policies. + // + this.init(); + } + + public XACMLPdpPolicyFinderFactory(Properties properties) { + // + // Save our properties + // + this.properties = properties; + // + // Here we differ from the StdPolicyFinderFactory in that we initialize right away. + // We do not wait for a policy request to happen to look for and load policies. + // + this.init(); + } + + /** + * Loads the <code>PolicyDef</code> for the given <code>String</code> identifier by looking first + * for a ".file" property associated with the ID and using that to load from a <code>File</code> and + * looking for a ".url" property associated with the ID and using that to load from a <code>URL</code>. + * + * @param policyId the <code>String</code> identifier for the policy + * @return a <code>PolicyDef</code> loaded from the given identifier + */ + protected PolicyDef loadPolicyDef(String policyId) { + String propLocation = null; + if (this.properties == null) { + propLocation = XACMLProperties.getProperty(policyId + PROP_FILE); + } else { + propLocation = this.properties.getProperty(policyId + PROP_FILE); + } + if (propLocation != null) { + File fileLocation = new File(propLocation); + if (!fileLocation.exists()) { + XACMLPdpPolicyFinderFactory.logger.error("Policy file " + fileLocation.getAbsolutePath() + " does not exist."); + } else if (!fileLocation.canRead()) { + XACMLPdpPolicyFinderFactory.logger.error("Policy file " + fileLocation.getAbsolutePath() + " cannot be read."); + } else { + try { + XACMLPdpPolicyFinderFactory.logger.info("Loading policy file " + fileLocation); + PolicyDef policyDef = DOMPolicyDef.load(fileLocation); + if (policyDef != null) { + return policyDef; + } + } catch (DOMStructureException ex) { + XACMLPdpPolicyFinderFactory.logger.error("Error loading policy file " + fileLocation.getAbsolutePath() + ": " + ex.getMessage(), ex); + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } + } + } + if (this.properties == null) { + propLocation = XACMLProperties.getProperty(policyId + PROP_URL); + } else { + propLocation = this.properties.getProperty(policyId + PROP_URL); + } + if (propLocation != null) { + InputStream is = null; + try { + URL url = new URL(propLocation); + URLConnection urlConnection = url.openConnection(); + XACMLPdpPolicyFinderFactory.logger.info("Loading policy file " + url.toString()); + is = urlConnection.getInputStream(); + PolicyDef policyDef = DOMPolicyDef.load(is); + if (policyDef != null) { + return policyDef; + } + } catch (MalformedURLException ex) { + XACMLPdpPolicyFinderFactory.logger.error("Invalid URL " + propLocation + ": " + ex.getMessage(), ex); + } catch (IOException ex) { + XACMLPdpPolicyFinderFactory.logger.error("IOException opening URL " + propLocation + ": " + ex.getMessage(), ex); + } catch (DOMStructureException ex) { + XACMLPdpPolicyFinderFactory.logger.error("Invalid Policy " + propLocation + ": " + ex.getMessage(), ex); + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + XACMLPdpPolicyFinderFactory.logger.error("Exception closing InputStream for GET of url " + propLocation + " : " + e.getMessage() + " (May be memory leak)", e); + } + } + } + } + + XACMLPdpPolicyFinderFactory.logger.error("No known location for Policy " + policyId); + return null; + } + + /** + * Finds the identifiers for all of the policies referenced by the given property name in the + * <code>XACMLProperties</code> and loads them using the requested loading method. + * + * @param propertyName the <code>String</code> name of the property containing the list of policy identifiers + * @return a <code>List</code> of <code>PolicyDef</code>s loaded from the given property name + */ + protected List<PolicyDef> getPolicyDefs(String propertyName) { + String policyIds = XACMLProperties.getProperty(propertyName); + if (policyIds == null || policyIds.length() == 0) { + return null; + } + + Iterable<String> policyIdArray = Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds); + if (policyIdArray == null) { + return null; + } + + List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>(); + for (String policyId : policyIdArray) { + PolicyDef policyDef = this.loadPolicyDef(policyId); + if (policyDef != null) { + listPolicyDefs.add(policyDef); + } + } + return listPolicyDefs; + } + + protected synchronized void init() { + if (this.needsInit) { + if (XACMLPdpPolicyFinderFactory.logger.isDebugEnabled()) { + XACMLPdpPolicyFinderFactory.logger.debug("Initializing"); + } + this.rootPolicies = this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES); + this.referencedPolicies = this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES); + if (XACMLPdpPolicyFinderFactory.logger.isDebugEnabled()) { + XACMLPdpPolicyFinderFactory.logger.debug("Root Policies: " + this.rootPolicies); + XACMLPdpPolicyFinderFactory.logger.debug("Referenced Policies: " + this.referencedPolicies); + } + this.needsInit = false; + } + } + + @Override + public PolicyFinder getPolicyFinder() throws FactoryException { + // + // Force using any properties that were passed upon construction + // + return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, this.properties); + } + + @Override + public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException { + return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties); + } + +}
diff --git a/openaz-xacml-pdp-rest/src/main/resources/log4j.properties b/openaz-xacml-pdp-rest/src/main/resources/log4j.properties new file mode 100755 index 0000000..b45fa2f --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/resources/log4j.properties
@@ -0,0 +1,22 @@ +# +# Use this properties for debugging and development. +# +# +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, MAIN_LOG + +# A1 is set to be a ConsoleAppender. +log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n + +# +# This is specifically for Xacml request/response logging +# +log4j.logger.xacml.request=INFO, REQUEST_LOG + +log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender +log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n \ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class new file mode 100644 index 0000000..43eeb50 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class new file mode 100644 index 0000000..b43d395 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class new file mode 100644 index 0000000..9809046 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class new file mode 100644 index 0000000..59e6daa --- /dev/null +++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class new file mode 100644 index 0000000..54de986 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class new file mode 100644 index 0000000..f9825d8 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/log4j.properties b/openaz-xacml-pdp-rest/target/classes/log4j.properties new file mode 100644 index 0000000..b45fa2f --- /dev/null +++ b/openaz-xacml-pdp-rest/target/classes/log4j.properties
@@ -0,0 +1,22 @@ +# +# Use this properties for debugging and development. +# +# +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, MAIN_LOG + +# A1 is set to be a ConsoleAppender. +log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n + +# +# This is specifically for Xacml request/response logging +# +log4j.logger.xacml.request=INFO, REQUEST_LOG + +log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender +log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n \ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties b/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties new file mode 100644 index 0000000..5eebb03 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@ +#Generated by Maven +#Tue Apr 07 07:42:37 EDT 2015 +version=0.0.1-SNAPSHOT +groupId=org.openliberty.openaz +artifactId=openaz-xacml-pdp-rest
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..667efe3 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,6 @@ +com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class +com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class +com/att/research/xacml/rest/XACMLPdpServlet.class +com/att/research/xacml/rest/XACMLPdpLoader.class +com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class +com/att/research/xacml/rest/XACMLPdpRegisterThread.class
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..12a596f --- /dev/null +++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,5 @@ +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..8eca8bd --- /dev/null +++ b/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar Binary files differ
diff --git a/openaz-xacml-pdp-rest/xacml.pdp.properties b/openaz-xacml-pdp-rest/xacml.pdp.properties new file mode 100755 index 0000000..34e6b77 --- /dev/null +++ b/openaz-xacml-pdp-rest/xacml.pdp.properties
@@ -0,0 +1,53 @@ +# Default XACML Properties File for PDP RESTful servlet +# +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +# NOT USED SEE BELOW xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory +xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory +# +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +# NOT USED SEE BELOW xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +# +# AT&T RESTful PDP Implementation Factories +# +xacml.pipFinderFactory=com.att.research.xacml.rest.impl.XACMLPdpPIPFinderFactory +xacml.att.policyFinderFactory=com.att.research.xacml.rest.XACMLPdpPolicyFinderFactory +# +# PDP RESTful API properties +# +# Set this to the address where the XACML-PAP-REST servlet is running +# +xacml.rest.pap.url=http://localhost:9090/pap/ +# +# Give the running PDP an ID for the PAP. The url that its running as is a good choice. +# The PAP identifies PDP's using the URL of the PDP. +# +xacml.rest.pdp.id=http://localhost:8080/pdp/ +# +# Set the directory where the PDP holds its Policy Cache and PIP Configuration +# +xacml.rest.pdp.config=config +# +# Initialize register with PAP servlet +# +xacml.rest.pdp.register=true +# +# Sleep period in seconds between register attempts +# +xacml.rest.pdp.register.sleep=15 +# +# number of attempts to register. -1 means keep trying forever. +# +xacml.rest.pdp.register.retries=-1 +# +# max number of bytes in a POST of a XML/JSON request +# +xacml.rest.pdp.maxcontent=32767 \ No newline at end of file
diff --git a/openaz-xacml-pdp/logging.properties b/openaz-xacml-pdp/logging.properties new file mode 100755 index 0000000..ef56def --- /dev/null +++ b/openaz-xacml-pdp/logging.properties
@@ -0,0 +1,9 @@ +handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler + +.level = ALL + +java.util.logging.ConsoleHandler.level = INFO +java.util.logging.FileHandler.level = INFO +java.util.logging.FileHandler.pattern=%h/xacml_log%u.log +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter +java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
diff --git a/openaz-xacml-pdp/pom.xml b/openaz-xacml-pdp/pom.xml new file mode 100755 index 0000000..e55bdf4 --- /dev/null +++ b/openaz-xacml-pdp/pom.xml
@@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>openaz</artifactId> + <groupId>org.openliberty.openaz</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>openaz-xacml-pdp</artifactId> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>openaz-xacml</artifactId> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + </dependencies> + +</project> \ No newline at end of file
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java new file mode 100755 index 0000000..c3c0bfb --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java
@@ -0,0 +1,255 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp; + +import java.net.URI; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.AttributeCategory; +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPException; +import com.att.research.xacml.api.pdp.ScopeResolver; +import com.att.research.xacml.api.trace.TraceEngine; +import com.att.research.xacml.api.trace.TraceEngineFactory; +import com.att.research.xacml.api.trace.Traceable; +import com.att.research.xacml.std.StdIndividualDecisionRequestGenerator; +import com.att.research.xacml.std.StdMutableResponse; +import com.att.research.xacml.std.StdMutableResult; +import com.att.research.xacml.std.StdResult; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.trace.StdTraceEvent; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult; + +/** + * ATTPDPEngine implements the {@link com.att.research.xacml.api.pdp.PDPEngine} interface using the XACML 3.0 specification. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class ATTPDPEngine implements PDPEngine, Traceable { + private static final Status STATUS_ADVICE_NA = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Advice not allowed in combined decision"); + private static final Status STATUS_OBLIGATIONS_NA = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Obligations not allowed in combined decision"); + private static final Status STATUS_COMBINE_FAILED = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Individual decisions do not match"); + private static final Result RESULT_ECTX_NULL = new StdMutableResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null EvaluationContext")); + + /* + * These are the profiles that this reference implementation of the PDP engine supports + */ + private static final Set<URI> PROFILES = new HashSet<URI>(); + static { + PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_COMBINED_DECISION.getUri()); + PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_REFERENCE.getUri()); + PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_REPEATED_ATTRIBUTE_CATEGORIES.getUri()); + PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_SCOPE.getUri()); + PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_XPATH_EXPRESSION.getUri()); + } + + private EvaluationContextFactory evaluationContextFactory; + private Decision defaultDecision = Decision.INDETERMINATE; + private ScopeResolver scopeResolver; + private TraceEngine traceEngine; + private Log logger = LogFactory.getLog(this.getClass()); + + protected TraceEngine getTraceEngine() { + if (this.traceEngine == null) { + synchronized(this) { + if (this.traceEngine == null) { + try { + this.traceEngine = TraceEngineFactory.newInstance().getTraceEngine(); + } catch (FactoryException ex) { + this.logger.error("FactoryException creating TraceEngine instance: " + ex.toString(), ex); + throw new IllegalStateException("FactoryException creating TraceEngine instance", ex); + } + } + } + } + return this.traceEngine; + } + + public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, ScopeResolver scopeResolverIn) { + this.evaluationContextFactory = evaluationContextFactoryIn; + this.scopeResolver = scopeResolverIn; + } + + public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, Decision defaultDecisionIn, ScopeResolver scopeResolverIn) { + this(evaluationContextFactoryIn, scopeResolverIn); + this.defaultDecision = defaultDecisionIn; + } + + public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, Decision defaultDecisionIn, ScopeResolver scopeResolverIn, Properties properties) { + this(evaluationContextFactoryIn, defaultDecisionIn, scopeResolverIn); + } + + protected Result processRequest(EvaluationContext evaluationContext) { + try { + PolicyFinderResult<PolicyDef> policyFinderResult = evaluationContext.getRootPolicyDef(); + if (policyFinderResult.getStatus() != null && !policyFinderResult.getStatus().isOk()) { + return new StdMutableResult(policyFinderResult.getStatus()); + } + PolicyDef policyDefRoot = policyFinderResult.getPolicyDef(); + if (policyDefRoot == null) { + switch(this.defaultDecision) { + case DENY: + case NOTAPPLICABLE: + case PERMIT: + return new StdMutableResult(this.defaultDecision, new StdStatus(StdStatusCode.STATUS_CODE_OK, "No applicable policy")); + case INDETERMINATE: + case INDETERMINATE_DENY: + case INDETERMINATE_DENYPERMIT: + case INDETERMINATE_PERMIT: + return new StdMutableResult(this.defaultDecision, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No applicable policy")); + } + } + Result result = policyDefRoot.evaluate(evaluationContext); + if (result.getStatus().isOk()) { + Collection<AttributeCategory> listRequestAttributesIncludeInResult = evaluationContext.getRequest().getRequestAttributesIncludedInResult(); + if (listRequestAttributesIncludeInResult != null && listRequestAttributesIncludeInResult.size() > 0) { + StdMutableResult stdMutableResult = new StdMutableResult(result); + stdMutableResult.addAttributeCategories(listRequestAttributesIncludeInResult); + result = new StdResult(stdMutableResult); + } + } + return result; + } catch (EvaluationException ex) { + return new StdMutableResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage())); + } + } + + @Override + public Response decide(Request pepRequest) throws PDPException { + /* + * Validate the request + */ + TraceEngine traceEngineThis = this.getTraceEngine(); + if (traceEngineThis.isTracing()) { + traceEngineThis.trace(new StdTraceEvent<Request>("Input Request", this, pepRequest)); + } + Status statusRequest = pepRequest.getStatus(); + if (statusRequest != null && !statusRequest.isOk()) { + return new StdMutableResponse(statusRequest); + } + + /* + * Split the original request up into individual decision requests + */ + StdIndividualDecisionRequestGenerator stdIndividualDecisionRequestGenerator = new StdIndividualDecisionRequestGenerator(this.scopeResolver, pepRequest); + /* + * Determine if we are combining multiple results into a single result + */ + boolean bCombineResults = pepRequest.getCombinedDecision(); + StdMutableResult stdResultCombined = null; + + /* + * Iterate over all of the individual decision requests and process them, combining them into the final response + */ + StdMutableResponse stdResponse = new StdMutableResponse(); + Iterator<Request> iterRequestsIndividualDecision = stdIndividualDecisionRequestGenerator.getIndividualDecisionRequests(); + if (iterRequestsIndividualDecision == null || !iterRequestsIndividualDecision.hasNext()) { + return new StdMutableResponse(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No individual decision requests")); + } + + while (iterRequestsIndividualDecision.hasNext()) { + Request requestIndividualDecision = iterRequestsIndividualDecision.next(); + if (traceEngineThis.isTracing()) { + traceEngineThis.trace(new StdTraceEvent<Request>("Individual Request", this, requestIndividualDecision)); + } + Result resultIndividualDecision = null; + if (requestIndividualDecision.getStatus() != null && !requestIndividualDecision.getStatus().isOk()) { + resultIndividualDecision = new StdMutableResult(requestIndividualDecision.getStatus()); + } else { + EvaluationContext evaluationContext = this.evaluationContextFactory.getEvaluationContext(requestIndividualDecision); + if (evaluationContext == null) { + resultIndividualDecision = RESULT_ECTX_NULL; + } else { + resultIndividualDecision = this.processRequest(evaluationContext); + } + } + + assert(resultIndividualDecision != null); + if (traceEngineThis.isTracing()) { + traceEngineThis.trace(new StdTraceEvent<Result>("Individual Result", this, resultIndividualDecision)); + } + if (bCombineResults) { + Decision decision = resultIndividualDecision.getDecision(); + Status status = resultIndividualDecision.getStatus(); + if (resultIndividualDecision.getAssociatedAdvice().size() > 0) { + decision = Decision.INDETERMINATE; + status = STATUS_ADVICE_NA; + } else if (resultIndividualDecision.getObligations().size() > 0) { + decision = Decision.INDETERMINATE; + status = STATUS_OBLIGATIONS_NA; + } + + if (stdResultCombined == null) { + stdResultCombined = new StdMutableResult(decision, status); + } else { + if (stdResultCombined.getDecision() != resultIndividualDecision.getDecision()) { + stdResultCombined.setDecision(Decision.INDETERMINATE); + stdResultCombined.setStatus(STATUS_COMBINE_FAILED); + } + } + stdResultCombined.addPolicyIdentifiers(resultIndividualDecision.getPolicyIdentifiers()); + stdResultCombined.addPolicySetIdentifiers(resultIndividualDecision.getPolicySetIdentifiers()); + stdResultCombined.addAttributeCategories(resultIndividualDecision.getAttributes()); + if (traceEngineThis.isTracing()) { + traceEngineThis.trace(new StdTraceEvent<Result>("Combined result", this, stdResultCombined)); + } + } else { + stdResponse.add(resultIndividualDecision); + } + } + + if (bCombineResults) { + stdResponse.add(stdResultCombined); + } + return stdResponse; + } + + @Override + public Collection<URI> getProfiles() { + return Collections.unmodifiableCollection(PROFILES); + } + + @Override + public boolean hasProfile(URI uriProfile) { + return PROFILES.contains(uriProfile); + } + + @Override + public String getTraceId() { + return this.getClass().getCanonicalName(); + } + + @Override + public Traceable getCause() { + return null; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java new file mode 100755 index 0000000..7bd165a --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java
@@ -0,0 +1,56 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp; + +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPEngineFactory; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory; + +/** + * ATTPDPEngineFactory extends {@link com.att.research.xacml.api.pdp.PDPEngineFactory} by implementing the abstract + * <code>newEngine</code> method to create a {@link ATTPDPEngine} instance and initialize it + * with policies and PIP instances based on configuration information provided to the factory. + * + * @author car + * @version $Revision: 1.4 $ + */ +public class ATTPDPEngineFactory extends PDPEngineFactory { + private Log logger = LogFactory.getLog(this.getClass()); + + public ATTPDPEngineFactory() { + } + + @Override + public PDPEngine newEngine() throws FactoryException { + EvaluationContextFactory evaluationContextFactory = EvaluationContextFactory.newInstance(); + if (evaluationContextFactory == null) { + this.logger.error("Null EvaluationContextFactory"); + throw new FactoryException("Null EvaluationContextFactory"); + } + return new ATTPDPEngine(evaluationContextFactory, this.getDefaultBehavior(), this.getScopeResolver()); + } + + @Override + public PDPEngine newEngine(Properties properties) throws FactoryException { + EvaluationContextFactory evaluationContextFactory = EvaluationContextFactory.newInstance(properties); + if (evaluationContextFactory == null) { + this.logger.error("Null EvaluationContextFactory"); + throw new FactoryException("Null EvaluationContextFactory"); + } + return new ATTPDPEngine(evaluationContextFactory, this.getDefaultBehavior(), this.getScopeResolver(), properties); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java new file mode 100755 index 0000000..24adb1d --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java
@@ -0,0 +1,23 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.eval; + +/** + * Evaluatable is the interface objects implement to indicate they can be evaluated with an {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} + * and return an {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult}. + * + * @author car + * @version $Revision: 1.1 $ + */ +public interface Evaluatable { + public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException; +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java new file mode 100755 index 0000000..321fff1 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java
@@ -0,0 +1,73 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.eval; + +import com.att.research.xacml.api.IdReferenceMatch; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPRequest; +import com.att.research.xacml.api.pip.PIPResponse; +import com.att.research.xacml.api.trace.TraceEngine; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult; +import com.att.research.xacmlatt.pdp.policy.PolicySet; + +/** + * EvaluationContext provides the interface that the PDP uses to evaluate its set of Policies and PolicySets against + * a {@link com.att.research.xacml.api.Request}. + * + * @author car + * @version $Revision: 1.2 $ + */ +public interface EvaluationContext extends PIPFinder, TraceEngine { + /** + * Gets the original <code>Request</code> provided to the <code>ATTPDPEngine</code>'s <code>decide</code> method. + * + * @return the <code>Request</code> provided to the <code>ATTPDPEngine</code>'s <code>decide</code> method. + */ + public Request getRequest(); + + /** + * Gets the root {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} from the policy store + * configured by the particular implementation of the <code>PolicyFinderFactory</code> class. + * + * @return a <code>PolicyFinderResult</code> with the root <code>PolicyDef</code> + */ + public abstract PolicyFinderResult<PolicyDef> getRootPolicyDef(); + + /** + * Gets the {@link com.att.research.xacmlatt.pdp.policy.Policy} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}. + * + * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for + * @return a <code>PolicyFinderResult</code> with the <code>Policy</code> matching the given <code>IdReferenceMatch</code> + */ + public abstract PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch); + + /** + * Gets the {@link com.att.research.xacmlatt.pdp.policy.PolicySet} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}. + * + * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for + * @return a <code>PolicyFinderResult</code> with the <code>PolicySet</code> matching the given <code>IdReferenceMatch</code>. + */ + public abstract PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch); + + /** + * Gets the {@link com.att.research.xacml.api.pip.PIPResponse} containing {@link com.att.research.xacml.api.Attribute}s that + * match the given {@link com.att.research.xacml.api.pip.PIPRequest} from this <code>EvaluationContext</code>. + * + * @param pipRequest the <code>PIPRequest</code> specifying which <code>Attribute</code>s to retrieve + * @return the <code>PIPResponse</code> containing the {@link com.att.research.xacml.api.Status} and <code>Attribute</code>s + * @throws EvaluationException if there is an error retrieving the <code>Attribute</code>s + */ + public PIPResponse getAttributes(PIPRequest pipRequest) throws PIPException; +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java new file mode 100755 index 0000000..d814961 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java
@@ -0,0 +1,42 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.eval; + +/** + * EvaluationContextException extends <code>Exception</code> to represent errors thrown by + * methods in the {@link EvaluationContext} and {@link EvaluationContextFactory}. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class EvaluationContextException extends Exception { + private static final long serialVersionUID = -8270506903118536839L; + + public EvaluationContextException() { + } + + public EvaluationContextException(String message) { + super(message); + } + + public EvaluationContextException(Throwable cause) { + super(cause); + } + + public EvaluationContextException(String message, Throwable cause) { + super(message, cause); + } + + public EvaluationContextException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java new file mode 100755 index 0000000..4f54deb --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java
@@ -0,0 +1,79 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.eval; + +import java.util.Properties; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.FactoryFinder; +import com.att.research.xacmlatt.pdp.policy.PolicyFinder; +import com.att.research.xacmlatt.pdp.util.ATTPDPProperties; + +/** + * EvaluationContextFactory provides methods for creating {@link EvaluationContext} objects + * based on configuration information found in standard places. (TODO: Detail what these are) + * + * @author car + * @version $Revision: 1.3 $ + */ +public abstract class EvaluationContextFactory { + private static final String FACTORYID = ATTPDPProperties.PROP_EVALUATIONCONTEXTFACTORY; + private static final String DEFAULT_FACTORY_CLASSNAME = "com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory"; + + protected EvaluationContextFactory() { + } + + protected EvaluationContextFactory(Properties properties) { + } + + public static EvaluationContextFactory newInstance() throws FactoryException { + return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, EvaluationContextFactory.class); + } + + public static EvaluationContextFactory newInstance(Properties properties) throws FactoryException { + return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, EvaluationContextFactory.class, properties); + } + + public static EvaluationContextFactory newInstance(String className, ClassLoader classLoader) throws FactoryException { + return FactoryFinder.newInstance(className, EvaluationContextFactory.class, classLoader, false); + } + + public static EvaluationContextFactory newInstance(String className) throws FactoryException { + return FactoryFinder.newInstance(className, EvaluationContextFactory.class, null, true); + } + + /** + * Gets a new {@link com.att.research.xacml.pdp.eval.EvaluationContext} for the given {@link com.att.research.xacml.api.Request}. + * + * @param request the <code>Request</code> for the new <code>EvaluationContext</code> + * @return a new <code>EvaluationContext</code> for the given <code>Request</code> + */ + public abstract EvaluationContext getEvaluationContext(Request request); + + /** + * Sets the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinder} for this <code>EvaluationContextFactory</code> to an + * explicit instance instead of the default or configured value. + * + * @param policyFinder the <code>PolicyFinder</code> to use in creating new <code>EvaluationContext</code>s. + */ + public abstract void setPolicyFinder(PolicyFinder policyFinder); + + /** + * Sets the {@link com.att.research.xacml.api.pip.PIPFinder} for this <code>EvaluationContextFactory</code> to an + * explicit instance instaed of the default or configured value. + * + * @param pipFinder the <code>PIPFinder</code> to use in creating new <code>EvaluationContext</code>s. + */ + public abstract void setPIPFinder(PIPFinder pipFinder); + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java new file mode 100755 index 0000000..0a0b49a --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java
@@ -0,0 +1,43 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.eval; + +/** + * EvaluationException extends <code>Exception</code> to represent errors returned by methods of the + * {@link Evaluatable} interface and the {@link Matchable} interface. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class EvaluationException extends Exception { + private static final long serialVersionUID = 302250127793947492L; + + public EvaluationException() { + } + + public EvaluationException(String message) { + super(message); + } + + public EvaluationException(Throwable cause) { + super(cause); + } + + public EvaluationException(String message, Throwable cause) { + super(message, cause); + } + + public EvaluationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java new file mode 100755 index 0000000..78828e5 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java
@@ -0,0 +1,80 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.eval; + +import java.util.Collection; + +import com.att.research.xacml.api.Advice; +import com.att.research.xacml.api.AttributeCategory; +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.IdReference; +import com.att.research.xacml.api.Obligation; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdMutableResult; + +/** + * EvaluationResult extends {@link com.att.research.xacml.std.StdMutableResult} with methods useful within a PDP implementation + * + * @author car + * @version $Revision: 1.1 $ + */ +public class EvaluationResult extends StdMutableResult { + public EvaluationResult() { + super(); + } + + public EvaluationResult(Decision decisionIn, Status statusIn) { + super(decisionIn, statusIn); + } + + public EvaluationResult(Status statusIn) { + super(statusIn); + } + + public EvaluationResult(Decision decisionIn) { + super(decisionIn); + } + + public EvaluationResult(Decision decisionIn, + Collection<Obligation> obligationsIn, + Collection<Advice> adviceIn, + Collection<AttributeCategory> attributesIn, + Collection<IdReference> policyIdentifiersIn, + Collection<IdReference> policySetIdentifiersIn) { + super(decisionIn, obligationsIn, adviceIn, attributesIn, policyIdentifiersIn, policySetIdentifiersIn); + } + + /** + * Creates an <code>EvaluationResult</code> generally from a {@link com.att.research.xacmlatt.pdp.policy.Rule} <code>evaluation</code> + * call. + * + * @param decisionIn the <code>Decision</code> + * @param obligationsIn the <code>Collection</code> of <code>Obligation</code>s + * @param adviceIn the <code>Collection</code> of <code>Advice</code> objects + */ + public EvaluationResult(Decision decisionIn, Collection<Obligation> obligationsIn, Collection<Advice> adviceIn) { + super(decisionIn, obligationsIn, adviceIn, null, null, null); + } + + public void merge(EvaluationResult evaluationResult) { + if (this.getStatus() == null) { + this.setStatus(evaluationResult.getStatus()); + } else { + this.getStatus().merge(evaluationResult.getStatus()); + } + this.addObligations(evaluationResult.getObligations()); + this.addAdvice(evaluationResult.getAssociatedAdvice()); + this.addAttributeCategories(evaluationResult.getAttributes()); + this.addPolicyIdentifiers(evaluationResult.getPolicyIdentifiers()); + this.addPolicySetIdentifiers(evaluationResult.getPolicySetIdentifiers()); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java new file mode 100755 index 0000000..4398b79 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java
@@ -0,0 +1,71 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.eval; + +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; + +/** + * MatchResult is the value returned by the {@link Matchable} interface. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class MatchResult { + public static enum MatchCode { + INDETERMINATE, + MATCH, + NOMATCH + } + + public static MatchResult MM_MATCH = new MatchResult(MatchCode.MATCH); + public static MatchResult MM_NOMATCH = new MatchResult(MatchCode.NOMATCH); + + private MatchCode matchCode; + private Status status; + + public MatchResult(MatchCode matchCodeIn, Status statusIn) { + this.matchCode = matchCodeIn; + this.status = statusIn; + } + + public MatchResult(MatchCode matchCodeIn) { + this(matchCodeIn, StdStatus.STATUS_OK); + } + + public MatchResult(Status statusIn) { + this(MatchCode.INDETERMINATE, statusIn); + } + + public MatchCode getMatchCode() { + return this.matchCode; + } + + public Status getStatus() { + return this.status; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("matchCode="); + stringBuilder.append(this.getMatchCode()); + Status thisStatus = this.getStatus(); + if (thisStatus != null) { + stringBuilder.append(", status="); + stringBuilder.append(thisStatus.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java new file mode 100755 index 0000000..0550b07 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java
@@ -0,0 +1,30 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.eval; + +/** + * Matchable is the interface objects implement to indicate they are part of a XACML Target matching tree. + * + * @author car + * @version $Revision: 1.1 $ + */ +public interface Matchable { + /** + * Matches this <code>Matchable</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} and + * returns a {@link com.att.research.xacmlatt.pdp.eval.MatchResult}. + * + * @param evaluationContext the <code>EvaluationContext</code> to use in matching + * @return a <code>MatchResult</code> indicating whether this <code>Matchable</code> matches against the given <code>EvaluationContext</code>. + * @throws EvaluationException if there is an error testing the match. + */ + public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException; +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java new file mode 100755 index 0000000..eb01ff5 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java
@@ -0,0 +1,19 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.eval; + +/** + * com.att.research.xacmlatt.pdp.eval contains interfaces and classes used in evaluating and matching XACML policy components. + * + * @author car + * @version $Revision: 1.1 $ + */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java new file mode 100755 index 0000000..b6c251b --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java
@@ -0,0 +1,20 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp; + +/** + * com.att.research.xacmlatt.pdp contains a reference implementation of the {@link com.att.research.xacml.pdp.PDPEngine} interface + * developed at AT&T Laboratories. + * + * @author car + * @version $Revision: 1.1 $ + */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java new file mode 100755 index 0000000..9ef9adc --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java
@@ -0,0 +1,201 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Advice; +import com.att.research.xacml.api.AttributeAssignment; +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdMutableAdvice; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; + +/** + * AdviceExpression extends {@link PolicyComponent} to implement the XACML AdviceExpression element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class AdviceExpression extends PolicyComponent { + private List<AttributeAssignmentExpression> listAttributeAssignmentExpressions = new ArrayList<AttributeAssignmentExpression>(); + private Identifier adviceId; + private RuleEffect appliesTo; + + protected List<AttributeAssignmentExpression> getAttributeAssignmentExpressionList() { + return this.listAttributeAssignmentExpressions; + } + + protected void clearAttributeAssignmentExpressionList() { + this.getAttributeAssignmentExpressionList().clear(); + } + + public AdviceExpression(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public AdviceExpression(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public AdviceExpression() { + } + + public AdviceExpression(Identifier adviceIdIn, RuleEffect ruleEffectIn, Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) { + this.adviceId = adviceIdIn; + this.appliesTo = ruleEffectIn; + if (attributeAssignmentExpressions != null) { + this.listAttributeAssignmentExpressions.addAll(attributeAssignmentExpressions); + } + } + + public Identifier getAdviceId() { + return this.adviceId; + } + + public void setAdviceId(Identifier identifier) { + this.adviceId = identifier; + } + + public RuleEffect getAppliesTo() { + return this.appliesTo; + } + + public void setAppliesTo(RuleEffect ruleEffect) { + this.appliesTo = ruleEffect; + } + + public Iterator<AttributeAssignmentExpression> getAttributeAssignmentExpressions() { + return this.getAttributeAssignmentExpressionList().iterator(); + } + + public void setAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) { + this.clearAttributeAssignmentExpressionList(); + if (attributeAssignmentExpressions != null) { + + } + } + + public void addAttributeAssignmentExpression(AttributeAssignmentExpression attributeAssignmentExpression) { + this.getAttributeAssignmentExpressionList().add(attributeAssignmentExpression); + } + + public void addAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) { + this.getAttributeAssignmentExpressionList().addAll(attributeAssignmentExpressions); + } + + /** + * Evaluates the <code>AttributeAssignmentExpression</code>s in this <code>AdviceExpression</code> to generate an + * {@link com.att.research.xacml.api.Advice} object. + * + * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} in which to evaluate the <code>AttributeAssignmentExpression</code>s + * @param policyDefaults the {@link PolicyDefaults} for the evaluation + * @return a new <code>Advice</code> evaluated from this <code>AdviceExpression</code> + * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the evaluation + */ + public Advice evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return null; + } + + List<AttributeAssignment> attributeAssignments = new ArrayList<AttributeAssignment>(); + Iterator<AttributeAssignmentExpression> iterAttributeAssignmentExpressions = this.getAttributeAssignmentExpressions(); + if (iterAttributeAssignmentExpressions != null) { + while (iterAttributeAssignmentExpressions.hasNext()) { + AttributeAssignmentResult attributeAssignmentResult = iterAttributeAssignmentExpressions.next().evaluate(evaluationContext, policyDefaults); + if (attributeAssignmentResult.isOk() && attributeAssignmentResult.getNumAttributeAssignments() > 0) { + Iterator<AttributeAssignment> iterAttributeAssignments = attributeAssignmentResult.getAttributeAssignments(); + while (iterAttributeAssignments.hasNext()) { + attributeAssignments.add(iterAttributeAssignments.next()); + } + } + } + } + + return new StdMutableAdvice(this.getAdviceId(), attributeAssignments); + } + + /** + * Evaluates a <code>Collection</code> of <code>AdviceExpression</code>s in the given <code>EvaluationContext</code> and returns + * a <code>List</code> of <code>Advice</code>s. + * + * @param evaluationContext + * @param policyDefaults + * @param listAdviceExpressions + * @return + * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException + */ + public static List<Advice> evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults, Decision decision, Collection<AdviceExpression> listAdviceExpressions) throws EvaluationException { + List<Advice> listAdvices = new ArrayList<Advice>(); + Iterator<AdviceExpression> iterAdviceExpressions = listAdviceExpressions.iterator(); + while (iterAdviceExpressions.hasNext()) { + AdviceExpression adviceExpression = iterAdviceExpressions.next(); + adviceExpression.validateComponent(); + if ( ! adviceExpression.isOk()) { + throw new EvaluationException(adviceExpression.getStatusMessage()); + } + if (decision == null || adviceExpression.getAppliesTo().getDecision().equals(decision)) { + Advice advice = adviceExpression.evaluate(evaluationContext, policyDefaults); + if (advice != null) { + listAdvices.add(advice); + } + } + } + return listAdvices; + } + + @Override + protected boolean validateComponent() { + if (this.getAdviceId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AdviceId"); + return false; + } else if (this.getAppliesTo() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AppliesTo"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getAdviceId()) != null) { + stringBuilder.append(",adviceId="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getAppliesTo()) != null) { + stringBuilder.append(",appliesTo="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = StringUtils.toString(this.getAttributeAssignmentExpressions())) != null) { + stringBuilder.append(",attributeAssignmentExpressions="); + stringBuilder.append((String)objectToDump); + } + + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java new file mode 100755 index 0000000..721750a --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java
@@ -0,0 +1,136 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.MatchResult; +import com.att.research.xacmlatt.pdp.eval.Matchable; + +/** + * AnyOf extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the {@link com.att.research.xacmlatt.pdp.policy.Matchable} + * interface to represent XACML AllOf elements in a XACML Target. + * + * @author car + * @version $Revision + */ +public class AllOf extends PolicyComponent implements Matchable { + private List<Match> matches; + + protected List<Match> getMatchList(boolean bNoNulls) { + if (this.matches == null && bNoNulls) { + this.matches = new ArrayList<Match>(); + } + return this.matches; + } + + protected void clearMatchList() { + if (this.matches != null) { + this.matches.clear(); + } + } + + public AllOf(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public AllOf(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public AllOf() { + } + + public Iterator<Match> getMatches() { + return (this.matches == null ? null : this.matches.iterator()); + } + + public void setMatches(Collection<Match> matchesIn) { + this.clearMatchList(); + if (matchesIn != null) { + this.addMatches(matchesIn); + } + } + + public void addMatch(Match match) { + List<Match> matchList = this.getMatchList(true); + matchList.add(match); + } + + public void addMatches(Collection<Match> matchesIn) { + List<Match> matchList = this.getMatchList(true); + matchList.addAll(matchesIn); + } + + @Override + public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException { + if (!this.validate()) { + return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + Iterator<Match> iterMatches = this.getMatches(); + assert(iterMatches != null && iterMatches.hasNext()); + + MatchResult matchResultFallThrough = MatchResult.MM_MATCH; + while (iterMatches.hasNext()) { + MatchResult matchResultMatch = iterMatches.next().match(evaluationContext); + assert(matchResultMatch != null); + switch(matchResultMatch.getMatchCode()) { + case INDETERMINATE: + if (matchResultFallThrough.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) { + matchResultFallThrough = matchResultMatch; + } + break; + case MATCH: + break; + case NOMATCH: + return matchResultMatch; + } + } + return matchResultFallThrough; + } + + @Override + protected boolean validateComponent() { + Iterator<Match> iterMatches = this.getMatches(); + if (iterMatches == null || !iterMatches.hasNext()) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing matches"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + String stringMatches = StringUtils.toString(this.getMatches()); + if (stringMatches != null) { + stringBuilder.append(",matches="); + stringBuilder.append(stringMatches); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java new file mode 100755 index 0000000..749904f --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java
@@ -0,0 +1,150 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.MatchResult; +import com.att.research.xacmlatt.pdp.eval.Matchable; + +/** + * AnyOf extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the {@link com.att.research.xacmlatt.pdp.policy.Matchable} + * interface to represent XACML AnyOf elements in a XACML Target. + * + * @author car + * @version $Revision + */ +public class AnyOf extends PolicyComponent implements Matchable { + private List<AllOf> allOfs; + + protected List<AllOf> getAllOfList(boolean bNoNull) { + if (this.allOfs == null && bNoNull) { + this.allOfs = new ArrayList<AllOf>(); + } + return this.allOfs; + } + + protected void clearAllOfList() { + if (this.allOfs != null) { + this.allOfs.clear(); + } + } + + public AnyOf(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public AnyOf(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public AnyOf() { + } + + public AnyOf(Collection<AllOf> allOfsIn) { + if (allOfsIn != null) { + this.addAllOfs(allOfsIn); + } + } + + public Iterator<AllOf> getAllOfs() { + return (this.allOfs == null ? null : this.allOfs.iterator()); + } + + public void setAllOfs(Collection<AllOf> allOfsIn) { + this.clearAllOfList(); + if (allOfsIn != null) { + this.addAllOfs(allOfsIn); + } + } + + public void addAllOf(AllOf allOf) { + List<AllOf> listAllOfs = this.getAllOfList(true); + listAllOfs.add(allOf); + } + + public void addAllOfs(Collection<AllOf> allOfs) { + List<AllOf> listAllOfs = this.getAllOfList(true); + listAllOfs.addAll(allOfs); + } + + @Override + public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException { + if (!this.validate()) { + return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + Iterator<AllOf> iterAllOfs = this.getAllOfs(); + if (iterAllOfs == null || !iterAllOfs.hasNext()) { + return MatchResult.MM_NOMATCH; + } + + /* + * Assume "No Match" until we find a match or an indeterminate result + */ + MatchResult matchResultFallThrough = MatchResult.MM_NOMATCH; + while (iterAllOfs.hasNext()) { + MatchResult matchResultAllOf = iterAllOfs.next().match(evaluationContext); + assert(matchResultAllOf != null); + switch(matchResultAllOf.getMatchCode()) { + case INDETERMINATE: + /* + * Keep the first indeterminate value to return if no other match is found + */ + if (matchResultFallThrough.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) { + matchResultFallThrough = matchResultAllOf; + } + break; + case MATCH: + return matchResultAllOf; + case NOMATCH: + break; + } + } + return matchResultFallThrough; + } + + @Override + protected boolean validateComponent() { + Iterator<AllOf> iterAllOfs = this.getAllOfs(); + if (iterAllOfs == null || !iterAllOfs.hasNext()) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AllOf elements in AnyOf"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + String iterToDump = StringUtils.toString(this.getAllOfs()); + if (iterToDump != null) { + stringBuilder.append(",allOfs="); + stringBuilder.append(iterToDump); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java new file mode 100755 index 0000000..047fff8 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java
@@ -0,0 +1,166 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.AttributeAssignment; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdMutableAttributeAssignment; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; + +/** + * AttributeAssignmentExpression extends {@link PolicyComponent} to represent a + * XACML AttributeAssignmentExpression element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class AttributeAssignmentExpression extends PolicyComponent { + private static final AttributeAssignmentResult AAR_NULL_EXPRESSION = new AttributeAssignmentResult(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Null expression")); + private static final AttributeAssignmentResult AAR_NULL_EXPRESSION_RESULT = new AttributeAssignmentResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null expression result")); + + private Expression expression; + private Identifier attributeId; + private Identifier category; + private String issuer; + + public AttributeAssignmentExpression(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public AttributeAssignmentExpression(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public AttributeAssignmentExpression() { + } + + public AttributeAssignmentExpression(Identifier categoryIn, Identifier attributeIdIn, String issuerIn, Expression expressionIn) { + this.category = categoryIn; + this.attributeId = attributeIdIn; + this.issuer = issuerIn; + this.expression = expressionIn; + } + + public Identifier getCategory() { + return this.category; + } + + public void setCategory(Identifier identifier) { + this.category = identifier; + } + + public Identifier getAttributeId() { + return this.attributeId; + } + + public void setAttributeId(Identifier identifier) { + this.attributeId = identifier; + } + + public String getIssuer() { + return this.issuer; + } + + public void setIssuer(String string) { + this.issuer = string; + } + + public Expression getExpression() { + return this.expression; + } + + public void setExpression(Expression expressionIn) { + this.expression = expressionIn; + } + + public AttributeAssignmentResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return new AttributeAssignmentResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + Expression thisExpression = this.getExpression(); + if (thisExpression == null) { + return AAR_NULL_EXPRESSION; + } + + ExpressionResult thisExpressionResult = thisExpression.evaluate(evaluationContext, policyDefaults); + if (thisExpressionResult == null) { + return AAR_NULL_EXPRESSION_RESULT; + } else if (!thisExpressionResult.isOk()) { + return new AttributeAssignmentResult(thisExpressionResult.getStatus()); + } else { + List<AttributeAssignment> listAttributeAssignments = new ArrayList<AttributeAssignment>(); + if (thisExpressionResult.isBag()) { + Bag bagValues = thisExpressionResult.getBag(); + if (bagValues == null || bagValues.size() == 0) { + listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), null)); + } else { + Iterator<AttributeValue<?>> iterBagValues = bagValues.getAttributeValues(); + while (iterBagValues.hasNext()) { + AttributeValue<?> attributeValue = iterBagValues.next(); + listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), attributeValue)); + } + } + } else { + listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), thisExpressionResult.getValue())); + } + return new AttributeAssignmentResult(listAttributeAssignments); + } + } + + @Override + protected boolean validateComponent() { + if (this.getAttributeId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeId"); + return false; + } else if (this.getExpression() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getCategory()) != null) { + stringBuilder.append(",category="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getAttributeId()) != null) { + stringBuilder.append(",attributeId="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getExpression()) != null) { + stringBuilder.append(",expression="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java new file mode 100755 index 0000000..cc6c549 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java
@@ -0,0 +1,95 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.AttributeAssignment; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.util.StringUtils; + +/** + * AttributeAssignmentResult is the object returned by the <code>evaluate</code> method of an {@link com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression}. + * It contains a {@link com.att.research.xacml.api.Status} and an optional collection of {@link com.att.research.xacml.api.AttributeAssignment} + * elements. + * + * @author car + * @version $Revision$ + */ +public class AttributeAssignmentResult { + private Status status; + private List<AttributeAssignment> listAttributeAssignments; + + protected List<AttributeAssignment> getListAttributeAssignments() { + return this.listAttributeAssignments; + } + + public AttributeAssignmentResult(Status statusIn, Collection<AttributeAssignment> listAttributeAssignmentsIn) { + this.status = statusIn; + if (listAttributeAssignmentsIn != null && listAttributeAssignmentsIn.size() > 0) { + this.listAttributeAssignments = new ArrayList<AttributeAssignment>(); + this.listAttributeAssignments.addAll(listAttributeAssignmentsIn); + } + } + + public AttributeAssignmentResult(Status statusIn) { + this(statusIn, null); + } + + public AttributeAssignmentResult(Collection<AttributeAssignment> listAttributeAssignmentsIn) { + this(StdStatus.STATUS_OK, listAttributeAssignmentsIn); + } + + public Status getStatus() { + return this.status; + } + + public boolean isOk() { + return (this.getStatus() == null || this.getStatus().isOk()); + } + + public Iterator<AttributeAssignment> getAttributeAssignments() { + List<AttributeAssignment> thisListAttributeAssignments = this.getListAttributeAssignments(); + return (thisListAttributeAssignments == null ? null : thisListAttributeAssignments.iterator()); + } + + public int getNumAttributeAssignments() { + List<AttributeAssignment> thisListAttributeAssignments = this.getListAttributeAssignments(); + return (thisListAttributeAssignments == null ? 0 : thisListAttributeAssignments.size()); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + boolean needsComma = false; + + Object objectToDump; + if ((objectToDump = this.getStatus()) != null) { + stringBuilder.append("status="); + stringBuilder.append(objectToDump.toString()); + needsComma = true; + } + + Iterator<?> iterToDump; + if ((iterToDump = this.getAttributeAssignments()) != null) { + if (needsComma) { + stringBuilder.append(','); + } + stringBuilder.append(StringUtils.toString(iterToDump)); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java new file mode 100755 index 0000000..47b7773 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java
@@ -0,0 +1,93 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; + +/** + * Bag represents a collection of XACML attribute values for the same attribute. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class Bag { + public static final Bag EMPTY = new Bag(); + + private List<AttributeValue<?>> attributeValues = new ArrayList<AttributeValue<?>>(); + + /** + * Gets the <code>List</code> of <code>AttributeValue</code>s for this <code>Bag</code>. + * + * @return the <code>List</code> of <code>AttributeValue</code>s for this <code>Bag</code> + */ + public List<AttributeValue<?>> getAttributeValueList() { + return this.attributeValues; + } + + /** + * Creates a new, empty <code>Bag</code>. + */ + public Bag() { + } + + /** + * Creates a new <code>Bag</code> by copying the {@link com.att.research.xacml.api.AttributeValue}s from the + * given <code>Collection</code>. + * + * @param attributeValuesIn the <code>Collection</code> of <code>AttributeValue</code>s for this <code>Bag</code>. + * + public Bag(Collection<AttributeValue<?>> attributeValuesIn) { + if (attributeValuesIn != null) { + this.attributeValues.addAll(attributeValuesIn); + } + } + + public Bag(Iterator<AttributeValue<?>> iterAttributeValuesIn) { + if (iterAttributeValuesIn != null) { + while (iterAttributeValuesIn.hasNext()) { + this.attributeValues.add(iterAttributeValuesIn.next()); + } + } + } + */ + + /** + * Adds an <code>AttributeValue</code> to this <code>Bag</code>> + * + * @param attributeValue the <code>AttributeValue</code> to add + */ + public void add(AttributeValue<?> attributeValue) { + this.attributeValues.add(attributeValue); + } + + /** + * Gets the number of <code>AttributeValue</code>s in this <code>Bag</code>. + * + * @return the number of <code>AttributeValue</code>s in this <code>Bag</code>. + */ + public int size() { + return this.getAttributeValueList().size(); + } + + /** + * Gets an <code>Iterator</code> over all of the <code>AttributeValue</code>s in this <code>Bag</code>. + * + * @return an <code>Iterator</code> over all of the <code>AttributeValue</code>s in this <code>Bag</code>. + */ + public Iterator<AttributeValue<?>> getAttributeValues() { + return this.getAttributeValueList().iterator(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java new file mode 100755 index 0000000..8277428 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java
@@ -0,0 +1,149 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatusCode; + +/** + * CombinerParameter extends {@link PolicyComponent} to represent a XACML CombinerParameter element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class CombinerParameter extends PolicyComponent { + private String name; + private AttributeValue<?> attributeValue; + + @Override + protected boolean validateComponent() { + if (this.getName() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing parameter name"); + return false; + } else if (this.getAttributeValue() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing attribute value"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + /** + * Creates a new <code>CombinerParameter</code> with the given <code>String</code> name, <code>AttributeValue</code>, + * {@link com.att.research.xacml.api.StatusCode} and <code>String</code> status message. + * + * @param nameIn the <code>String</code> name of the <code>CombinerParameter</code> + * @param attributeValueIn the <code>AttributeValue</code> of the <code>CombinerParameter</code> + * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code> + * @param statusMessageIn the <code>String</code> status message of the <code>CombinerParameter</code> + */ + public CombinerParameter(String nameIn, AttributeValue<?> attributeValueIn, StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + this.name = nameIn; + this.attributeValue = attributeValueIn; + } + + /** + * Creates a new <code>CombinerParameter</code> for an error condition with the given <code>StatusCode</code> and + * <code>String</code> status message. + * + * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code> + * @param statusMessageIn the <code>String</code> status message of the <code>CombinerParameter</code> + */ + public CombinerParameter(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + /** + * Creates a new <code>CombinerParameter</code> for an error condition with the given <code>StatusCode</code> and + * null status message. + * + * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code> + */ + public CombinerParameter(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + /** + * Creates a new <code>CombinerParameter</code> with a default <code>StatusCode</code>, null status message, and the given + * <code>String</code> name and <code>AttributeValue</code>> + * + * @param nameIn the <code>String</code> name of the <code>CombinerParameter</code> + * @param attributeValueIn the <code>AttributeValue</code> of the <code>CombinerParameter</code> + */ + public CombinerParameter(String nameIn, AttributeValue<?> attributeValueIn) { + super(); + this.name = nameIn; + this.attributeValue = attributeValueIn; + } + + public CombinerParameter() { + + } + + /** + * Gets the <code>String</code> name of this <code>CombinerParameter</code>. + * + * @return the <code>String</code> name of this <code>CombinerParameter</code> + */ + public String getName() { + return this.name; + } + + /** + * Sets the name of this <code>CombinerParameter</code> to the given <code>String</code>. + * + * @param nameIn the <code>String</code> name for this <code>CombinerParameter</code>. + */ + public void setName(String nameIn) { + this.name = nameIn; + } + + /** + * Gets the <code>AttributeValue</code> of this <code>CombinerParameter</code>. + * + * @return the <code>AttributeValue</code> of this <code>CombinerParameter</code> + */ + public AttributeValue<?> getAttributeValue() { + return this.attributeValue; + } + + /** + * Sets the <code>AttributeValue</code> for this <code>CombinerParameter</code>> + * + * @param attributeValueIn the <code>AttributeValue</code> for this <code>CombinerParameter</code>> + */ + public void setAttributeValue(AttributeValue<?> attributeValueIn) { + this.attributeValue = attributeValueIn; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getName()) != null) { + stringBuilder.append(",name="); + stringBuilder.append((String)objectToDump); + } + if ((objectToDump = this.getAttributeValue()) != null) { + stringBuilder.append(",attributeValue="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java new file mode 100755 index 0000000..d161efa --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java
@@ -0,0 +1,49 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.List; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.Evaluatable; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; + +/** + * CombiningAlgorithm is the interface for objects that implement XACML combining algorithms for rules, policies, and policy sets. + * + * @author car + * @version $Revision: 1.1 $ + * + * @param <T> the type of object to be combined + * @param <U> the type of the identifier for <code>T</code> + */ +public interface CombiningAlgorithm<T extends Evaluatable> { + /** + * Gets the {@link com.att.research.xacml.api.Identifier} for this <code>CombiningAlgorithm</code>. + * + * @return the <code>Identifier</code> for this <code>CombiningAlgorithm</code> + */ + public Identifier getId(); + + /** + * Evaluates as many of the <code>CombiningElement</code>s supplied with the given <code>CombinerParameter</code>s based on + * the particular combining algorithm and combines their <code>EvaluationResult</code>s into a single <code>EvaluationResult</code>. + * + * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate each of the <code>CombiningElement</code>s + * @param elements the <code>List</code> of <code>CombiningElement</code>s to evaluate + * @param combinerParameters the <code>List</code> of <code>CombinerParameter</code>s to apply to the combining algorithm + * @return the combined <code>EvaluationResult</code> + * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the <code>evaluate</code> method of any of the <code>CombiningElement</code>s + */ + public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException; +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java new file mode 100755 index 0000000..b6b278e --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java
@@ -0,0 +1,91 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.Properties; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.FactoryFinder; +import com.att.research.xacmlatt.pdp.util.ATTPDPProperties; + +/** + * CombiningAlgorithmFactory is an abstract class for mapping function {@link com.att.research.xacml.api.Identifier} ids to + * {@link CombiningAlgorithm} objects. + * + * @author car + * @version $Revision: 1.3 $ + */ +public abstract class CombiningAlgorithmFactory { + private static final String FACTORYID = ATTPDPProperties.PROP_COMBININGALGORITHMFACTORY; + private static final String DEFAULT_FACTORY_CLASSNAME = "com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory"; + + protected CombiningAlgorithmFactory() { + } + + protected CombiningAlgorithmFactory(Properties properties) { + } + + /** + * Maps the given <code>Identifier</code> representing a XACML rule combining algorithm to a <code>CombiningAlgorithm</code> object. + * + * @param combiningAlgorithmId the <code>Identifier</code> of the <code>CombiningAlgorithm</code> to retrieve + * @return the <code>CombiningAlgorithm</code> for the given <code>Identifier</code> or null if not found + */ + public abstract CombiningAlgorithm<Rule> getRuleCombiningAlgorithm(Identifier combiningAlgorithmId); + + /** + * Maps the given <code>Identifier</code> representing a XACML policy combinign algorithm to a <code>CombiningAlgorithm</code> object. + * + * @param combiningAlgorithmId the <code.Identifier</code> of the <code>CombiningAlgorithm</code> to retrieve + * @return the <code>CombiningAlgorithm</code> for the given <code>Identifier</code> or null if not found + */ + public abstract CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm(Identifier combiningAlgorithmId); + + /** + * Creates an instance of the <code>CombiningAlgorithmFactory</code> using default configuration information. + * + * @return the default <code>CombiningAlgorithmFactory</code> + */ + public static CombiningAlgorithmFactory newInstance() throws FactoryException { + return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, CombiningAlgorithmFactory.class); + } + + /** + * Creates an instance of the <code>CombiningAlgorithmFactory</code> using default configuration information. + * + * @return the default <code>CombiningAlgorithmFactory</code> + */ + public static CombiningAlgorithmFactory newInstance(Properties properties) throws FactoryException { + return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, CombiningAlgorithmFactory.class, properties); + } + + /** + * Creates an instance of the <code>CombiningAlgorithmFactory</code> using the given class name. + * + * @param className the <code>String</code> class name of the <code>CombiningAlgorithmFactory</code> to create + * @return the <code>CombiningAlgorithmFactory</code> for the given class name. + */ + public static CombiningAlgorithmFactory newInstance(String className) throws FactoryException { + return FactoryFinder.newInstance(className, CombiningAlgorithmFactory.class, null, true); + } + + /** + * Creates an instance of the <code>CombiningAlgorithmFactory</code> using the given class name using the given <code>ClassLoader</code>. + * + * @param className the <code>String</code> class name of the <code>CombiningAlgorithmFactory</code> to create + * @param classLoader the <code>ClassLoader</code> to use to load the class with the given class name + * @return the <code>CombiningAlgorithmFactory</code> for the given class name + */ + public static CombiningAlgorithmFactory newInstance(String className, ClassLoader classLoader) throws FactoryException { + return FactoryFinder.newInstance(className, CombiningAlgorithmFactory.class, classLoader, false); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java new file mode 100755 index 0000000..8890b1a --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java
@@ -0,0 +1,82 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacmlatt.pdp.eval.Evaluatable; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; + +/** + * CombiningElement wraps an {@link com.att.research.xacmlatt.pdp.evl.Evaluatable} with a set of + * {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s for use with a + * {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} to get a combined {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult} + * + * @author car + * @version $Revision: 1.1 $ + * + * @param <T> the java class extending <code>Evaluatable</code> of the objects to be combined + */ +public class CombiningElement<T extends Evaluatable> { + private T evaluatable; + private List<CombinerParameter> targetedCombinerParameters; + + /** + * Creates a new <code>CombiningElement</code> with the given <code>Evaluatable</code> and <code>List</code> of + * <code>TargetedCombinerParameter</code>. + * + * @param evaluatableIn the <code>Evaluatable</code> + * @param targetedCombinerParametersIn the <code>List</code> of <code>TargetedCombinerParameter</code>s. + */ + public CombiningElement(T evaluatableIn, Collection<CombinerParameter> targetedCombinerParametersIn) { + this.evaluatable = evaluatableIn; + if (targetedCombinerParametersIn != null) { + this.targetedCombinerParameters = new ArrayList<CombinerParameter>(); + this.targetedCombinerParameters.addAll(targetedCombinerParametersIn); + } + } + + /** + * Gets the <code>Evaluatable</code> for this <code>CombiningElement</code>. + * + * @return the <code>Evaluatable</code> for this <code>CombiningElement</code> + */ + public T getEvaluatable() { + return this.evaluatable; + } + + /** + * Gets an <code>Iterator</code> over the <code>TargetedCombinerParameters</code> for this + * <code>CombiningElement</code>. + * + * @return an <code>Iterator</code> over the <code>TargetedCombinerParameters</code> for this <code>CombiningElement</code> + */ + public Iterator<CombinerParameter> getTargetedCombinerParameters() { + return (this.targetedCombinerParameters == null ? null : this.targetedCombinerParameters.iterator()); + } + + /** + * Evaluates this <code>CombiningElement</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}. + * + * @param evaluationContext the <code>EvaluationContext</code> + * @return the {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult} from the <code>Evaluatable</code> + * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the <code>evaluate</code> method of the <code>Evaluatable</code> + */ + public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException { + return this.getEvaluatable().evaluate(evaluationContext); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java new file mode 100755 index 0000000..0f02f78 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java
@@ -0,0 +1,149 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; + +/** + * Condition extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent the XACML Condition element + * in a XACML Rule. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class Condition extends PolicyComponent { + private static final Status STATUS_PE_RETURNED_BAG = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Condition Expression returned a bag"); + private static final ExpressionResultBoolean ERB_RETURNED_BAG = new ExpressionResultBoolean(STATUS_PE_RETURNED_BAG); + private static final Status STATUS_PE_RETURNED_NULL = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null value from Condition Expression"); + private static final ExpressionResultBoolean ERB_RETURNED_NULL = new ExpressionResultBoolean(STATUS_PE_RETURNED_NULL); + private static final Status STATUS_PE_RETURNED_NON_BOOLEAN = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Non-boolean value from Condition Expression"); + private static final ExpressionResultBoolean ERB_RETURNED_NON_BOOLEAN = new ExpressionResultBoolean(STATUS_PE_RETURNED_NON_BOOLEAN); + private static final Status STATUS_PE_INVALID_BOOLEAN = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Invalid Boolean value"); + private static final ExpressionResultBoolean ERB_INVALID_BOOLEAN = new ExpressionResultBoolean(STATUS_PE_INVALID_BOOLEAN); + + private Expression expression; + + /** + * Creates a <code>Condition</code> with the given {@link com.att.research.xacml.api.StatusCode} and <code>String</code> + * status message. + * + * @param statusCodeIn the <code>StatusCode</code> for the <code>Condition</code> + * @param statusMessageIn the <code>String</code> status message for the <code>Condition</code> + */ + public Condition(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + /** + * Creates a <code>Condition</code> with the given <code>StatusCode</code. and a null status message. + * + * @param statusCodeIn the <code>StatusCode</code> for the <code>Condition</code> + */ + public Condition(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + /** + * Creates an empty <code>Condition</code> + */ + public Condition() { + } + + /** + * Creates a new <code>Condition</code> with the given {@link com.att.research.xacmlatt.pdp.policy.Expression} and a default + * OK <code>StatusCode</code>. + * + * @param expressionIn the <code>Expression</code> for the <code>Condition</code> + */ + public Condition(Expression expressionIn) { + this.expression = expressionIn; + } + + public Expression getExpression() { + return this.expression; + } + + public void setExpression(Expression expressionIn) { + this.expression = expressionIn; + } + + @Override + protected boolean validateComponent() { + if (this.getExpression() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + /** + * Evaluates the <code>Expression</code> in this <code>Condition</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}. + * and validates that the result is a boolean. + * + * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>Expression</code> + * @param policyDefaults the {@link com.att.research.xacml.pdp.policy.PolicyDefaults} to use in evaluating this <code>Expression</code> + * @return a {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} + */ + public ExpressionResultBoolean evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return new ExpressionResultBoolean(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + /* + * Evaluate the expression + */ + ExpressionResult expressionResult = this.getExpression().evaluate(evaluationContext, policyDefaults); + assert(expressionResult != null); + + if (!expressionResult.isOk()) { + return new ExpressionResultBoolean(expressionResult.getStatus()); + } + + /* + * Ensure the result is a single element of type boolean + */ + if (expressionResult.isBag()) { + return ERB_RETURNED_BAG; + } + AttributeValue<?> attributeValueResult = expressionResult.getValue(); + if (attributeValueResult == null) { + return ERB_RETURNED_NULL; + } else if (!DataTypes.DT_BOOLEAN.getId().equals(attributeValueResult.getDataTypeId())) { + return ERB_RETURNED_NON_BOOLEAN; + } + + /* + * Otherwise it is a valid condition evaluation + */ + Boolean booleanValue = null; + try { + booleanValue = DataTypes.DT_BOOLEAN.convert(attributeValueResult.getValue()); + } catch (DataTypeException ex) { + return new ExpressionResultBoolean(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage())); + } + if (booleanValue == null) { + return ERB_INVALID_BOOLEAN; + } else { + return (booleanValue.booleanValue() ? ExpressionResultBoolean.ERB_TRUE : ExpressionResultBoolean.ERB_FALSE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java new file mode 100755 index 0000000..c40c41a --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java
@@ -0,0 +1,44 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; + +/** + * Expression extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent a XACML ExpressionType element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public abstract class Expression extends PolicyComponent { + + public Expression(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public Expression(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public Expression() { + } + + /** + * Evaluates this <code>Expression</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}. + * + * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>Expression</code> + * @param policyDefaults the {@link com.att.research.xacml.pdp.policy.PolicyDefaults} to use in evaluating this <code>Expression</code> + * @return a {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} + */ + public abstract ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException; +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java new file mode 100755 index 0000000..778861f --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java
@@ -0,0 +1,254 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.Iterator; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; + +/** + * ExpressionResult is the object returned by the <code>evaluate</code> method of {@link Expression} + * objects. + * + * @author car + * @version $Revision: 1.1 $ + */ +public abstract class ExpressionResult implements FunctionArgument { + private Status status; + + /** + * ExpressionResultError extends <code>ExpressionResult</code> to represent error results. + * + * @author car + * @version $Revision: 1.1 $ + */ + private static class ExpressionResultError extends ExpressionResult { + public ExpressionResultError(Status statusIn) { + super(statusIn); + } + + @Override + public AttributeValue<?> getValue() { + return null; + } + + @Override + public boolean isBag() { + return false; + } + + @Override + public Bag getBag() { + return null; + } + } + + /** + * ExpressionResultSingle extends <code>ExpressionResult</code> to represent results with a single value. + * + * @author car + * @version $Revision: 1.1 $ + */ + private static class ExpressionResultSingle extends ExpressionResult { + AttributeValue<?> attributeValue; + + public ExpressionResultSingle(AttributeValue<?> attributeValueIn) { + super(StdStatus.STATUS_OK); + this.attributeValue = attributeValueIn; + } + + @Override + public AttributeValue<?> getValue() { + return this.attributeValue; + } + + @Override + public boolean isBag() { + return false; + } + + @Override + public Bag getBag() { + return null; + } + } + + private static class ExpressionResultBag extends ExpressionResult { + private Bag bag; + + public ExpressionResultBag(Bag bagIn) { + super(StdStatus.STATUS_OK); + this.bag = bagIn; + } + + @Override + public AttributeValue<?> getValue() { + Iterator<AttributeValue<?>> iter = this.bag.getAttributeValues(); + if (iter != null && iter.hasNext()) { + return iter.next(); + } else { + return null; + } + } + + @Override + public boolean isBag() { + return true; + } + + @Override + public Bag getBag() { + return this.bag; + } + } + + private static class ExpressionResultEmptyBag extends ExpressionResult { + public ExpressionResultEmptyBag() { + super(StdStatus.STATUS_OK); + } + + @Override + public AttributeValue<?> getValue() { + return null; + } + + @Override + public boolean isBag() { + return true; + } + + @Override + public Bag getBag() { + return Bag.EMPTY; + } + } + + /** + * Creates a new <code>ExpressionResult</code> with the given {@link com.att.research.xacml.api.Status}. + * + * @param statusIn the <code>Status</code> of this <code>ExpressionResult</code> + */ + protected ExpressionResult(Status statusIn) { + this.status = statusIn; + } + + /** + * Gets the <code>Status</code> for this <code>ExpressionResult</code>. + * + * @return the <code>Status</code> for this <code>ExpressionResult</code> + */ + public Status getStatus() { + return this.status; + } + + /** + * Shortcut procedure for determining if the <code>Status</code> of this <code>ExpressionResult</code> is OK. + * + * @return true if the <code>Status</code> is null or has a <code>StatusCode</code> value of <code>STATUS_CODE_OK</code>. + */ + public boolean isOk() { + return (this.getStatus() == null || this.getStatus().isOk()); + } + + /** + * Gets the single {@link com.att.research.xacml.api.AttributeValue} from this <code>ExpressionResult</code>. If this + * <code>ExpressionResult</code> represents a bag, the first element in the bag is returned. + * + * @return a single <code>AttributeValue</code> from this <code>ExpressionResult</code> + */ + public abstract AttributeValue<?> getValue(); + + /** + * Determines if this <code>ExpressionResult</code> represents a bag of <code>AttributeValue</code>s or not. + * + * @return true if this <code>ExpressionResult</code> represents a bag of <code>AttributeValue</code>s, else false + */ + public abstract boolean isBag(); + + /** + * Gets the {@link Bag} of values for this <code>ExpressionResult</code> if + * there is one. + * + * @return the <code>Bag</code> of <code>AttributeValue</code>s for this <code>ExpressionResult</code>. + */ + public abstract Bag getBag(); + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("isOk=" + this.isOk()); + stringBuilder.append(", isBag=" + this.isBag()); + Status thisStatus = this.getStatus(); + if (thisStatus != null) { + stringBuilder.append(", status="); + stringBuilder.append(thisStatus.toString()); + } + AttributeValue<?> value = this.getValue(); + if (value != null) { + stringBuilder.append(", value="); + stringBuilder.append(value); + } + /* + * Not sure if I want this dumped + if (this.isBag()) { + Bag bag = this.getBag(); + if (bag != null) { + } + } + */ + stringBuilder.append('}'); + return stringBuilder.toString(); + } + /** + * Creates a new instance of the <code>ExpressionResult</code> class representing an error. + * + * @param statusIn the <code>Status</code> containing the error information + * @return a new <code>ExpressionResult</code> representing the error + */ + public static ExpressionResult newError(Status statusIn) { + return new ExpressionResultError(statusIn); + } + + public static ExpressionResult newSingle(AttributeValue<?> attributeValue) { + return new ExpressionResultSingle(attributeValue); + } + + /** + * Creates a new instance of the <code>ExpressionResult</code> class representing a bag of values + * from the given <code>Bag</code>. + * + * @param bag the <code>Bag</code> for the new <code>ExpressionResult</code> + * @return a new <code>ExpressionResult</code> representing the given <code>Bag</code>. + */ + public static ExpressionResult newBag(Bag bag) { + return new ExpressionResultBag(bag); + } + + /** + * Creates a new instance of the <code>ExpressionResult</code> class representing an empty bag of values. + * + * @return the <code>ExpressionResult</code> representing the empty bag of values of the expression + */ + public static ExpressionResult newEmpty() { + return new ExpressionResultEmptyBag(); + } + + public static ExpressionResult newInstance(Status statusIn) { + if (statusIn.getStatusCode().equals(StdStatus.STATUS_OK.getStatusCode())) { + return newEmpty(); + } else { + return newError(statusIn); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java new file mode 100755 index 0000000..3554dfa --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java
@@ -0,0 +1,65 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.datatypes.DataTypeBoolean; + +/** + * ExpressionResultBoolean extends {@link ExpressionResult} to represent predicates. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class ExpressionResultBoolean extends ExpressionResult { + private AttributeValue<Boolean> value; + public static final ExpressionResultBoolean ERB_FALSE = new ExpressionResultBoolean(false); + public static final ExpressionResultBoolean ERB_TRUE = new ExpressionResultBoolean(true); + + public ExpressionResultBoolean(Status statusIn) { + super(statusIn); + } + + public ExpressionResultBoolean(boolean bvalue) { + super(StdStatus.STATUS_OK); + this.value = (bvalue ? DataTypeBoolean.AV_TRUE : DataTypeBoolean.AV_FALSE); + } + + /** + * Gets the <code>boolean</code> value of this <code>ExpressionResultBoolean</code> + * + * @return the <code>boolean</code> value of this <code>ExpressionResultBoolean</code> + */ + public boolean isTrue() { + if (this.value == null) { + return false; + } else { + return this.value.getValue().booleanValue(); + } + } + + @Override + public AttributeValue<?> getValue() { + return this.value; + } + + @Override + public boolean isBag() { + return false; + } + + @Override + public Bag getBag() { + return null; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java new file mode 100755 index 0000000..207da3d --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java
@@ -0,0 +1,62 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Status; + +/** + * FunctionArgument is the interface implemented by objects that can serve as arguments to a {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} + * <code>evaluate</code> call. + * + * @author car + * @version $Revision: 1.3 $ + */ +public interface FunctionArgument { + /** + * Gets the {@link com.att.research.xacml.api.Status} from the evaluation of this <code>FunctionArgument</code>. + * + * @return the <code>Status</code> from the evaluation of this <code>FunctionArgument</code>> + */ + public Status getStatus(); + + /** + * Determines if this <code>FunctionArgument</code> is OK and can have its <code>AttributeValue</code> or + * <code>Bag</code> retrieved. + * + * @return true if this <code>FunctionArgument</code> is OK, otherwise false. + */ + public boolean isOk(); + + /** + * Determines if this <code>FunctionArgument</code> represents a bag of values. + * + * @return true if this <code>FunctionArgument</code> represents a bag of values, else false. + */ + public boolean isBag(); + + /** + * Gets the single <code>AttributeValue</code> representing the value of this <code>FunctionArgument</code>. If + * this <code>FunctionArgument</code> represents a bag, the value returned is up to the implementation. + * + * @return the single <code>AttributeValue</code> representing the value of this <code>FunctionArgument</code>. + */ + public AttributeValue<?> getValue(); + + /** + * Gets the {@link Bag} value for this <code>FunctionArgument</code> if the + * argument represents a <code>Bag</code>, (i.e. <code>isBag</code> returns true). + * + * @return the <code>Bag</code> value for this <code>FunctionArgument</code>. + */ + public Bag getBag(); + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java new file mode 100755 index 0000000..d81c14b --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java
@@ -0,0 +1,59 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; + +/** + * FunctionArgumentAttributeValue implements {@link FunctionArgument} for a single + * {@link com.att.research.xacml.api.AttributeValue} + * @author car + * + */ +public class FunctionArgumentAttributeValue implements FunctionArgument { + private AttributeValue<?> attributeValue; + + /** + * Creates a new <code>FunctionArgumentAttributeValue</code> from the given <code>AttributeValue</code>. + * + * @param attributeValueIn the <code>AttributeValue</code> for the new <code>FunctionArgumentAttributeValue</code>. + */ + public FunctionArgumentAttributeValue(AttributeValue<?> attributeValueIn) { + this.attributeValue = attributeValueIn; + } + + @Override + public Status getStatus() { + return StdStatus.STATUS_OK; + } + + @Override + public boolean isOk() { + return true; + } + + @Override + public boolean isBag() { + return false; + } + + @Override + public AttributeValue<?> getValue() { + return this.attributeValue; + } + + @Override + public Bag getBag() { + return null; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java new file mode 100755 index 0000000..9fc66cd --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java
@@ -0,0 +1,67 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.Iterator; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; + +/** + * FunctionArgumentBag implements the {@link FunctionArgument} interface for + * a {@link Bag} objects. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class FunctionArgumentBag implements FunctionArgument { + private Bag bag; + + /** + * Creates a new <code>FunctionArgumentBag</code> from the given <code>Bag</code>. + * + * @param bagIn the <code>Bag</code> for the new <code>FunctionArgumentBag</code>. + */ + public FunctionArgumentBag(Bag bagIn) { + this.bag = bagIn; + } + + @Override + public Status getStatus() { + return StdStatus.STATUS_OK; + } + + @Override + public boolean isOk() { + return true; + } + + @Override + public boolean isBag() { + return true; + } + + @Override + public AttributeValue<?> getValue() { + Iterator<AttributeValue<?>> iterAttributeValues = this.bag.getAttributeValues(); + if (iterAttributeValues == null || !iterAttributeValues.hasNext()) { + return null; + } else { + return iterAttributeValues.next(); + } + } + + @Override + public Bag getBag() { + return this.bag; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java new file mode 100755 index 0000000..5845280 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java
@@ -0,0 +1,113 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; + +/** + * FunctionArgumentExpression implements the {@link FunctionArgument} interface for + * unevaluated {@link Expression}s. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class FunctionArgumentExpression implements FunctionArgument { + private static final Status STATUS_NULL_EXPRESSION_RESULT = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null expression result"); + + private Expression expression; + private EvaluationContext evaluationContext; + private ExpressionResult expressionResult; + private PolicyDefaults policyDefaults; + + protected ExpressionResult evaluateExpression() { + if (this.getExpression() != null && this.getEvaluationContext() != null) { + try { + this.expressionResult = this.getExpression().evaluate(this.getEvaluationContext(), this.getPolicyDefaults()); + } catch (EvaluationException ex) { + this.expressionResult = ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage())); + } + } + return this.expressionResult; + } + + public FunctionArgumentExpression() { + } + + public FunctionArgumentExpression(Expression expressionIn, EvaluationContext evaluationContextIn, PolicyDefaults policyDefaultsIn) { + this.expression = expressionIn; + this.evaluationContext = evaluationContextIn; + this.policyDefaults = policyDefaultsIn; + } + + protected ExpressionResult getExpressionResult() { + return this.expressionResult; + } + + protected Expression getExpression() { + return this.expression; + } + + protected EvaluationContext getEvaluationContext() { + return this.evaluationContext; + } + + protected PolicyDefaults getPolicyDefaults() { + + return this.policyDefaults; + } + + @Override + public Status getStatus() { + ExpressionResult thisExpressionResult = this.getExpressionResult(); + if (thisExpressionResult == null) { + thisExpressionResult = this.evaluateExpression(); + } + return (thisExpressionResult == null ? STATUS_NULL_EXPRESSION_RESULT : thisExpressionResult.getStatus()); + } + + @Override + public boolean isOk() { + Status thisStatus = this.getStatus(); + return (thisStatus == null ? true : thisStatus.isOk()); + } + + @Override + public boolean isBag() { + ExpressionResult thisExpressionResult = this.getExpressionResult(); + if (thisExpressionResult == null) { + thisExpressionResult = this.evaluateExpression(); + } + return (thisExpressionResult == null ? false : thisExpressionResult.isBag()); + } + + @Override + public AttributeValue<?> getValue() { + ExpressionResult thisExpressionResult = this.getExpressionResult(); + if (thisExpressionResult == null) { + thisExpressionResult = this.evaluateExpression(); + } + return (thisExpressionResult == null ? null : thisExpressionResult.getValue()); + } + + @Override + public Bag getBag() { + ExpressionResult thisExpressionResult = this.getExpressionResult(); + if (thisExpressionResult == null) { + thisExpressionResult = this.evaluateExpression(); + } + return (thisExpressionResult == null ? null : thisExpressionResult.getBag()); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java new file mode 100755 index 0000000..d112318 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java
@@ -0,0 +1,56 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.List; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; + +/** + * FunctionDefinition is the interface that objects representing XACML functions found in Match and Apply elements in Policies, PolicySets + * and Rules. + * + * @author car + * @version $Revision: 1.1 $ + */ +public interface FunctionDefinition { + /** + * Gets the {@link com.att.research.xacml.api.Identifier} for this <code>FunctionDefinition</code>. + * + * @return the <code>Identifier</code> for this <code>FunctionDefinition</code>. + */ + public Identifier getId(); + + /** + * Returns the <code>Identifier</code> for the data type returned by this function if <code>returnsBag()</code> is false or + * if this <code>FunctionDefinition</code> returns a bag containing a single data type. Otherwise it returns null. + * + * @return the <code>Identifier</code> for the XACML data type this <code>FunctionDefinition</code> returns + */ + public Identifier getDataTypeId(); + + /** + * Determines if this <code>FunctionDefinition</code> returns a bag of values or a single value. + * + * @return true if this <code>FunctionDefinition</code> returns a bag, else false + */ + public boolean returnsBag(); + + /** + * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link FunctionArgument}s. + * + * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation + * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation + * @return an {@link ExpressionResult} with the results of the call + */ + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments); +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java new file mode 100755 index 0000000..f204729 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java
@@ -0,0 +1,83 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.Properties; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.FactoryFinder; +import com.att.research.xacmlatt.pdp.util.ATTPDPProperties; + +/** + * FunctionDefinitionFactory is an abstract class for mapping function {@link com.att.research.xacml.api.Identifier} ids to + * {@link FunctionDefinition} objects. + * + * @author car + * @version $Revision: 1.3 $ + */ +public abstract class FunctionDefinitionFactory { + private static final String FACTORYID = ATTPDPProperties.PROP_FUNCTIONDEFINITIONFACTORY; + private static final String DEFAULT_FACTORY_CLASSNAME = "com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory"; + + protected FunctionDefinitionFactory() { + } + + protected FunctionDefinitionFactory(Properties properties) { + } + + /** + * Maps the given <code>Identifier</code> representing a XACML function to a <code>FunctionDefinition</code> object. + * + * @param functionId the <code>Identifier</code> of the <code>FunctionDefinition</code> to retrieve + * @return the <code>FunctionDefinition</code> for the given <code>Identifier</code> or null if not found + */ + public abstract FunctionDefinition getFunctionDefinition(Identifier functionId); + + /** + * Creates an instance of the <code>FunctionDefinitionFactory</code> using default configuration information. + * + * @return the default <code>FunctionDefinitionFactory</code> + */ + public static FunctionDefinitionFactory newInstance() throws FactoryException { + return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, FunctionDefinitionFactory.class); + } + + /** + * Creates an instance of the <code>FunctionDefinitionFactory</code> using default configuration information. + * + * @return the default <code>FunctionDefinitionFactory</code> + */ + public static FunctionDefinitionFactory newInstance(Properties properties) throws FactoryException { + return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, FunctionDefinitionFactory.class, properties); + } + + /** + * Creates an instance of the <code>FunctionDefinitionFactory</code> using the given class name. + * + * @param className the <code>String</code> class name of the <code>FunctionDefinitionFactory</code> to create + * @return the <code>FunctionDefinitionFactory</code> for the given class name. + */ + public static FunctionDefinitionFactory newInstance(String className) throws FactoryException { + return FactoryFinder.newInstance(className, FunctionDefinitionFactory.class, null, true); + } + + /** + * Creates an instance of the <code>FunctionDefinitionFactory</code> using the given class name using the given <code>ClassLoader</code>. + * + * @param className the <code>String</code> class name of the <code>FunctionDefinitionFactory</code> to create + * @param classLoader the <code>ClassLoader</code> to use to load the class with the given class name + * @return the <code>FunctionDefinitionFactory</code> for the given class name + */ + public static FunctionDefinitionFactory newInstance(String className, ClassLoader classLoader) throws FactoryException { + return FactoryFinder.newInstance(className, FunctionDefinitionFactory.class, classLoader, false); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java new file mode 100755 index 0000000..d32b8cc --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java
@@ -0,0 +1,243 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.MatchResult; +import com.att.research.xacmlatt.pdp.eval.Matchable; +import com.att.research.xacmlatt.pdp.policy.expressions.AttributeRetrievalBase; + +/** + * Match extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the + * {@link com.att.research.xacmlatt.pdp.eval.Matchable} interface to represent a XACML Match element. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class Match extends PolicyComponent implements Matchable { + private Identifier matchId; + private AttributeValue<?> attributeValue; + private AttributeRetrievalBase attributeRetrievalBase; + private PolicyDefaults policyDefaults; + private FunctionDefinition functionDefinition; + + protected FunctionDefinition getFunctionDefinition() { + Identifier functionDefinitionId = this.getMatchId(); + if (this.functionDefinition == null && functionDefinitionId != null) { + try { + this.functionDefinition = FunctionDefinitionFactory.newInstance().getFunctionDefinition(functionDefinitionId); + } catch (FactoryException ex) { + this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "FactoryException getting FunctionDefinition"); + } + } + return this.functionDefinition; + } + + public Match(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public Match(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public Match() { + } + + public Match(Identifier matchIdIn, AttributeValue<?> attributeValueIn, AttributeRetrievalBase attributeRetrievalBaseIn, PolicyDefaults policyDefaultsIn) { + this(StdStatusCode.STATUS_CODE_OK); + this.matchId = matchIdIn; + this.attributeValue = attributeValueIn; + this.attributeRetrievalBase = attributeRetrievalBaseIn; + this.policyDefaults = policyDefaultsIn; + } + + public Identifier getMatchId() { + return this.matchId; + } + + public void setMatchId(Identifier matchIdIn) { + this.matchId = matchIdIn; + } + + public AttributeValue<?> getAttributeValue() { + return this.attributeValue; + } + + public void setAttributeValue(AttributeValue<?> attributeValueIn) { + this.attributeValue = attributeValueIn; + } + + public AttributeRetrievalBase getAttributeRetrievalBase() { + return this.attributeRetrievalBase; + } + + public void setAttributeRetrievalBase(AttributeRetrievalBase attributeRetrievalBaseIn) { + this.attributeRetrievalBase = attributeRetrievalBaseIn; + } + + public PolicyDefaults getPolicyDefaults() { + return this.policyDefaults; + } + + public void setPolicyDefaults(PolicyDefaults policyDefaultsIn) { + this.policyDefaults = policyDefaultsIn; + } + + private static MatchResult match(EvaluationContext evaluationContext, FunctionDefinition functionDefinition, FunctionArgument arg1, FunctionArgument arg2) throws EvaluationException { + List<FunctionArgument> listArguments = new ArrayList<FunctionArgument>(2); + listArguments.add(arg1); + listArguments.add(arg2); + + ExpressionResult expressionResult = functionDefinition.evaluate(evaluationContext, listArguments); + assert(expressionResult != null); + if (!expressionResult.isOk()) { + return new MatchResult(expressionResult.getStatus()); + } + + AttributeValue<Boolean> attributeValueResult = null; + try { + attributeValueResult = DataTypes.DT_BOOLEAN.convertAttributeValue(expressionResult.getValue()); + } catch (DataTypeException ex) { + return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage())); + } + if (attributeValueResult == null) { + return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Non-boolean result from Match Function " + functionDefinition.getId() + " on " + expressionResult.getValue().toString())); + } else if (attributeValueResult.getValue().booleanValue()) { + return MatchResult.MM_MATCH; + } else { + return MatchResult.MM_NOMATCH; + } + + } + + @Override + public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException { + if (!this.validate()) { + return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + FunctionDefinition functionDefinitionMatch = this.getFunctionDefinition(); + assert(functionDefinitionMatch != null); + + AttributeValue<?> attributeValue = this.getAttributeValue(); + assert(attributeValue != null); + FunctionArgument functionArgument1 = new FunctionArgumentAttributeValue(attributeValue); + + AttributeRetrievalBase attributeRetrievalBase = this.getAttributeRetrievalBase(); + assert(attributeRetrievalBase != null); + + ExpressionResult expressionResult = attributeRetrievalBase.evaluate(evaluationContext, this.getPolicyDefaults()); + assert(expressionResult != null); + if (!expressionResult.isOk()) { + return new MatchResult(expressionResult.getStatus()); + } + + if (expressionResult.isBag()) { + MatchResult matchResult = MatchResult.MM_NOMATCH; + Bag bagAttributeValues = expressionResult.getBag(); + if (bagAttributeValues != null) { + Iterator<AttributeValue<?>> iterAttributeValues = bagAttributeValues.getAttributeValues(); + while (matchResult.getMatchCode() != MatchResult.MatchCode.MATCH && iterAttributeValues.hasNext()) { + MatchResult matchResultValue = match(evaluationContext, functionDefinitionMatch, functionArgument1, new FunctionArgumentAttributeValue(iterAttributeValues.next())); + switch(matchResultValue.getMatchCode()) { + case INDETERMINATE: + if (matchResult.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) { + matchResult = matchResultValue; + } + break; + case MATCH: + matchResult = matchResultValue; + break; + case NOMATCH: + break; + } + } + } + return matchResult; + } else { + /* + * There is a single value, so add it as the second argument and do the one function evaluation + */ + AttributeValue<?> attributeValueExpressionResult = expressionResult.getValue(); + if (attributeValueExpressionResult == null) { + return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null AttributeValue")); + } + + return match(evaluationContext, functionDefinitionMatch, functionArgument1, new FunctionArgumentAttributeValue(attributeValueExpressionResult)); + } + } + + @Override + protected boolean validateComponent() { + FunctionDefinition functionDefinitionHere; + if (this.getAttributeValue() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeValue"); + return false; + } else if (this.getMatchId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing MatchId"); + return false; + } else if ((functionDefinitionHere = this.getFunctionDefinition()) == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Unknown MatchId \"" + this.getMatchId().toString() + "\""); + return false; + } else if (functionDefinitionHere.returnsBag()) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "FunctionDefinition returns a bag"); + return false; + } else if (functionDefinitionHere.getDataTypeId() == null || !functionDefinitionHere.getDataTypeId().equals(XACML.ID_DATATYPE_BOOLEAN)) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Non-Boolean return type for FunctionDefinition"); + return false; + } else if (this.getAttributeRetrievalBase() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeSelector or AttributeDesignator"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getMatchId()) != null) { + stringBuilder.append(",matchId="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getAttributeValue()) != null) { + stringBuilder.append(",attributeValue="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getAttributeRetrievalBase()) != null) { + stringBuilder.append(",attributeRetrieval="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java new file mode 100755 index 0000000..3ef01ef --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java
@@ -0,0 +1,174 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.AttributeAssignment; +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Obligation; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdMutableObligation; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; + +/** + * ObligationExpression extends {@link PolicyComponent} to implement the XACML + * ObligationExpression element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class ObligationExpression extends PolicyComponent { + private Identifier obligationId; + private RuleEffect ruleEffect; + private List<AttributeAssignmentExpression> attributeAssignmentExpressions; + + protected List<AttributeAssignmentExpression> getAttributeAssignmentExpressionList(boolean bNoNull) { + if (this.attributeAssignmentExpressions == null && bNoNull) { + this.attributeAssignmentExpressions = new ArrayList<AttributeAssignmentExpression>(); + } + return this.attributeAssignmentExpressions; + } + + protected void clearAttributeAssignmentExpressions() { + if (this.attributeAssignmentExpressions != null) { + this.attributeAssignmentExpressions.clear(); + } + } + + public ObligationExpression(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public ObligationExpression(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public ObligationExpression() { + } + + public Identifier getObligationId() { + return this.obligationId; + } + + public void setObligationId(Identifier identifier) { + this.obligationId = identifier; + } + + public RuleEffect getRuleEffect() { + return this.ruleEffect; + } + + public void setRuleEffect(RuleEffect ruleEffectIn) { + this.ruleEffect = ruleEffectIn; + } + + public Iterator<AttributeAssignmentExpression> getAttributeAssignmentExpressions() { + List<AttributeAssignmentExpression> listAttributeAssignmentExpressions = this.getAttributeAssignmentExpressionList(false); + return (listAttributeAssignmentExpressions == null ? null : listAttributeAssignmentExpressions.iterator()); + } + + public void setAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressionsIn) { + this.clearAttributeAssignmentExpressions(); + if (attributeAssignmentExpressionsIn != null) { + this.addAttributeAssignmentExpressions(attributeAssignmentExpressionsIn); + } + } + + public void addAttributeAssignmentExpression(AttributeAssignmentExpression attributeAssignmentExpression) { + List<AttributeAssignmentExpression> listAttributeAssignmentExpressions = this.getAttributeAssignmentExpressionList(true); + listAttributeAssignmentExpressions.add(attributeAssignmentExpression); + } + + public void addAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressionsIn) { + List<AttributeAssignmentExpression> listAttributeAssignmentExpressions = this.getAttributeAssignmentExpressionList(true); + listAttributeAssignmentExpressions.addAll(attributeAssignmentExpressionsIn); + } + + /** + * Evaluates this <code>ObligationExpression</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} + * to get an {@link com.att.research.xacml.api.Obligation} to include in a PDP result. + * + * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>ObligationExpression</code> + * @param policyDefaults the <code>PolicyDefaults</code> to apply to the evaluation + * @return a new <code>Obliagion</code> from this <code>ObligationExpression</code> + * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error evaluating any of the <code>AttributeAssignmentExpression</code>s + */ + public Obligation evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return null; + } + List<AttributeAssignment> listAttributeAssignments = new ArrayList<AttributeAssignment>(); + Iterator<AttributeAssignmentExpression> iterAttributeAssignmentExpressions = this.getAttributeAssignmentExpressions(); + if (iterAttributeAssignmentExpressions != null) { + while (iterAttributeAssignmentExpressions.hasNext()) { + AttributeAssignmentResult attributeAssignmentResult = iterAttributeAssignmentExpressions.next().evaluate(evaluationContext, policyDefaults); + if (attributeAssignmentResult.isOk() && attributeAssignmentResult.getNumAttributeAssignments() > 0) { + Iterator<AttributeAssignment> iterAttributeAssignments = attributeAssignmentResult.getAttributeAssignments(); + while (iterAttributeAssignments.hasNext()) { + listAttributeAssignments.add(iterAttributeAssignments.next()); + } + } + } + } + return new StdMutableObligation(this.getObligationId(), listAttributeAssignments); + } + + /** + * Evaluates a <code>Collection</code> of <code>ObligationExpression</code>s in the given <code>EvaluationContext</code> and returns + * a <code>List</code> of <code>Obligation</code>s. + * + * @param evaluationContext + * @param policyDefaults + * @param listObligationExpressions + * @return + * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException + */ + public static List<Obligation> evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults, Decision decision, Collection<ObligationExpression> listObligationExpressions) throws EvaluationException { + List<Obligation> listObligations = new ArrayList<Obligation>(); + Iterator<ObligationExpression> iterObligationExpressions = listObligationExpressions.iterator(); + while (iterObligationExpressions.hasNext()) { + ObligationExpression obligationExpression = iterObligationExpressions.next(); + obligationExpression.validateComponent(); + if ( ! obligationExpression.isOk()) { + throw new EvaluationException(obligationExpression.getStatusMessage()); + } + if (decision == null || obligationExpression.getRuleEffect().getDecision().equals(decision)) { + Obligation obligation = obligationExpression.evaluate(evaluationContext, policyDefaults); + if (obligation != null) { + listObligations.add(obligation); + } + } + } + return listObligations; + } + + @Override + protected boolean validateComponent() { + if (this.getObligationId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing ObligationId attribute"); + return false; + } else if (this.getRuleEffect() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FulfillOn attribute"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java new file mode 100755 index 0000000..a7efaa5 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java
@@ -0,0 +1,323 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.trace.StdTraceEvent; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.eval.MatchResult; + +/** + * Policy extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} to represent a XACML 3.0 Policy element. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class Policy extends PolicyDef { + private TargetedCombinerParameterMap<String,Rule> ruleCombinerParameters = new TargetedCombinerParameterMap<String,Rule>(); + private VariableMap variableMap = new VariableMap(); + private List<Rule> rules = new ArrayList<Rule>(); + private List<CombiningElement<Rule>> combiningRules; + private CombiningAlgorithm<Rule> ruleCombiningAlgorithm; + + @Override + protected boolean validateComponent() { + if (super.validateComponent()) { + if (this.getRuleCombiningAlgorithm() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing rule combining algorithm"); + return false; + } else { + return true; + } + } else { + return false; + } + } + + /** + * Performs lazy evaluation of the combining parameters from this <code>Policy</code>. + * + * @return the <code>List</code> of <code>CombiningElement</code>s for all of the <code>Rule</code>s + */ + protected List<CombiningElement<Rule>> getCombiningRules() { + if (this.combiningRules == null) { + this.combiningRules = new ArrayList<CombiningElement<Rule>>(); + Iterator<Rule> iterRules = this.getRules(); + while (iterRules.hasNext()) { + Rule rule = iterRules.next(); + this.combiningRules.add(new CombiningElement<Rule>(rule, this.ruleCombinerParameters.getCombinerParameters(rule))); + } + } + return this.combiningRules; + } + + public Policy(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) { + super(policySetParent, statusCodeIn, statusMessageIn); + } + + public Policy(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public Policy(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public Policy(PolicySet policySetParent) { + super(policySetParent); + } + + public Policy() { + super(); + ruleCombinerParameters.getTargetedCombinerParameters(); + } + + /** + * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s for + * the {@link Rule}s in this <code>Policy</code>. + * + * @return an <code>Iterator</code> over the <code>TargetedCombinerParameter</code>s for this <code>Policy</code>. + */ + public Iterator<TargetedCombinerParameter<String,Rule>> getRuleCombinerParameters() { + return this.ruleCombinerParameters.getTargetedCombinerParameters(); + } + + /** + * Sets the Rule combiner parameters for this <code>Policy</code> to the contents of the given <code>Collection</code> of + * <code>TargetedCombinerParameter</code>s. + * + * @param ruleCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to set + */ + public void setRuleCombinerParameters(Collection<TargetedCombinerParameter<String,Rule>> ruleCombinerParameters) { + this.ruleCombinerParameters.setCombinerParameters(ruleCombinerParameters); + } + + /** + * Adds the given <code>TargetedCombinerParameter</code> to the set of Rule combiner parameters for this <code>Policy</code>. + * @param ruleCombinerParameter the <code>TargetedCombinerParameter</code> for <code>Rule</code>s to add. + */ + public void addRuleCombinerParameter(TargetedCombinerParameter<String,Rule> ruleCombinerParameter) { + this.ruleCombinerParameters.addCombinerParameter(ruleCombinerParameter); + } + + /** + * Adds the contents of the given <code>Collection</code> of <code>TargetedCombinerParameter</code>s to the set of Rule combiner parameters + * for this <code>Policy</code>. + * + * @param ruleCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to add + */ + public void addRuleCombinerParameters(Collection<TargetedCombinerParameter<String,Rule>> ruleCombinerParameters) { + this.ruleCombinerParameters.addCombinerParameters(ruleCombinerParameters); + } + + /** + * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition}s in this <code>Policy</code>. + * + * @return an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>Policy</code> + */ + public Iterator<VariableDefinition> getVariableDefinitions() { + return this.variableMap.getVariableDefinitions(); + } + + /** + * Gets the <code>VariableDefinition</code> for the given <code>String</code> variable identifier. + * + * @param variableId the <code>String</code> variable identifier + * @return the <code>VariableDefinition</code> with the given <code>String</code> identifier or null if not found + */ + public VariableDefinition getVariableDefinition(String variableId) { + return this.variableMap.getVariableDefinition(variableId); + } + + /** + * Sets the <code>VariableDefinition</code>s in this <code>Policy</code> to the contents of the given <code>Collection</code>. + * + * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to set + */ + public void setVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) { + this.variableMap.setVariableDefinitions(listVariableDefinitions); + } + + /** + * Adds the given <code>VariableDefinition</code> to the set of <code>VariableDefinition</code>s for this <code>Policy</code>. + * + * @param variableDefinition the <code>VariableDefinition</code> to add + */ + public void addVariableDefinition(VariableDefinition variableDefinition) { + this.variableMap.add(variableDefinition); + } + + /** + * Adds the contents of the given <code>Collection</code> of <code>VariableDefinition</code>s to this <code>Policy</code>. + * + * @param variableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to add. + */ + public void addVariableDefinitions(Collection<VariableDefinition> variableDefinitions) { + this.variableMap.addVariableDefinitions(variableDefinitions); + } + + /** + * Gets an <code>Iterator</code> over the <code>Rule</code>s in this <code>Policy</code> or null if there are none. + * + * @return an <code>Iterator</code> over the <code>Rule</code>s in this <code>Policy</code> or null if there are none. + */ + public Iterator<Rule> getRules() { + return this.rules.iterator(); + } + + /** + * Sets the <code>Rule</code>s for this <code>Policy</code> to the contents of the given <code>Collection</code> of + * <code>Rule</code>s. If the <code>Collection</code> is null, the set of <code>Rule</code>s for this <code>Policy</code> is set to null. + * + * @param listRules the <code>Collection</code> of <code>Rule</code>s or null + */ + public void setRules(Collection<Rule> listRules) { + this.rules.clear(); + if (listRules != null) { + this.addRules(listRules); + } + } + + /** + * Adds the given <code>Rule</code> to the set of <code>Rule</code>s for this <code>Policy</code>. + * + * @param rule the <code>Rule</code> to add + */ + public void addRule(Rule rule) { + this.rules.add(rule); + } + + /** + * Adds the contents of the given <code>Collection</code> of <code>Rule</code>s to the set of <code>Rule</code>s for + * this <code>Policy</code>. + * + * @param listRules the <code>Collection</code> of <code>Rule</code>s to add + */ + public void addRules(Collection<Rule> listRules) { + this.rules.addAll(listRules); + } + + /** + * Gets the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>. + * + * @return the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>. + */ + public CombiningAlgorithm<Rule> getRuleCombiningAlgorithm() { + return this.ruleCombiningAlgorithm; + } + + /** + * Sets the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>> + * + * @param ruleCombiningAlgorithmIn the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code> + */ + public void setRuleCombiningAlgorithm(CombiningAlgorithm<Rule> ruleCombiningAlgorithmIn) { + this.ruleCombiningAlgorithm = ruleCombiningAlgorithmIn; + } + + @Override + public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException { + /* + * First check to see if we are valid. If not, return an error status immediately + */ + if (!this.validate()) { + return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + /* + * See if we match + */ + MatchResult thisMatchResult = this.match(evaluationContext); + assert(thisMatchResult != null); + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, thisMatchResult)); + } + switch(thisMatchResult.getMatchCode()) { + case INDETERMINATE: + return new EvaluationResult(Decision.INDETERMINATE, thisMatchResult.getStatus()); + case MATCH: + break; + case NOMATCH: + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + + /* + * Get the combining elements + */ + List<CombiningElement<Rule>> ruleCombiningElements = this.getCombiningRules(); + assert(ruleCombiningElements != null); + + /* + * Run the combining algorithm + */ + assert(this.getRuleCombiningAlgorithm() != null); + EvaluationResult evaluationResultCombined = this.getRuleCombiningAlgorithm().combine(evaluationContext, ruleCombiningElements, this.getCombinerParameterList()); + assert(evaluationResultCombined != null); + + if (evaluationResultCombined.getDecision() == Decision.DENY || evaluationResultCombined.getDecision() == Decision.PERMIT) { + this.updateResult(evaluationResultCombined, evaluationContext); + + /* + * Add my id to the policy identifiers + */ + if (evaluationContext.getRequest().getReturnPolicyIdList()) { + evaluationResultCombined.addPolicyIdentifier(this.getIdReference()); + } + } + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResultCombined)); + } + return evaluationResultCombined; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + String iteratorToDump; + if ((iteratorToDump = StringUtils.toString(this.getRuleCombinerParameters())) != null) { + stringBuilder.append(",ruleCombinerParameters="); + stringBuilder.append(iteratorToDump); + } + if ((iteratorToDump = StringUtils.toString(this.getVariableDefinitions())) != null) { + stringBuilder.append(",variableDefinitions="); + stringBuilder.append(iteratorToDump); + } + if ((iteratorToDump = StringUtils.toString(this.getRules())) != null) { + stringBuilder.append(",rules="); + stringBuilder.append(iteratorToDump); + } + + Object objectToDump; + if ((objectToDump = this.getRuleCombiningAlgorithm()) != null) { + stringBuilder.append(",ruleCombiningAlgorithm="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java new file mode 100755 index 0000000..9195249 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java
@@ -0,0 +1,144 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatusCode; + +/** + * PolicyComponent is the base class for all pieces of a XACML Policy or PolicySet that could potentially have errors associated + * with them by the policy loader. + * + * @author car + * @version $Revision: 1.1 $ + */ +abstract class PolicyComponent { + private StatusCode statusCode; + private String statusMessage; + + /** + * Creates a new <code>PolicyComponent</code> with the given {@link com.att.research.xacml.api.StatusCode} and + * <code>String</code> detailed message. If the <code>StatusCode</code> is null, a default OK status code is used. + * + * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicyComponent</code> + * @param statusMessageIn the <code>String</code> detailed status message for the new <code>PolicyComponent</code> + */ + public PolicyComponent(StatusCode statusCodeIn, String statusMessageIn) { + this.statusCode = statusCodeIn; + this.statusMessage = statusMessageIn; + } + + /** + * Creates a new <code>PolicyComponent</code> with the given <code>StatusCode</code> and no status message. + * + * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicyComponent</code> + */ + public PolicyComponent(StatusCode statusCodeIn) { + this(statusCodeIn, null); + } + + /** + * Creates a new <code>PolicyCOmponent</code> with no <code>StatusCode</code> or status message. + */ + public PolicyComponent() { + this(null, null); + } + + /** + * Gets the <code>StatusCode</code> associated with this <code>PolicyComponent</code>. + * + * @return the <code>StatusCode</code> associated with this <code>PolicyComponent</code> + */ + public StatusCode getStatusCode() { + return this.statusCode; + } + + /** + * Gets the <code>String</code> status message associated with this <code>PolicyComponent</code>. + * + * @return the <code>String</code> status message associated with this <code>PolicyComponent</code> or null if none + */ + public String getStatusMessage() { + return this.statusMessage; + } + + /** + * Sets the <code>StatusCode</code> and <code>String</code> status message for this <code>PolicyComponent</code>. + * This method is mainly provided for objects that may have lazy evaluations performed on them, in which case the + * status is not determined until the object is actually used. + * + * @param statusCodeIn the <code>StatusCode</code> for this <code>PolicyComponent</code> + * @param messageIn the <code>String</code> status message for this <code>PolicyComponent</code> + */ + public void setStatus(StatusCode statusCodeIn, String messageIn) { + this.statusCode = statusCodeIn; + this.statusMessage = messageIn; + } + + /** + * Does a check on the <code>StatusCode</code> for this element to determine if it is equivalent to the + * OK status code. + * + * @return true if the <code>StatusCode</code> is equivalent to OK, otherwise false + */ + public boolean isOk() { + return StdStatusCode.STATUS_CODE_OK.equals(this.getStatusCode()); + } + + /** + * Validates that this <code>PolicyComponent</code> has all of the required elements according to the XACML 3.0 + * specification. If the component is not valid, this method should set the <code>StatusCode</code> to reflect a + * syntax error, and should set the status message to reflect the invalid piece(s). + * + * <code>PolicyComponent</code>s that implement this method should only validate their immediate elements and not perform + * a deep validation of descendents. + * + * @return true if the resulting status code is OK, otherwise false + */ + abstract protected boolean validateComponent(); + + /** + * If a <code>StatusCode</code> has not been set, ask this <code>PolicyComponent</code> to validate itself and return + * the value from the validation. Otherwise, check to see if the cached <code>StatusCode</code> indicates this <code>PolicyComponent</code> is valid. + * + * @return true if this <code>PolicyComponent</code> is valid, else false. + */ + public boolean validate() { + if (this.getStatusCode() == null) { + return this.validateComponent(); + } else { + return this.isOk(); + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + Object objectToDump; + boolean needsComma = false; + if ((objectToDump = this.getStatusCode()) != null) { + stringBuilder.append("statusCode="); + stringBuilder.append(objectToDump.toString()); + needsComma = true; + } + if ((objectToDump = this.getStatusMessage()) != null) { + if (needsComma) { + stringBuilder.append(','); + } + stringBuilder.append("statusMessage="); + stringBuilder.append((String)objectToDump); + needsComma = true; + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java new file mode 100755 index 0000000..1c785c5 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java
@@ -0,0 +1,476 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Advice; +import com.att.research.xacml.api.IdReference; +import com.att.research.xacml.api.IdReferenceMatch; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Obligation; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.api.Version; +import com.att.research.xacml.api.VersionMatch; +import com.att.research.xacml.std.StdIdReference; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.eval.MatchResult; + +/** + * PolicyDef extends {@link com.att.research.xacmlatt.pdp.policy.PolicySetChild} with members and methods common + * to XACML 3.0 Policies and PolicySets. + * + * @author car + * @version $Revision: 1.2 $ + */ +public abstract class PolicyDef extends PolicySetChild { + private String description; + private PolicyIssuer policyIssuer; + private Target target; + private List<CombinerParameter> combinerParameters; + private List<ObligationExpression> obligationExpressions; + private List<AdviceExpression> adviceExpressions; + private Version version; + private Integer maxDelegationDepth; + + private IdReference idReference; + + private void ensureCombinerParameters() { + if (this.combinerParameters == null) { + this.combinerParameters = new ArrayList<CombinerParameter>(); + } + } + + private void ensureObligationExpressions() { + if (this.obligationExpressions == null) { + this.obligationExpressions = new ArrayList<ObligationExpression>(); + } + } + + private void ensureAdviceExpressions() { + if (this.adviceExpressions == null) { + this.adviceExpressions = new ArrayList<AdviceExpression>(); + } + } + + protected List<CombinerParameter> getCombinerParameterList() { + return this.combinerParameters; + } + + protected List<ObligationExpression> getObligationExpressionList() { + return this.obligationExpressions; + } + + protected List<AdviceExpression> getAdviceExpressionList() { + return this.adviceExpressions; + } + + protected void updateResult(EvaluationResult evaluationResult, EvaluationContext evaluationContext) throws EvaluationException { + List<ObligationExpression> thisObligationExpressions = this.getObligationExpressionList(); + if (thisObligationExpressions != null && thisObligationExpressions.size() > 0) { + List<Obligation> listObligations = ObligationExpression.evaluate(evaluationContext, this.getPolicyDefaults(), evaluationResult.getDecision(), thisObligationExpressions); + if (listObligations != null && listObligations.size() > 0) { + evaluationResult.addObligations(listObligations); + } + } + + List<AdviceExpression> thisAdviceExpressions = this.getAdviceExpressionList(); + if (thisAdviceExpressions != null && thisAdviceExpressions.size() > 0) { + List<Advice> listAdvices = AdviceExpression.evaluate(evaluationContext, this.getPolicyDefaults(), evaluationResult.getDecision(), thisAdviceExpressions); + if (listAdvices != null && listAdvices.size() > 0) { + evaluationResult.addAdvice(listAdvices); + } + } + } + + @Override + protected boolean validateComponent() { + if (super.validateComponent()) { + if (this.getVersion() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing version string"); + return false; + } else if (this.getTarget() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Target in policy " + this.getIdReference().getId().stringValue()); + return false; + } else { + return true; + } + } else { + return false; + } + } + + public PolicyDef(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) { + super(policySetParent, statusCodeIn, statusMessageIn); + } + + public PolicyDef(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public PolicyDef(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public PolicyDef(PolicySet policySetParent) { + super(policySetParent); + } + + public PolicyDef() { + super(); + } + + @Override + public void setIdentifier(Identifier identifierIn) { + super.setIdentifier(identifierIn); + this.idReference = null; + } + + /** + * Gets the <code>String</code> description of this <code>PolicyDef</code>. + * + * @return the <code>String</code> description of this <code>PolicyDef</code>. + */ + public String getDescription() { + return this.description; + } + + /** + * Sets the <code>String</code> description of this <code>PolicyDef</code>. + * + * @param s the <code>String</code> description of this <code>PolicyDef</code> + */ + public void setDescription(String s) { + this.description = s; + } + + /** + * Gets the {@link com.att.research.xacmlatt.pdp.policy.PolicyIssuer} for this <code>PolicyDef</code>. + * + * @return the <code>PolicyIssuer</code> for this <code>PolicyDef</code> + */ + public PolicyIssuer getPolicyIssuer() { + return this.policyIssuer; + } + + /** + * Sets the <code>PolicyIssuer</code> for this <code>PolicyDef</code>. + * + * @param policyIssuerIn the <code>PolicyIssuer</code> for this <code>PolicyDef</code>. + */ + public void setPolicyIssuer(PolicyIssuer policyIssuerIn) { + this.policyIssuer = policyIssuerIn; + } + + /** + * Gets the <code>Target</code> for this <code>PolicyDef</code>. + * + * @return the <code>Target</code> for this <code>PolicyDef</code> + */ + public Target getTarget() { + return this.target; + } + + /** + * Sets the <code>Target</code> for this <code>PolicyDef</code>. + * + * @param targetIn the <code>Target</code> for this <code>PolicyDef</code> + */ + public void setTarget(Target targetIn) { + this.target = targetIn; + } + + /** + * Gets an <code>Iterator</code> over the <code>CombinerParameter</code>s for this <code>Policy</code>. + * + * @return an <code>Iterator</code> over the <code>CombinerParameter</code>s for this <code>Policy</code> or null if there are none + */ + public Iterator<CombinerParameter> getCombinerParameters() { + return (this.combinerParameters == null ? null : this.combinerParameters.iterator()); + } + + /** + * Sets the <code>CombinerParameter</code>s for this<code>Policy</code> to the contents of the + * given <code>Collection</code>. If the <code>Collection</code> is null, the set of <code>CombinerParameter</code>s + * for this <code>Policy</code> is set to null. + * + * @param combinerParametersIn the <code>Collection</code> of <code>CombinerParameter</code>s for this <code>PolicyDef</code> + */ + public void setCombinerParameters(Collection<CombinerParameter> combinerParametersIn) { + this.combinerParameters = null; + if (combinerParametersIn != null) { + this.addCombinerParameters(combinerParametersIn); + } + } + + /** + * Adds the given <code>CombinerParameter</code> to the set of <code>CombinerParameter</code>s for this + * <code>PolicyDef</code>> + * + * @param combinerParameter the <code>CombinerParameter</code> to add + */ + public void add(CombinerParameter combinerParameter) { + this.ensureCombinerParameters(); + this.combinerParameters.add(combinerParameter); + } + + /** + * Adds the given <code>Collection</code> of <code>CombinerParameter</code>s to this <code>PolicyDef</code>> + * + * @param combinerParametersIn the <code>Collection</code> of <code>CombinerParameter</code>s to add + */ + public void addCombinerParameters(Collection<CombinerParameter> combinerParametersIn) { + this.ensureCombinerParameters(); + this.combinerParameters.addAll(combinerParametersIn); + } + + /** + * Gets an <code>Iterator</code> over the <code>ObligationExpression</code>s for this <code>PolicyDef</code>. + * + * @return an <code>Iterator</code> over the <code>ObligationExpression</code>s for this <code>PolicyDef</code> or null if there are none. + */ + public Iterator<ObligationExpression> getObligationExpressions() { + return (this.obligationExpressions == null ? null : this.obligationExpressions.iterator()); + } + + /** + * Sets the <code>ObligationExpression</code>s for this <code>PolicyDef</code> to the contents of the given <code>Collection</code>. + * If the <code>Collection</code> is null, the <code>ObligationExpression</code>s for this <code>PolicyDef</code> are set to null. + * + * @param obligationExpressionsIn the <code>Collection</code> of <code>ObligationExpression</code>s for this <code>PolicyDef</code>. + */ + public void setObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) { + this.obligationExpressions = null; + if (obligationExpressionsIn != null) { + this.addObligationExpressions(obligationExpressionsIn); + } + } + + /** + * Adds the given <code>ObligationExpression</code> to the set of <code>ObligationExpression</code>s for this <code>PolicyDef</code>. + * + * @param obligationExpression the <code>ObligationExpression</code> to add + */ + public void add(ObligationExpression obligationExpression) { + this.ensureObligationExpressions(); + this.obligationExpressions.add(obligationExpression); + } + + /** + * Adds the contents of the given <code>Collection</code> of <code>ObligationExpression</code>s to the set of <code>ObligationExpression</code>s for + * this <code>PolicyDef</code>. + * + * @param obligationExpressionsIn the <code>Collection</code> of <code>ObligationExpression</code>s to add + */ + public void addObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) { + this.ensureObligationExpressions(); + this.obligationExpressions.addAll(obligationExpressionsIn); + } + + /** + * Gets an <code>Iterator</code> over the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code>. + * + * @return an <code>Iterator</code> over the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code> or null if there are none. + */ + public Iterator<AdviceExpression> getAdviceExpressions() { + return (this.adviceExpressions == null ? null : this.adviceExpressions.iterator()); + } + + /** + * Sets the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code> to the contents of the given <code>Collection</code>. + * + * @param adviceExpressionsIn the <code>Collection</code> of <code>AdviceExpression</code> to add + */ + public void setAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) { + this.adviceExpressions = null; + if (adviceExpressionsIn != null) { + this.addAdviceExpressions(adviceExpressionsIn); + } + } + + /** + * Adds the given <code>AdviceExpression</code> to the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code>. + * + * @param adviceExpression the <code>AdviceExpression</code> to add. + */ + public void add(AdviceExpression adviceExpression) { + this.ensureAdviceExpressions(); + this.adviceExpressions.add(adviceExpression); + } + + /** + * Adds the contents of the given <code>Collection</code> of <code>AdviceExpression</code>s to the set of + * <code>AdviceExpression</code>s for this <code>PolicyDef</code>. + * + * @param adviceExpressionsIn the <code>Collection</code> of <code>AdviceExpression</code>s to add. + */ + public void addAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) { + this.ensureAdviceExpressions(); + this.adviceExpressions.addAll(adviceExpressionsIn); + } + + /** + * Gets the <code>String</code> version for this <code>PolicyDef</code>. + * + * @return the <code>String</code> version for this <code>PolicyDef</code>. + */ + public Version getVersion() { + return this.version; + } + + /** + * Sets the version <code>String</code> for this <code>PolicyDef</code>> + * + * @param versionIn the <code>String</code> version for this <code>PolicyDef</code> + */ + public void setVersion(Version versionIn) { + this.version = versionIn; + this.idReference = null; + } + + /** + * Creates the <code>IdReference</code> for this <code>PolicyDef</code> if needed and returns it. + * + * @return the <code>IdReference</code> for this <code>PolicyDef</code> + */ + public IdReference getIdReference() { + if (this.idReference == null) { + this.idReference = new StdIdReference(this.getIdentifier(), this.getVersion()); + } + return this.idReference; + } + + public boolean matches(IdReferenceMatch idReferenceRequest) { + IdReference thisIdReference = this.getIdReference(); + if (thisIdReference == null || thisIdReference.getId() == null || idReferenceRequest == null || idReferenceRequest.getId() == null) { + return false; + } else if (!thisIdReference.getId().equals(idReferenceRequest.getId())) { + return false; + } + + /* + * Now do version number matching + */ + VersionMatch idReferenceRequestVersion = idReferenceRequest.getVersion(); + if (idReferenceRequestVersion != null) { + /* + * Do exact version matching + */ + Version thisVersion = thisIdReference.getVersion(); + if (thisVersion == null) { + return false; + } else { + return idReferenceRequestVersion.match(thisVersion, 0); + } + } else { + VersionMatch idReferenceRequestEarliestVersion = idReferenceRequest.getEarliestVersion(); + Version thisVersion = thisIdReference.getVersion(); + + if (idReferenceRequestEarliestVersion != null) { + if (thisVersion == null) { + return false; + } else if (!idReferenceRequestEarliestVersion.match(thisVersion, 1)) { + return false; + } + } + + VersionMatch idReferenceRequestLatestVersion = idReferenceRequest.getLatestVersion(); + if (idReferenceRequestLatestVersion != null) { + if (thisVersion == null) { + return false; + } else if (!idReferenceRequestLatestVersion.match(thisVersion, -1)) { + return false; + } + } + + return true; + } + } + + /** + * Gets the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>. + * + * @return the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code> + */ + public Integer getMaxDelegationDepth() { + return this.maxDelegationDepth; + } + + /** + * Sets the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code> + * @param i the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code> + */ + public void setMaxDelegationDepth(Integer i) { + this.maxDelegationDepth = i; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getDescription()) != null) { + stringBuilder.append(",description="); + stringBuilder.append((String)objectToDump); + } + if ((objectToDump = this.getPolicyIssuer()) != null) { + stringBuilder.append(",policyIssuer="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getTarget()) != null) { + stringBuilder.append(",target="); + stringBuilder.append(objectToDump.toString()); + } + String iteratorToString; + if ((iteratorToString = StringUtils.toString(this.getCombinerParameters())) != null) { + stringBuilder.append(",combinerParameters="); + stringBuilder.append(iteratorToString); + } + if ((iteratorToString = StringUtils.toString(this.getObligationExpressions())) != null) { + stringBuilder.append(",obligationExpressions="); + stringBuilder.append(iteratorToString); + } + if ((iteratorToString = StringUtils.toString(this.getAdviceExpressions())) != null) { + stringBuilder.append(",adviceExpressions="); + stringBuilder.append(iteratorToString); + } + if ((objectToDump = this.getVersion()) != null) { + stringBuilder.append(",version="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getMaxDelegationDepth()) != null) { + stringBuilder.append(",maxDelegationDepth="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + + @Override + public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException { + if (!this.validate()) { + return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + return this.getTarget().match(evaluationContext); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java new file mode 100755 index 0000000..a2c0c3c --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java
@@ -0,0 +1,111 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.net.URI; + +import com.att.research.xacml.api.XACML; + +/** + * PolicyDefaults represents the default values associated with a XACML 3.0 Policy or PolicySet that may + * be overridden or inherited by child Policies or PolicySets. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class PolicyDefaults { + private static URI xpathVersionDefault; + + static { + try { + xpathVersionDefault = new URI(XACML.XPATHVERSION_2_0); + } catch (Exception ex) { + + } + } + + private URI xpathVersion; + private PolicyDefaults policyDefaultsParent; + + /** + * Creates a new <code>PolicyDefaults</code> with the given <code>URI</code> for the XPath version and + * the given <code>PolicyDefaults</code> pointing to the parent. + * + * @param xpathVersionIn the <code>URI</code> representing the XPath version for the new <code>PolicyDefaults</code> + * @param policyDefaultsParentIn the <code>PolicyDefaults</code> object that is the parent of the new <code>PolicyDefaults</code> + */ + public PolicyDefaults(URI xpathVersionIn, PolicyDefaults policyDefaultsParentIn) { + this.xpathVersion = xpathVersionIn; + this.policyDefaultsParent = policyDefaultsParentIn; + } + + /** + * Gets the parent <code>PolicyDefaults</code> for this <code>PolicyDefaults</code>. + * + * @return the parent <code>PolicyDefaults</code> for this <code>PolicyDefaults</code> or null if none + */ + public PolicyDefaults getPolicyDefaultsParent() { + return this.policyDefaultsParent; + } + + /** + * Gets the XPath version <code>URI</code> for this <code>PolicyDefaults</code>. If there is no explicit + * version in this <code>PolicyDefaults</code>, walk up the parent <code>PolicyDefaults</code> hierarchy until + * one is found, or return the default value. + * + * @return the <code>URI</code> for the XPath version + */ + public URI getXPathVersion() { + /* + * See if the XPath version was explicitly set here + */ + if (this.xpathVersion != null) { + return this.xpathVersion; + } + + /* + * Try the parent hierarchy if there is one + */ + PolicyDefaults policyDefaultsParentThis = this.getPolicyDefaultsParent(); + if (policyDefaultsParentThis != null) { + return policyDefaultsParentThis.getXPathVersion(); + } + + /* + * Use the default + */ + return xpathVersionDefault; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + boolean needsComma = false; + Object objectToDump; + if ((objectToDump = this.xpathVersion) != null) { + stringBuilder.append("xpathVersion="); + stringBuilder.append(objectToDump.toString()); + needsComma = true; + } + if ((objectToDump = this.getPolicyDefaultsParent()) != null) { + if (needsComma) { + stringBuilder.append(','); + } + stringBuilder.append("policyDefaultsParent="); + stringBuilder.append(objectToDump.toString()); + needsComma = true; + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java new file mode 100755 index 0000000..8a3b391 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java
@@ -0,0 +1,50 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.IdReferenceMatch; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; + +/** + * PolicyFinder is the interface for objects that can locate XACML Policies and PolicySets by identifier and contains the root + * Policy or Policy set. The interface is designed to allow for finders that can retrieve a root policy from a repository based on + * matching a {@link com.att.research.xacml.api.Request}. + * + * @author car + * @version $Revision: 1.1 $ + */ +public interface PolicyFinder { + /** + * Gets the root {@link PolicyDef} from the policy store + * configured by the particular implementation of the <code>PolicyFinderFactory</code> class that + * is applicable to the {@link com.att.research.xacml.api.Request} in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}. + * + * @return a <code>PolicyFinderResult</code> with the root <code>PolicyDef</code> + */ + public PolicyFinderResult<PolicyDef> getRootPolicyDef(EvaluationContext evaluationContext); + + /** + * Gets the {@link Policy} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}. + * + * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for + * @return a <code>PolicyFinderResult</code> with the <code>Policy</code> matching the given <code>IdReferenceMatch</code> + */ + public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch); + + /** + * Gets the {@link PolicySet} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}. + * + * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for + * @return a <code>PolicyFinderResult</code> with the <code>PolicySet</code> matching the given <code>IdReferenceMatch</code>. + */ + public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch); + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java new file mode 100755 index 0000000..f700046 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java
@@ -0,0 +1,65 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.Properties; + +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.FactoryFinder; +import com.att.research.xacmlatt.pdp.util.ATTPDPProperties; + +/** + * PolicyFinderFactory provides methods for loading XACML 3.0 policies and policy sets that are used + * by the {@link com.att.research.xacmlatt.pdp.PDPEngine} to evaluate requests. + * + * @author car + * @version $Revision: 1.3 $ + */ +public abstract class PolicyFinderFactory { + private static final String FACTORYID = ATTPDPProperties.PROP_POLICYFINDERFACTORY; + private static final String DEFAULT_FACTORY_CLASSNAME = "com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory"; + + protected PolicyFinderFactory() { + } + + protected PolicyFinderFactory(Properties properties) { + } + + public static PolicyFinderFactory newInstance() throws FactoryException { + return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, PolicyFinderFactory.class); + } + + public static PolicyFinderFactory newInstance(Properties properties) throws FactoryException { + return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, PolicyFinderFactory.class, properties); + } + + public static PolicyFinderFactory newInstance(String className, ClassLoader classLoader) throws FactoryException { + return FactoryFinder.newInstance(className, PolicyFinderFactory.class, classLoader, false); + } + + public static PolicyFinderFactory newInstance(String className) throws FactoryException { + return FactoryFinder.newInstance(className, PolicyFinderFactory.class, null, true); + } + + /** + * Gets the configured {@link PolicyFinder}. + * + * @return the configured <code>PolicyFinder</code> + */ + abstract public PolicyFinder getPolicyFinder() throws FactoryException; + + /** + * Gets the configured {@link PolicyFinder}. + * + * @return the configured <code>PolicyFinder</code> + */ + abstract public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException; +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java new file mode 100755 index 0000000..fe1d8ab --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java
@@ -0,0 +1,36 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.Status; + +/** + * PolicyFinderResult is the interface for return values of the methods in the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory} interface. + * + * @author car + * @version $Revision: 1.1 $ + * @param <T> the class extending {@link PolicyDef} contained as a result in this <code>PolicyFinderResult</code> + */ +public interface PolicyFinderResult<T extends PolicyDef> { + /** + * Gets the {@link com.att.research.xacml.api.Status} of the method call. + * + * @return the <code>Status</code> of the method call + */ + public Status getStatus(); + + /** + * Gets the {@link PolicyDef} returned by the method if the status is OK. + * + * @return the <code>T</code> returned by the method if the status is OK. + */ + public T getPolicyDef(); +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java new file mode 100755 index 0000000..ea75497 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java
@@ -0,0 +1,57 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; + +/** + * PolicyIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReferenceBase} for + * {@link Policy} objects with an implementation of the <code>ensureReferencee</code> + * method to find a <code>Policy</code>. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class PolicyIdReference extends PolicyIdReferenceBase<Policy> { + + public PolicyIdReference(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) { + super(policySetParent, statusCodeIn, statusMessageIn); + } + + public PolicyIdReference(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public PolicyIdReference(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public PolicyIdReference(PolicySet policySetParent) { + super(policySetParent); + } + + public PolicyIdReference() { + } + + @Override + protected Policy ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException { + if (this.getReferencee() == null) { + PolicyFinderResult<Policy> policyFactoryResult = evaluationContext.getPolicy(this.getIdReferenceMatch()); + if (policyFactoryResult.getStatus() == null || policyFactoryResult.getStatus().isOk()) { + this.setReferencee(policyFactoryResult.getPolicyDef()); + } + } + return this.getReferencee(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java new file mode 100755 index 0000000..10961fc --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java
@@ -0,0 +1,122 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.IdReferenceMatch; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.eval.MatchResult; + +/** + * PolicyIdReferenceBase extends {@link PolicySetChild} to implement a XACML PolicyIdReference element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public abstract class PolicyIdReferenceBase<T extends PolicyDef> extends PolicySetChild { + private IdReferenceMatch idReferenceMatch; + private T referencee; + + @Override + protected boolean validateComponent() { + if (super.validateComponent()) { + if (this.getIdReferenceMatch() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing reference id"); + return false; + } else { + return true; + } + } else { + return false; + } + } + + /** + * If the <code>T</code> referencee has not been set, this method will try and find it + * in the given <code>EvaluationContext</code> and return it. + * + * @param evaluationContext the <code>EvaluationContext</code> to search for the referencee + * @return the <code>T</code> referencee if found, else null + * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error attempting to locate the referenced <code>T</code>. + */ + protected abstract T ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException; + + public PolicyIdReferenceBase(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) { + super(policySetParent, statusCodeIn, statusMessageIn); + } + + public PolicyIdReferenceBase(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public PolicyIdReferenceBase(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public PolicyIdReferenceBase(PolicySet policySetParent) { + super(policySetParent); + } + + public PolicyIdReferenceBase() { + } + + /** + * Gets the {@link com.att.research.xacml.api.IdReferenceMatch} for this <code>PolicyIdReferenceBase</code>. + * + * @return the <code>IdReferenceMatch</code> for this <code>PolicyIdReference</code>. + */ + public IdReferenceMatch getIdReferenceMatch() { + return this.idReferenceMatch; + } + + public void setIdReferenceMatch(IdReferenceMatch idReferenceMatchIn) { + this.idReferenceMatch = idReferenceMatchIn; + } + + /** + * Sets the <code>PolicyDef</code> object referred to by this <code>PolicyIdReferenceBase</code>. + * + * @return the <code>PolicyDef</code> object referred to by this <code>PolicyIdReferenceBase</code> + */ + public T getReferencee() { + return this.referencee; + } + + public void setReferencee(T referenceeIn) { + this.referencee = referenceeIn; + } + + @Override + public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException { + T thisReferencee = this.ensureReferencee(evaluationContext); + if (thisReferencee == null) { + return new EvaluationResult(Decision.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Could not find referencee for " + this.getIdReferenceMatch().toString())); + } else { + return thisReferencee.evaluate(evaluationContext); + } + } + + @Override + public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException { + T thisReferencee = this.ensureReferencee(evaluationContext); + if (thisReferencee == null) { + return new MatchResult(MatchResult.MatchCode.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Could not find referencee for " + this.getIdReferenceMatch().toString())); + } else { + return thisReferencee.match(evaluationContext); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java new file mode 100755 index 0000000..792d864 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java
@@ -0,0 +1,111 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.w3c.dom.Node; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatusCode; + +/** + * PolicyIssuer extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent the XACML 3.0 + * PolicyIssuer element in Policies and PolicySets. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class PolicyIssuer extends PolicyComponent { + private Node content; + private List<Attribute> attributes; + + public PolicyIssuer(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public PolicyIssuer(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public PolicyIssuer() { + } + + public Node getContent() { + return this.content; + } + + public void setContent(Node nodeContent) { + this.content = nodeContent; + } + + public Iterator<Attribute> getAttributes() { + return (this.attributes == null ? null : this.attributes.iterator()); + } + + public void setAttributes(Collection<Attribute> listAttributes) { + this.attributes = null; + if (listAttributes != null) { + this.add(listAttributes); + } + } + + public void add(Attribute attribute) { + if (this.attributes == null) { + this.attributes = new ArrayList<Attribute>(); + } + this.attributes.add(attribute); + } + + public void add(Collection<Attribute> listAttributes) { + if (this.attributes == null) { + this.attributes = new ArrayList<Attribute>(); + } + this.attributes.addAll(listAttributes); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getContent()) != null) { + stringBuilder.append(",content="); + stringBuilder.append(objectToDump.toString()); + } + Iterator<Attribute> iterAttributes = this.getAttributes(); + if (iterAttributes != null && iterAttributes.hasNext()) { + stringBuilder.append(",attributes=["); + stringBuilder.append(iterAttributes.next().toString()); + while (iterAttributes.hasNext()) { + stringBuilder.append(','); + stringBuilder.append(iterAttributes.next().toString()); + } + stringBuilder.append(']'); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + + @Override + protected boolean validateComponent() { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java new file mode 100755 index 0000000..a4333be --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java
@@ -0,0 +1,259 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.api.trace.Traceable; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.trace.StdTraceEvent; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.eval.MatchResult; + +/** + * PolicySet extends {@link PolicyDef} to represent a XACML PolicySet element. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class PolicySet extends PolicyDef { + private TargetedCombinerParameterMap<Identifier,PolicySetChild> policyCombinerParameters = new TargetedCombinerParameterMap<Identifier,PolicySetChild>(); + private List<PolicySetChild> children; + private List<CombiningElement<PolicySetChild>> combiningPolicies; + private CombiningAlgorithm<PolicySetChild> combiningAlgorithm; + + private void ensureChildren() { + if (this.children == null) { + this.children = new ArrayList<PolicySetChild>(); + } + } + + /** + * Performs lazy evaluation of the combining parameters from this <code>Policy</code>. + * + * @return the <code>List</code> of <code>CombiningElement</code>s for all of the <code>Rule</code>s + */ + protected List<CombiningElement<PolicySetChild>> getCombiningPolicies() { + if (this.combiningPolicies == null) { + this.combiningPolicies = new ArrayList<CombiningElement<PolicySetChild>>(); + Iterator<PolicySetChild> iterPolicies = this.getChildren(); + if (iterPolicies != null) { + while (iterPolicies.hasNext()) { + PolicySetChild policySetChild = iterPolicies.next(); + this.combiningPolicies.add(new CombiningElement<PolicySetChild>(policySetChild, this.policyCombinerParameters.getCombinerParameters(policySetChild))); + } + } + } + return this.combiningPolicies; + } + + @Override + protected boolean validateComponent() { + if (super.validateComponent()) { + if (this.getPolicyCombiningAlgorithm() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing policy combining algorithm"); + return false; + } else { + return true; + } + } else { + return false; + } + } + + public PolicySet(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public PolicySet(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public PolicySet(PolicySet policySetParent) { + super(policySetParent); + } + + public PolicySet() { + } + + /** + * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s + * for {@link Policy} elements in this + * <code>PolicySet</code>. + * + * @return an <code>Iterator</code> over the <code>TargetedCombinerParameter</code>s for <code>Policy</code> elements in this + * <code>PolicySet</code>. + */ + public Iterator<TargetedCombinerParameter<Identifier,PolicySetChild>> getPolicyCombinerParameters() { + return this.policyCombinerParameters.getTargetedCombinerParameters(); + } + + /** + * Sets the Policy combiner parameters for this <code>PolicySet</code> from the contents of the given <code>Collection</code> + * of <code>TargetedCombinerParameter</code>s. + * + * @param policyCombinerParametersIn the <code>Collection</code> of <code>TargetedCombinerParameter</code>s. + */ + public void setPolicyCombinerParameters(Collection<TargetedCombinerParameter<Identifier,PolicySetChild>> policyCombinerParametersIn) { + this.policyCombinerParameters.setCombinerParameters(policyCombinerParametersIn); + } + + public void addPolicyCombinerParameter(TargetedCombinerParameter<Identifier,PolicySetChild> policyCombinerParameter) { + this.policyCombinerParameters.addCombinerParameter(policyCombinerParameter); + } + + public void addPolicyCombinerParameters(Collection<TargetedCombinerParameter<Identifier,PolicySetChild>> policyCombinerParametersIn) { + this.policyCombinerParameters.addCombinerParameters(policyCombinerParametersIn); + } + + /** + * Gets an <code>Iterator</code> over the <code>PolicySetChild</code> children of this <code>PolicySet</code>. + * + * @return an <code>Iterator</code> over the <code>PolicySetChild</code> children of this <code>PolicySet</code> or null if there are none. + */ + public Iterator<PolicySetChild> getChildren() { + return (this.children == null ? null : this.children.iterator()); + } + + public void setChildren(Collection<PolicySetChild> policySetChildren) { + this.children = null; + if (policySetChildren != null) { + this.addChildren(policySetChildren); + } + } + + public void addChild(PolicySetChild policySetChild) { + this.ensureChildren(); + this.children.add(policySetChild); + } + + public void addChildren(Collection<PolicySetChild> policySetChildren) { + this.ensureChildren(); + this.children.addAll(policySetChildren); + } + + /** + * Gets the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} for <code>PolicySetChild</code> children for this <code>PolicySet</code>. + * + * @return the <code>CombiningAlgorithm</code> for <code>PolicySetChild</code> children for this <code>PolicySet</code>. + */ + public CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm() { + return this.combiningAlgorithm; + } + + public void setPolicyCombiningAlgorithm(CombiningAlgorithm<PolicySetChild> combiningAlgorithmIn) { + this.combiningAlgorithm = combiningAlgorithmIn; + } + + @Override + public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException { + /* + * First check to see if we are valid. If not, return an error status immediately + */ + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<Object>("PolicySet", this, null)); + } + if (!this.validate()) { + return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + /* + * See if we match + */ + MatchResult thisMatchResult = this.match(evaluationContext); + assert(thisMatchResult != null); + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, thisMatchResult)); + } + switch(thisMatchResult.getMatchCode()) { + case INDETERMINATE: + return new EvaluationResult(Decision.INDETERMINATE, thisMatchResult.getStatus()); + case MATCH: + break; + case NOMATCH: + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + + /* + * Get the combining elements + */ + List<CombiningElement<PolicySetChild>> listCombiningElements = this.getCombiningPolicies(); + assert(listCombiningElements != null); + + /* + * Run the PolicyCombiningAlgorithm + */ + assert(this.getPolicyCombiningAlgorithm() != null); + EvaluationResult evaluationResultCombined = this.getPolicyCombiningAlgorithm().combine(evaluationContext, listCombiningElements, getCombinerParameterList()); + assert(evaluationResultCombined != null); + + if (evaluationResultCombined.getDecision() == Decision.DENY || evaluationResultCombined.getDecision() == Decision.PERMIT) { + this.updateResult(evaluationResultCombined, evaluationContext); + + /* + * Add my id to the policy set identifiers + */ + if (evaluationContext.getRequest().getReturnPolicyIdList()) { + evaluationResultCombined.addPolicySetIdentifier(this.getIdReference()); + } + } + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResultCombined)); + } + return evaluationResultCombined; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + String iteratorToDump; + if ((iteratorToDump = StringUtils.toString(this.getPolicyCombinerParameters())) != null) { + stringBuilder.append(",policyCombinerParameters="); + stringBuilder.append(iteratorToDump); + } + if ((iteratorToDump = StringUtils.toString(this.getChildren())) != null) { + stringBuilder.append(",children="); + stringBuilder.append(iteratorToDump); + } + Object objectToDump; + if ((objectToDump = this.getPolicyCombiningAlgorithm()) != null) { + stringBuilder.append(",policyCombiningAlgorithm="); + stringBuilder.append(objectToDump.toString()); + } + + stringBuilder.append('}'); + return stringBuilder.toString(); + } + + @Override + public String getTraceId() { + return this.getIdentifier().stringValue(); + } + + @Override + public Traceable getCause() { + return null; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java new file mode 100755 index 0000000..eeae452 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java
@@ -0,0 +1,149 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.api.trace.Traceable; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.Evaluatable; +import com.att.research.xacmlatt.pdp.eval.Matchable; + +/** + * PolicySetChild extends {@link com.att.research.xacmlatt.pdp.PolicyComponent} to represent XACML 3.0 Policies, PolicySets, PolicyReferences, + * and PolicySetReferences. + * + * @author car + * @version $Revision: 1.1 $ + */ +public abstract class PolicySetChild extends PolicyComponent implements Evaluatable, Matchable, Traceable { + private Identifier identifier; + private PolicyDefaults policyDefaults; + private PolicySet parent; + + /** + * Creates a new <code>PolicySetChild</code> with the given given {@link com.att.research.xacml.api.StatusCode} + * and <code>String</code> status message. + * + * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicySetChild</code> + * @param statusMessageIn the <code>String</code> status message for the new <code>PolicySetChild</code> + */ + protected PolicySetChild(PolicySet parentIn, StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + this.parent = parentIn; + } + + protected PolicySetChild(StatusCode statusCodeIn, String statusMessageIn) { + this(null, statusCodeIn, statusMessageIn); + } + + /** + * Creates a new <code>PolicySetChild</code> with the default OK <code>StatusCode</code>. + * + * @param statusCodeIn the <code>StatusCode</code> for this <code>PolicySetChild</code> + */ + protected PolicySetChild(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + protected PolicySetChild(PolicySet parentIn) { + this.parent = parentIn; + } + + /** + * Creates a new <code>PolicySetChild</code> with the default OK status. + */ + protected PolicySetChild() { + super(); + } + + /** + * Gets the <code>Identifier</code> for this <code>PolicySetChild</code>. + * + * @return the <code>Identifier</code> for this <code>PolicySetChild</code> + */ + public Identifier getIdentifier() { + return this.identifier; + } + + public void setIdentifier(Identifier identifierIn) { + this.identifier = identifierIn; + } + + /** + * Gets the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>. + * + * @return the <code>PolicyDefaults</code> for this <code>PolicySetChild</code> + */ + public PolicyDefaults getPolicyDefaults() { + return this.policyDefaults; + } + + /** + * Sets the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>. + * + * @param policyDefaultsIn the <code>PolicyDefaults</code> for this <code>PolicySetChild</code> + */ + public void setPolicyDefaults(PolicyDefaults policyDefaultsIn) { + this.policyDefaults = policyDefaultsIn; + } + + /** + * Gets the parent {@link PolicySet} containing this <code>PolicySetChild</code> + * or null if this is the root. + * + * @return the parent <code>PolicySet</code> of this <code>PolicySetChild</code> + */ + public PolicySet getParent() { + return this.parent; + } + + @Override + protected boolean validateComponent() { + if (this.getIdentifier() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing identifier"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override + public String getTraceId() { + return this.getIdentifier().stringValue(); + } + + @Override + public Traceable getCause() { + return this.parent; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getIdentifier()) != null) { + stringBuilder.append(",identifier="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getPolicyDefaults()) != null) { + stringBuilder.append(",policyDefaults="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java new file mode 100755 index 0000000..adb96a9 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java
@@ -0,0 +1,57 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; + +/** + * PolicySetIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReferenceBase} for + * {@link com.att.research.xacmlatt.pdp.PolicySet} objects to implement the <code>ensureReferencee</code> + * method to find <code>PolicySet</code>s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class PolicySetIdReference extends PolicyIdReferenceBase<PolicySet> { + + public PolicySetIdReference(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) { + super(policySetParent, statusCodeIn, statusMessageIn); + } + + public PolicySetIdReference(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public PolicySetIdReference(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public PolicySetIdReference(PolicySet policySetParent) { + super(policySetParent); + } + + public PolicySetIdReference() { + } + + @Override + protected PolicySet ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException { + if (this.getReferencee() == null) { + PolicyFinderResult<PolicySet> policyFactoryResult = evaluationContext.getPolicySet(this.getIdReferenceMatch()); + if (policyFactoryResult.getStatus() == null || policyFactoryResult.getStatus().isOk()) { + this.setReferencee(policyFactoryResult.getPolicyDef()); + } + } + return this.getReferencee(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java new file mode 100755 index 0000000..467255b --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java
@@ -0,0 +1,299 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Advice; +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Obligation; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.api.trace.Traceable; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.trace.StdTraceEvent; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.eval.Evaluatable; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.eval.MatchResult; +import com.att.research.xacmlatt.pdp.eval.Matchable; + +/** + * Rule extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent a XACML Rule within a Policy. It implements + * {@link com.att.research.xacmlatt.pdp.eval.Matchable} and {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} for matching and evaluation + * a request. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class Rule extends PolicyComponent implements Matchable, Evaluatable, Traceable { + private Policy policy; + private String ruleId; + private RuleEffect ruleEffect; + private String description; + private Target target; + private Condition condition; + private List<ObligationExpression> obligationExpressions = new ArrayList<ObligationExpression>(); + private List<AdviceExpression> adviceExpressions = new ArrayList<AdviceExpression>(); + + protected List<ObligationExpression> getObligationExpressionList() { + return this.obligationExpressions; + } + + protected void clearObligationExpressions() { + this.getObligationExpressionList().clear(); + } + + protected List<AdviceExpression> getAdviceExpressionList() { + return this.adviceExpressions; + } + + protected void clearAdviceExpressions() { + this.getAdviceExpressionList().clear(); + } + + public Rule(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public Rule(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public Rule() { + } + + public Policy getPolicy() { + return this.policy; + } + + public void setPolicy(Policy policyIn) { + this.policy = policyIn; + } + + public String getRuleId() { + return this.ruleId; + } + + public void setRuleId(String ruleIdIn) { + this.ruleId = ruleIdIn; + } + + public RuleEffect getRuleEffect() { + return this.ruleEffect; + } + + public void setRuleEffect(RuleEffect ruleEffectIn) { + this.ruleEffect = ruleEffectIn; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String descriptionIn) { + this.description = descriptionIn; + } + + public Target getTarget() { + return this.target; + } + + public void setTarget(Target targetIn) { + this.target = targetIn; + } + + public Condition getCondition() { + return this.condition; + } + + public void setCondition(Condition conditionIn) { + this.condition = conditionIn; + } + + public Iterator<ObligationExpression> getObligationExpressions() { + return (this.obligationExpressions == null ? null : this.obligationExpressions.iterator()); + } + + public void setObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) { + this.clearObligationExpressions(); + if (obligationExpressionsIn != null) { + this.addObligationExpressions(obligationExpressionsIn); + } + } + + public void addObligationExpression(ObligationExpression obligationExpression) { + this.getObligationExpressionList().add(obligationExpression); + } + + public void addObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) { + this.getObligationExpressionList().addAll(obligationExpressionsIn); + } + + public Iterator<AdviceExpression> getAdviceExpressions() { + return (this.adviceExpressions == null ? null : this.adviceExpressions.iterator()); + } + + public void setAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) { + this.clearAdviceExpressions(); + if (adviceExpressionsIn != null) { + this.addAdviceExpressions(adviceExpressionsIn); + } + } + + public void addAdviceExpression(AdviceExpression adviceExpression) { + this.getAdviceExpressionList().add(adviceExpression); + } + + public void addAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) { + this.getAdviceExpressionList().addAll(adviceExpressionsIn); + } + + @Override + public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException { + if (!this.validate()) { + return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + /* + * See if our target matches + */ + MatchResult matchResult = this.match(evaluationContext); + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, matchResult)); + } + switch(matchResult.getMatchCode()) { + case INDETERMINATE: + return new EvaluationResult(Decision.INDETERMINATE, matchResult.getStatus()); + case MATCH: + break; + case NOMATCH: + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + + /* + * See if our condition matches + */ + Condition thisCondition = this.getCondition(); + if (thisCondition != null) { + ExpressionResultBoolean expressionResultCondition = thisCondition.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults()); + assert(expressionResultCondition != null); + + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<ExpressionResultBoolean>("Condition", this, expressionResultCondition)); + } + + if (!expressionResultCondition.isOk()) { + return new EvaluationResult(Decision.INDETERMINATE, expressionResultCondition.getStatus()); + } else if (!expressionResultCondition.isTrue()) { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + + /* + * The target and condition match, so we can start creating the EvaluationResult + */ + List<Obligation> listObligations = ObligationExpression.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults(), this.getRuleEffect().getDecision(), this.getObligationExpressionList()); + List<Advice> listAdvices = AdviceExpression.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults(), this.getRuleEffect().getDecision(), this.getAdviceExpressionList()); + + EvaluationResult evaluationResult = new EvaluationResult(this.getRuleEffect().getDecision(), listObligations, listAdvices); + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResult)); + } + return evaluationResult; + } + + @Override + public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException { + if (!this.validate()) { + return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + Target thisTarget = this.getTarget(); + if (thisTarget != null) { + return thisTarget.match(evaluationContext); + } else { + return MatchResult.MM_MATCH; + } + } + + @Override + protected boolean validateComponent() { + if (this.getRuleId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing rule id"); + return false; + } else if (this.getPolicy() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Rule not in a Policy"); + return false; + } else if (this.getRuleEffect() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing effect"); + return false; + } + return true; + } + + @Override + public String toString() { + StringBuffer stringBuffer = new StringBuffer("{"); + stringBuffer.append("super="); + stringBuffer.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getRuleId()) != null) { + stringBuffer.append(",ruleId="); + stringBuffer.append((String)objectToDump); + } + if ((objectToDump = this.getRuleEffect()) != null) { + stringBuffer.append(",ruleEffect="); + stringBuffer.append(objectToDump.toString()); + } + if ((objectToDump = this.getDescription()) != null) { + stringBuffer.append(",description="); + stringBuffer.append((String)objectToDump); + } + if ((objectToDump = this.getTarget()) != null) { + stringBuffer.append(",target="); + stringBuffer.append(objectToDump.toString()); + } + if ((objectToDump = this.getCondition()) != null) { + stringBuffer.append(",condition="); + stringBuffer.append(objectToDump.toString()); + } + + String iterToDump; + if ((iterToDump = StringUtils.toString(this.getObligationExpressions())) != null) { + stringBuffer.append(",obligationExpressions="); + stringBuffer.append(iterToDump); + } + if ((iterToDump = StringUtils.toString(this.getAdviceExpressions())) != null) { + stringBuffer.append(",adviceExpressions="); + stringBuffer.append(iterToDump); + } + stringBuffer.append('}'); + return stringBuffer.toString(); + } + + @Override + public String getTraceId() { + return this.getRuleId(); + } + + @Override + public Traceable getCause() { + return this.policy; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java new file mode 100755 index 0000000..bdf95e3 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java
@@ -0,0 +1,61 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.Decision; + +/** + * RuleEffect is an enumeration of the XACML decision effects that a {@link Rule} may apply + * to. + * + * @author car + * @version $Revision: 1.1 $ + */ +public enum RuleEffect { + DENY("Deny", Decision.DENY), + PERMIT("Permit", Decision.PERMIT) + ; + + private String name; + private Decision decision; + private RuleEffect(String nameIn, Decision decisionIn) { + this.name = nameIn; + this.decision = decisionIn; + } + + public String getName() { + return this.name; + } + + public Decision getDecision() { + return this.decision; + } + + @Override + public String toString() { + return this.getName(); + } + + /** + * Maps a XACML rule effect <code>String</code> name to the matching <code>RuleEffect</code>. + * + * @param effectName the <code>String</code> effect name to match + * @return the matching <code>RuleEffect</code> or null if there is no match + */ + public static RuleEffect getRuleEffect(String effectName) { + for (RuleEffect ruleEffect: RuleEffect.values()) { + if (ruleEffect.getName().equalsIgnoreCase(effectName)) { + return ruleEffect; + } + } + return null; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java new file mode 100755 index 0000000..b4eac6c --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java
@@ -0,0 +1,138 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.MatchResult; +import com.att.research.xacmlatt.pdp.eval.Matchable; + +/** + * Target extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to implement XACML 3.0 Target elements for + * Policies, PolicySets, and Rules. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class Target extends PolicyComponent implements Matchable { + private List<AnyOf> anyOfs; + + protected List<AnyOf> getAnyOfList(boolean bNoNull) { + if (this.anyOfs == null && bNoNull) { + this.anyOfs = new ArrayList<AnyOf>(); + } + return this.anyOfs; + } + + protected void clearAnyOfList() { + if (this.anyOfs != null) { + this.anyOfs.clear(); + } + } + + public Target(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public Target(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public Target() { + } + + public Target(Collection<AnyOf> anyOfsIn) { + if (anyOfsIn != null) { + this.addAnyOfs(anyOfsIn); + } + } + + public Target(AnyOf anyOfIn) { + if (anyOfIn != null) { + this.addAnyOf(anyOfIn); + } + } + + /** + * Gets an <code>Iterator</code> over all of the {@link AnyOf}s in this <code>Target</code>. + * + * @return an <code>Iterator</code> over all of the <code>AnyOf</code>s in this <code>Target</code> or null if there are none + */ + public Iterator<AnyOf> getAnyOfs() { + return (this.anyOfs == null ? null : this.anyOfs.iterator()); + } + + public void setAnyOfs(Collection<AnyOf> anyOfsIn) { + this.clearAnyOfList(); + if (anyOfsIn != null) { + this.addAnyOfs(anyOfsIn); + } + } + + public void addAnyOf(AnyOf anyOfIn) { + List<AnyOf> listAnyOfs = this.getAnyOfList(true); + listAnyOfs.add(anyOfIn); + } + + public void addAnyOfs(Collection<AnyOf> anyOfsIn) { + List<AnyOf> listAnyOfs = this.getAnyOfList(true); + listAnyOfs.addAll(anyOfsIn); + } + + @Override + public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException { + if (!this.validate()) { + return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + Iterator<AnyOf> iterAnyOfs = this.getAnyOfs(); + if (iterAnyOfs == null || !iterAnyOfs.hasNext()) { + return MatchResult.MM_MATCH; + } else { + MatchResult matchResult = MatchResult.MM_MATCH; + while (iterAnyOfs.hasNext()) { + matchResult = iterAnyOfs.next().match(evaluationContext); + if (matchResult.getMatchCode() != MatchResult.MatchCode.MATCH) { + return matchResult; + } + } + return matchResult; + } + } + + @Override + protected boolean validateComponent() { + return true; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + String iterToDump = StringUtils.toString(this.getAnyOfs()); + if (iterToDump != null) { + stringBuilder.append(",anyOfs="); + stringBuilder.append(iterToDump); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java new file mode 100755 index 0000000..f93b520 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java
@@ -0,0 +1,107 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.StatusCode; + +/** + * TargetedCombinerParameter extends {@link CombinerParameter} to include a lazy + * reference to a particular sub-element within the evaluatable children that should be used when combining evaluation + * results from that sub-element. + * + * @author car + * + * @param <T> the type of the identifier used to reference the targeted object + * @param <U> the type of the targeted object + */ +public class TargetedCombinerParameter<T, U> extends CombinerParameter { + private T targetId; + private U target; + + public TargetedCombinerParameter(T targetIdIn, String nameIn, AttributeValue<?> attributeValueIn, StatusCode statusCodeIn, String statusMessageIn) { + super(nameIn, attributeValueIn, statusCodeIn, statusMessageIn); + this.targetId = targetIdIn; + } + + public TargetedCombinerParameter(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public TargetedCombinerParameter(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public TargetedCombinerParameter(T targetIdIn, String nameIn, AttributeValue<?> attributeValueIn) { + super(nameIn, attributeValueIn); + this.targetId = targetIdIn; + } + + public TargetedCombinerParameter() { + + } + + /** + * Gets the target id of this <code>TargetedCombinerParameter</code>. + * + * @return the <code>T</code> id of this <code>TargetedCombinerParameter</code> + */ + public T getTargetId() { + return this.targetId; + } + + /** + * Sets the target id to the given <code>T</code> value. + * + * @param targetIdIn the <code>T</code> to set as the target id + */ + public void setTargetId(T targetIdIn) { + this.targetId = targetIdIn; + } + + /** + * Gets the target for this <code>TargetedCombinerParameter</code>. + * + * @return the <code>U</code> target for this <code>TargetedCombinerParameter</code> + */ + public U getTarget() { + return this.target; + } + + /** + * Sets the target for this <code>TargetedCombinerParameter</code> to the given <code>U</code>. + * + * @param targetIn the <code>U</code> target for this <code>TargetedCombinerParameter</code> + */ + public void setTarget(U targetIn) { + this.target = targetIn; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getTargetId()) != null) { + stringBuilder.append("targetId="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getTarget()) != null) { + stringBuilder.append("target="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java new file mode 100755 index 0000000..1ffa5c0 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java
@@ -0,0 +1,155 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * TargetedCombinerParameterMap is a utility for maintaining a collection of {@link com.att.research.xacmlatt.policy.TargetedCombinerParameter} + * objects with the mappings to their targets. + * + * @author car + * @version $Revision: 1.1 $ + * + * @param <T> the type of the identifier for the <code>TargetedCombinerParameter</code>s in the map + * @param <U> the type of the object referenced by the identifier + */ +public class TargetedCombinerParameterMap<T, U> { + List<TargetedCombinerParameter<T,U>> targetedCombinerParameters = null; + Map<T,U> mapTargetIdToTarget = new HashMap<T,U>(); + Map<U,List<CombinerParameter>> mapTargetToCombinerParameters = null; + + private void ensureTargetedCombinerParameters() { + if (this.targetedCombinerParameters == null) { + this.targetedCombinerParameters = new ArrayList<TargetedCombinerParameter<T,U>>(); + } + } + + /** + * Gets the target from the given <code>TargetedCombinerParameter</code> if present. If not, find the + * target in the target id to target mapping, update the <code>TargetedCombinerParameter</code> and then + * return the target. + * + * @param targetedCombinerParameter the <code>TargetedCombinerParameter</code> to resolve + * @return the target for the given <code>TargetedCombinerParameter</code> + */ + protected U resolve(TargetedCombinerParameter<T,U> targetedCombinerParameter) { + U result; + if ((result = targetedCombinerParameter.getTarget()) != null) { + return result; + } else if ((result = this.mapTargetIdToTarget.get(targetedCombinerParameter.getTargetId())) != null) { + targetedCombinerParameter.setTarget(result); + return result; + } else { + return null; + } + } + + /** + * Ensures the <code>Map</code> from targets to <code>List</code> of <code>CombinerParameter</code>s has been + * created if needed. + * + * @throws IllegalStateException if there are <code>TargetedCombinerParameter</code>s that cannot be resolved + */ + protected void ensureMap() throws IllegalStateException { + if (this.mapTargetToCombinerParameters == null) { + if (this.targetedCombinerParameters != null && this.targetedCombinerParameters.size() > 0) { + this.mapTargetToCombinerParameters = new HashMap<U,List<CombinerParameter>>(); + for (TargetedCombinerParameter<T,U> targetedCombinerParameter: this.targetedCombinerParameters) { + U target = this.resolve(targetedCombinerParameter); + if (target == null) { + throw new IllegalStateException("Unresolved TargetCombinerParameter \"" + targetedCombinerParameter.toString() + "\""); + } + List<CombinerParameter> listCombinerParameters = this.mapTargetToCombinerParameters.get(target); + if (listCombinerParameters == null) { + listCombinerParameters = new ArrayList<CombinerParameter>(); + this.mapTargetToCombinerParameters.put(target, listCombinerParameters); + } + listCombinerParameters.add(targetedCombinerParameter); + } + } + } + } + + /** + * Creates a new <code>TargetedCombinerParameterMap</code>. + */ + public TargetedCombinerParameterMap() { + } + + /** + * Adds a new target object to the identifier map. + * + * @param targetId the id for the target + * @param target the target + */ + public void addTarget(T targetId, U target) { + this.mapTargetIdToTarget.put(targetId, target); + } + + /** + * Adds a new <code>TargetedCombinerParameter</code> to this <code>TargetedCombinerParameterMap</code>. + * + * @param targetdCombinerParameter the <code>TargetedCombinerParameter</code> to add + */ + public void addCombinerParameter(TargetedCombinerParameter<T,U> targetdCombinerParameter) { + this.ensureTargetedCombinerParameters(); + this.targetedCombinerParameters.add(targetdCombinerParameter); + this.mapTargetToCombinerParameters = null; + } + + /** + * Adds the contents of the given <code>Collection</code> of <code>TargetedCombinerParameter</code>s to this <code>TargetedCombinerParameterMap</code>. + * + * @param listTargetedCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to add + */ + public void addCombinerParameters(Collection<TargetedCombinerParameter<T,U>> listTargetedCombinerParameters) { + this.ensureTargetedCombinerParameters(); + this.targetedCombinerParameters.addAll(listTargetedCombinerParameters); + this.mapTargetToCombinerParameters = null; + } + + /** + * Sets the set of <code>TargetedCombinerParameter</code>s for this <code>TargetedCombinerParameterMap</code> to the contents of the + * given <code>Collection</code>> + * + * @param listTargetedCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to set + */ + public void setCombinerParameters(Collection<TargetedCombinerParameter<T,U>> listTargetedCombinerParameters) { + this.targetedCombinerParameters = null; + if (listTargetedCombinerParameters != null) { + this.addCombinerParameters(targetedCombinerParameters); + } + } + + /** + * Looks up the given target in the map for any {@link CombinerParameter}s for the + * given target. + * + * @param target the target + * @return a <code>List</code> of <code>CombinerParameter</code>s for the target or null if none + * @throws IllegalStateException if there are <code>TargetedCombinerParameter</code>s that cannot be resolved + */ + public List<CombinerParameter> getCombinerParameters(U target) throws IllegalStateException { + this.ensureMap(); + return (this.mapTargetToCombinerParameters == null ? null : this.mapTargetToCombinerParameters.get(target)); + } + + public Iterator<TargetedCombinerParameter<T,U>> getTargetedCombinerParameters() { + return (this.targetedCombinerParameters == null ? null : this.targetedCombinerParameters.iterator()); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java new file mode 100755 index 0000000..017dd12 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java
@@ -0,0 +1,106 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatusCode; + +/** + * VariableDefinition extends {@link PolicyComponent} to represent a XACML VariableDefinition element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class VariableDefinition extends PolicyComponent { + private String id; + private Expression expression; + + public VariableDefinition(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public VariableDefinition(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public VariableDefinition() { + super(); + } + + /** + * Gets the id of the variable for this <code>VariableDefinition</code>. + * + * @return the <code>String</code> id for the variable for this <code>VariableDefinition</code>. + */ + public String getId() { + return this.id; + } + + /** + * Sets the id of the variable for this <code>VariableDefinition</code>. + * + * @param idIn the <code>String</code> id for the variable for this <code>VariableDefinition</code>. + */ + public void setId(String idIn) { + this.id = idIn; + } + + /** + * Gets the {@link Expression} for this <code>VariableDefinition</code>. + * + * @return the <code>Expression</code> for this <code>VariableDefinition</code>. + */ + public Expression getExpression() { + return this.expression; + } + + /** + * Sets the <code>Expression</code> for this <code>VariableDefinition</code>. + * + * @param expressionIn the <code>Expression</code> for this <code>VariableDefinition</code> + */ + public void setExpression(Expression expressionIn) { + this.expression = expressionIn; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getId()) != null) { + stringBuilder.append(",id="); + stringBuilder.append((String)objectToDump); + } + if ((objectToDump = this.getExpression()) != null) { + stringBuilder.append(",expression="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + + @Override + protected boolean validateComponent() { + if (this.getId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing variable id"); + return false; + } else if (this.getExpression() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing variable expression"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java new file mode 100755 index 0000000..4d55a9d --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java
@@ -0,0 +1,116 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.att.research.xacml.util.StringUtils; + +/** + * VariableMap is a collection of {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition}s that are accessible by + * the variable identifier. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class VariableMap { + private List<VariableDefinition> variableDefinitions; + private Map<String, VariableDefinition> mapVariableDefinitions; + + private void ensureVariableDefinitions() { + if (this.variableDefinitions == null) { + this.variableDefinitions = new ArrayList<VariableDefinition>(); + } + } + + private void ensureMap() { + if (this.mapVariableDefinitions == null) { + this.mapVariableDefinitions = new HashMap<String, VariableDefinition>(); + } + } + + public VariableMap() { + } + + /** + * Gets the <code>VariableDefinition</code> with the given <code>String</code> id. + * + * @param variableId the <code>String</code> identifier of the <code>VariableDefinition</code> to retrieve + * @return the <code>VariableDefinition</code> with the given <code>String</code> id or null if not found. + */ + public VariableDefinition getVariableDefinition(String variableId) { + return (this.mapVariableDefinitions == null ? null : this.mapVariableDefinitions.get(variableId)); + } + + /** + * Gets an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>VariableMap</code> + * in the order they were added. + * + * @return an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>VariableMap</code> + */ + public Iterator<VariableDefinition> getVariableDefinitions() { + return (this.variableDefinitions == null ? null : this.variableDefinitions.iterator()); + } + + /** + * Adds the given <code>VariableDefinition</code> to this <code>VariableMap</code>. + * + * @param variableDefinition the <code>VariableDefinition</code> to add + */ + public void add(VariableDefinition variableDefinition) { + this.ensureMap(); + this.ensureVariableDefinitions(); + this.variableDefinitions.add(variableDefinition); + this.mapVariableDefinitions.put(variableDefinition.getId(), variableDefinition); + } + + /** + * Adds the contents of the given <code>Collection</code> of <code>VariableDefinition</code>s to the set of + * <code>VariableDefinition</code>s in this <code>VariableMap</code>> + * + * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to add + */ + public void addVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) { + for (VariableDefinition variableDefinition: listVariableDefinitions) { + this.add(variableDefinition); + } + } + + /** + * Sets the <code>VariableDefinition</code>s in this <code>VariableMap</code> to the contents of the given + * <code>Collection</code>. + * + * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code> to set + */ + public void setVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) { + this.variableDefinitions = null; + this.mapVariableDefinitions = null; + if (listVariableDefinitions != null) { + this.addVariableDefinitions(variableDefinitions); + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + if (this.mapVariableDefinitions.size() > 0) { + stringBuilder.append("variableDefinitions="); + stringBuilder.append(StringUtils.toString(this.mapVariableDefinitions.values().iterator())); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java new file mode 100755 index 0000000..eda3962 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java
@@ -0,0 +1,191 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.AdviceExpression; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.RuleEffect; + +/** + * DOMAdviceExpression extends {@link com.att.research.xacmlatt.pdp.policy.AdviceExpression} with methods for creation + * from {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMAdviceExpression extends AdviceExpression { + private static final Log logger = LogFactory.getLog(DOMAdviceExpression.class); + + protected DOMAdviceExpression() { + } + + /** + * Creates a new <code>AdviceExpression</code> by parsing the given <code>Node</code> representing a XACML AdviceExpression element. + * + * @param nodeAdviceExpression the <code>Node</code> representing the XACML AdviceExpression element + * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the AdviceExpression element + * @return a new <code>AdviceExpression</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static AdviceExpression newInstance(Node nodeAdviceExpression, Policy policy) throws DOMStructureException { + Element elementAdviceExpression = DOMUtil.getElement(nodeAdviceExpression); + boolean bLenient = DOMProperties.isLenient(); + + DOMAdviceExpression domAdviceExpression = new DOMAdviceExpression(); + + try { + NodeList children = elementAdviceExpression.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) { + domAdviceExpression.addAttributeAssignmentExpression(DOMAttributeAssignmentExpression.newInstance(child, policy)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeAdviceExpression); + } + } + } + } + + domAdviceExpression.setAdviceId(DOMUtil.getIdentifierAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_ADVICEID, !bLenient)); + + String string = DOMUtil.getStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO, !bLenient); + RuleEffect ruleEffect = RuleEffect.getRuleEffect(string); + if (ruleEffect == null && !bLenient) { + throw new DOMStructureException(nodeAdviceExpression, "Unknown EffectType \"" + string + "\""); + } else { + domAdviceExpression.setAppliesTo(ruleEffect); + } + } catch (DOMStructureException ex) { + domAdviceExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domAdviceExpression; + } + + public static boolean repair(Node nodeAdviceExpression) throws DOMStructureException { + Element elementAdviceExpression = DOMUtil.getElement(nodeAdviceExpression); + boolean result = false; + + NodeList children = elementAdviceExpression.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) { + result = DOMAttributeAssignmentExpression.repair(child) || result; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + nodeAdviceExpression.removeChild(child); + result = true; + } + } + } + } + + result = DOMUtil.repairIdentifierAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_ADVICEID, logger) || result; + result = DOMUtil.repairStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO, RuleEffect.DENY.getName(), logger) || result; + String stringRuleEffect = DOMUtil.getStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO); + RuleEffect ruleEffect = RuleEffect.getRuleEffect(stringRuleEffect); + if (ruleEffect == null) { + logger.warn("Setting invalid RuleEffect " + stringRuleEffect + " to " + RuleEffect.DENY.getName()); + elementAdviceExpression.setAttribute(XACML3.ATTRIBUTE_APPLIESTO, RuleEffect.DENY.getName()); + result = true; + } + return result; + } + + /** + * Creates a <code>List</code> of <code>AdviceExpression</code>s by parsing the given <code>Node</code> representing a + * XACML AdviceExpressions element. + * + * @param nodeAdviceExpressions the <code>Node</code> representing the XACML AdviceExpressions element + * @param policy the <code>Policy</code> encompassing the AdviceExpressions element + * @return a new <code>List</code> of <code>AdviceExpression</code>s parsed from the given <code>Node</code>. + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static List<AdviceExpression> newList(Node nodeAdviceExpressions, Policy policy) throws DOMStructureException { + Element elementAdviceExpressions = DOMUtil.getElement(nodeAdviceExpressions); + boolean bLenient = DOMProperties.isLenient(); + + List<AdviceExpression> listAdviceExpressions = new ArrayList<AdviceExpression>(); + + NodeList children = elementAdviceExpressions.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ADVICEEXPRESSION.equals(child.getLocalName())) { + listAdviceExpressions.add(DOMAdviceExpression.newInstance(child, policy)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeAdviceExpressions); + } + } + } + } + + if (listAdviceExpressions.size() == 0 && !bLenient) { + throw DOMUtil.newMissingElementException(nodeAdviceExpressions, XACML3.XMLNS, XACML3.ELEMENT_ADVICEEXPRESSION); + } + return listAdviceExpressions; + } + + public static boolean repairList(Node nodeAdviceExpressions) throws DOMStructureException { + Element elementAdviceExpressions = DOMUtil.getElement(nodeAdviceExpressions); + boolean result = false; + + boolean sawAdviceExpression = false; + NodeList children = elementAdviceExpressions.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ADVICEEXPRESSION.equals(child.getLocalName())) { + sawAdviceExpression = true; + result = result || DOMAdviceExpression.repair(child); + } else { + logger.warn("Unexpected element " + child.getNodeName()); + nodeAdviceExpressions.removeChild(child); + result = true; + } + } + } + } + + if (!sawAdviceExpression) { + throw DOMUtil.newMissingElementException(nodeAdviceExpressions, XACML3.XMLNS, XACML3.ELEMENT_ADVICEEXPRESSION); + } + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java new file mode 100755 index 0000000..c169bc7 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java
@@ -0,0 +1,109 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.AllOf; + +/** + * DOMAllOf extends {@link com.att.research.xacmlatt.pdp.policy.AllOf} with methods for creation from + * DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMAllOf extends AllOf { + private static final Log logger = LogFactory.getLog(DOMAllOf.class); + + protected DOMAllOf() { + } + + /** + * Creates a new <code>DOMAllOf</code> by parsing the given <code>Node</code> representing a XACML AllOf element. + * + * @param nodeAllOf the <code>Node</code> representing the XACML AllOf element + * @return a new <code>DOMAllOf</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the given <code>Node</code> + */ + public static AllOf newInstance(Node nodeAllOf) throws DOMStructureException { + Element elementAllOf = DOMUtil.getElement(nodeAllOf); + boolean bLenient = DOMProperties.isLenient(); + + DOMAllOf domAllOf = new DOMAllOf(); + + try { + NodeList children = elementAllOf.getChildNodes(); + int numChildren; + boolean sawMatch = false; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_MATCH.equals(child.getLocalName())) { + domAllOf.addMatch(DOMMatch.newInstance(child)); + sawMatch = true; + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeAllOf); + } + } + } + } + if (!sawMatch && !bLenient) { + throw DOMUtil.newMissingElementException(nodeAllOf, XACML3.XMLNS, XACML3.ELEMENT_MATCH); + } + } catch (DOMStructureException ex) { + domAllOf.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + return domAllOf; + } + + public static boolean repair(Node nodeAllOf) throws DOMStructureException { + Element elementAllOf = DOMUtil.getElement(nodeAllOf); + boolean result = false; + + NodeList children = elementAllOf.getChildNodes(); + int numChildren; + boolean sawMatch = false; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_MATCH.equals(child.getLocalName())) { + result = DOMMatch.repair(child) || result; + sawMatch = true; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementAllOf.removeChild(child); + result = true; + } + } + } + } + if (!sawMatch) { + throw DOMUtil.newMissingElementException(nodeAllOf, XACML3.XMLNS, XACML3.ELEMENT_MATCH); + } + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java new file mode 100755 index 0000000..882ce67 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java
@@ -0,0 +1,100 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.AnyOf; + +/** + * DOMAnyOf extends {@link com.att.research.xacmlatt.pdp.policy.AnyOf} with methods for creation + * from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMAnyOf extends AnyOf { + private static final Log logger = LogFactory.getLog(DOMAnyOf.class); + + protected DOMAnyOf() { + } + + /** + * Creates a new <code>DOMAnyOf</code> by parsing the given <code>Node</code> representing a XACML AnyOf element. + * + * @param nodeAnyOf the <code>Node</code> representing the XACML AnyOf element + * @return a new <code>DOMAnyOf</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the given <code>Node</code>. + */ + public static AnyOf newInstance(Node nodeAnyOf) throws DOMStructureException { + Element elementAnyOf = DOMUtil.getElement(nodeAnyOf); + boolean bLenient = DOMProperties.isLenient(); + + DOMAnyOf domAnyOf = new DOMAnyOf(); + + try { + NodeList children = elementAnyOf.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && (XACML3.ELEMENT_ALLOF.equals(child.getLocalName()))) { + domAnyOf.addAllOf(DOMAllOf.newInstance(child)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeAnyOf); + } + } + } + } + } catch (DOMStructureException ex) { + domAnyOf.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domAnyOf; + } + + public static boolean repair(Node nodeAnyOf) throws DOMStructureException { + Element elementAnyOf = DOMUtil.getElement(nodeAnyOf); + boolean result = false; + + NodeList children = elementAnyOf.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && (XACML3.ELEMENT_ALLOF.equals(child.getLocalName()))) { + result = DOMAllOf.repair(child) || result; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementAnyOf.removeChild(child); + result = true; + } + } + } + } + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java new file mode 100755 index 0000000..1ca3021 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java
@@ -0,0 +1,111 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.expressions.Apply; + +/** + * DOMApply extends {@link com.att.research.xacmlatt.pdp.policy.expressions.Apply} with methods for creation from + * DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMApply extends Apply { + private static final Log logger = LogFactory.getLog(DOMApply.class); + + protected DOMApply() { + } + + /** + * Creates a new <code>Apply</code> by parsing the given <code>Node</core> representing a XACML Apply element. + * + * @param nodeApply the <code>Node</code> representing the XACML Apply element + * @param policy the <code>Policy</code> encompassing the Apply element + * @return a new <code>Apply</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static Apply newInstance(Node nodeApply, Policy policy) throws DOMStructureException { + Element elementApply = DOMUtil.getElement(nodeApply); + boolean bLenient = DOMProperties.isLenient(); + + DOMApply domApply = new DOMApply(); + + try { + NodeList children = nodeApply.getChildNodes(); + if (children != null) { + int numChildren = children.getLength(); + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE && XACML3.XMLNS.equals(child.getNamespaceURI())) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) { + domApply.setDescription(child.getTextContent()); + } else if (DOMExpression.isExpression(child)) { + domApply.addArgument(DOMExpression.newInstance(child, policy)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeApply); + } + } + } + } + + domApply.setFunctionId(DOMUtil.getIdentifierAttribute(elementApply, XACML3.ATTRIBUTE_FUNCTIONID, !bLenient)); + } catch (DOMStructureException ex) { + domApply.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domApply; + } + + public static boolean repair(Node nodeApply) throws DOMStructureException { + Element elementApply = DOMUtil.getElement(nodeApply); + boolean result = false; + + NodeList children = nodeApply.getChildNodes(); + if (children != null) { + int numChildren = children.getLength(); + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE && XACML3.XMLNS.equals(child.getNamespaceURI())) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) { + } else if (DOMExpression.isExpression(child)) { + result = DOMExpression.repair(child) || result; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementApply.removeChild(child); + result = true; + } + } + } + } + + result = DOMUtil.repairIdentifierAttribute(elementApply, XACML3.ATTRIBUTE_FUNCTIONID, XACML3.ID_FUNCTION_STRING_EQUAL, logger) || result; + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java new file mode 100755 index 0000000..4e42751 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java
@@ -0,0 +1,116 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression; +import com.att.research.xacmlatt.pdp.policy.Policy; + +/** + * DOMAttributeAssignmentExpression extends {@link com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression} with + * methods for creation from {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class DOMAttributeAssignmentExpression extends AttributeAssignmentExpression { + private static final Log logger = LogFactory.getLog(DOMAttributeAssignmentExpression.class); + + protected DOMAttributeAssignmentExpression() { + } + + /** + * Creates a new <code>AttributeAssignmentExpression</code> by parsing the given <code>Node</code> representing + * a XACML AttributeAssignmentExpression element. + * + * @param nodeAttributeAssignmentExpression the <code>Node</code> representing the XACML AttributeAssignmentExpression element + * @return a new <code>AttributeAssignmentExpression</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static AttributeAssignmentExpression newInstance(Node nodeAttributeAssignmentExpression, Policy policy) throws DOMStructureException { + Element elementAttributeAssignmentExpression = DOMUtil.getElement(nodeAttributeAssignmentExpression); + boolean bLenient = DOMProperties.isLenient(); + + DOMAttributeAssignmentExpression domAttributeAssignmentExpression = new DOMAttributeAssignmentExpression(); + + try { + Node node = DOMUtil.getFirstChildElement(elementAttributeAssignmentExpression); + if (node == null) { + if (!bLenient) { + throw DOMUtil.newMissingElementException(elementAttributeAssignmentExpression, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION); + } + } else { + domAttributeAssignmentExpression.setExpression(DOMExpression.newInstance(node, policy)); + } + + Identifier identifier; + domAttributeAssignmentExpression.setAttributeId(DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ATTRIBUTEID, !bLenient));; + if ((identifier = DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_CATEGORY)) != null) { + domAttributeAssignmentExpression.setCategory(identifier); + } + + String issuer = DOMUtil.getStringAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ISSUER); + if (issuer != null) { + domAttributeAssignmentExpression.setIssuer(issuer); + } + } catch (DOMStructureException ex) { + domAttributeAssignmentExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domAttributeAssignmentExpression; + } + + public static boolean repair(Node nodeAttributeAssignmentExpression) throws DOMStructureException { + Element elementAttributeAssignmentExpression = DOMUtil.getElement(nodeAttributeAssignmentExpression); + boolean result = false; + + if (DOMUtil.getFirstChildElement(elementAttributeAssignmentExpression) == null) { + /* + * See if we can repair the <AttributeAssignmentExpression DataType="">string</AttributeAssignmentExpression> pattern + */ + Identifier identifier = DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_DATATYPE); + String textContent = elementAttributeAssignmentExpression.getTextContent(); + if (textContent != null) { + textContent = textContent.trim(); + } + if (textContent != null && textContent.length() > 0 && identifier != null) { + Element attributeValue = elementAttributeAssignmentExpression.getOwnerDocument().createElementNS(XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + attributeValue.setAttribute(XACML3.ATTRIBUTE_DATATYPE, identifier.stringValue()); + attributeValue.setTextContent(textContent); + logger.warn("Adding a new AttributeValue using the DataType from the AttributeAssignment"); + elementAttributeAssignmentExpression.removeAttribute(XACML3.ATTRIBUTE_DATATYPE); + while (elementAttributeAssignmentExpression.hasChildNodes()) { + elementAttributeAssignmentExpression.removeChild(elementAttributeAssignmentExpression.getFirstChild()); + } + elementAttributeAssignmentExpression.appendChild(attributeValue); + result = true; + } else { + throw DOMUtil.newMissingElementException(elementAttributeAssignmentExpression, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION); + } + } + result = DOMUtil.repairIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ATTRIBUTEID, logger) || result; + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java new file mode 100755 index 0000000..1d5936f --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java
@@ -0,0 +1,87 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.expressions.AttributeDesignator; + +/** + * DOMAttributeDesignator extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeDesignator} with methods + * for creation from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class DOMAttributeDesignator extends AttributeDesignator { + private static final Log logger = LogFactory.getLog(DOMAttributeDesignator.class); + + protected DOMAttributeDesignator() { + } + + /** + * Creates a new <code>DOMAttributeDesignator</code> by parsing the given <code>Node</code> representing a XACML AttributeDesignator + * element. + * + * @param nodeAttributeDesignator the <code>Node</code> representing the XACML AttributeDesignator element + * @return a new <code>DOMAttributeDesignator</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static AttributeDesignator newInstance(Node nodeAttributeDesignator) throws DOMStructureException { + Element elementAttributeDesignator = DOMUtil.getElement(nodeAttributeDesignator); + boolean bLenient = DOMProperties.isLenient(); + + DOMAttributeDesignator domAttributeDesignator = new DOMAttributeDesignator(); + + try { + domAttributeDesignator.setCategory(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_CATEGORY, !bLenient)); + domAttributeDesignator.setAttributeId(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ATTRIBUTEID, !bLenient)); + domAttributeDesignator.setDataTypeId(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_DATATYPE, !bLenient)); + + String string; + if ((string = DOMUtil.getStringAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ISSUER)) != null) { + domAttributeDesignator.setIssuer(string); + } + Boolean mustBePresent = DOMUtil.getBooleanAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_MUSTBEPRESENT, !bLenient); + if (mustBePresent != null) { + domAttributeDesignator.setMustBePresent(mustBePresent); + } + } catch (DOMStructureException ex) { + domAttributeDesignator.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domAttributeDesignator; + } + + public static boolean repair(Node nodeAttributeDesignator) throws DOMStructureException { + Element elementAttributeDesignator = DOMUtil.getElement(nodeAttributeDesignator); + boolean result = false; + + result = DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_CATEGORY, logger) || result; + result = DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ATTRIBUTEID, logger) || result; + result = DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_DATATYPE, logger) || result; + result = DOMUtil.repairBooleanAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_MUSTBEPRESENT, false, logger) || result; + + return result; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java new file mode 100755 index 0000000..da1359b --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java
@@ -0,0 +1,87 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.expressions.AttributeSelector; + +/** + * DOMAttributeSelector extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeSelector} with methods + * for creation from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class DOMAttributeSelector extends AttributeSelector { + private static Log logger = LogFactory.getLog(DOMAttributeSelector.class); + + protected DOMAttributeSelector() { + } + + /** + * Creates a new <code>DOMAttributeSelector</code> by parsing the given <code>Node</code> representing a XACML AttributeSelector element. + * + * @param nodeAttributeSelector the <code>Node</code> representing the XACML AttributeSelector element + * @return a new <code>DOMAttributeSelector</code> parsed from the given <code>Node</code>. + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static AttributeSelector newInstance(Node nodeAttributeSelector) throws DOMStructureException { + Element elementAttributeSelector = DOMUtil.getElement(nodeAttributeSelector); + boolean bLenient = DOMProperties.isLenient(); + + DOMAttributeSelector domAttributeSelector = new DOMAttributeSelector(); + + try { + domAttributeSelector.setCategory(DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CATEGORY, !bLenient)); + + Identifier identifier; + if ((identifier = DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CONTEXTSELECTORID)) != null) { + domAttributeSelector.setContextSelectorId(identifier); + } + + domAttributeSelector.setPath(DOMUtil.getStringAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_PATH, !bLenient)); + domAttributeSelector.setDataTypeId(DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_DATATYPE, !bLenient)); + Boolean mustBePresent = DOMUtil.getBooleanAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_MUSTBEPRESENT, !bLenient); + if (mustBePresent != null) { + domAttributeSelector.setMustBePresent(mustBePresent); + } + } catch (DOMStructureException ex) { + domAttributeSelector.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domAttributeSelector; + } + + public static boolean repair(Node nodeAttributeSelector) throws DOMStructureException { + Element elementAttributeSelector = DOMUtil.getElement(nodeAttributeSelector); + boolean result = false; + + result = DOMUtil.repairIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CATEGORY, logger) || result; + result = DOMUtil.repairStringAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_PATH, "/", logger) || result; + result = DOMUtil.repairIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_DATATYPE, logger) || result; + result = DOMUtil.repairBooleanAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_MUSTBEPRESENT, false, logger) || result; + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java new file mode 100755 index 0000000..b32a4c7 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java
@@ -0,0 +1,183 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMAttributeValue; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; + +/** + * DOMCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.CombinerParameter} with methods for + * creation from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMCombinerParameter extends CombinerParameter { + private static final Log logger = LogFactory.getLog(DOMCombinerParameter.class); + + protected DOMCombinerParameter() { + + } + + /** + * Creates a new <code>CombinerParameter</code> by parsing the given <code>Node</code> representing a XACML CombinerParameter element. + * + * @param nodeCombinerParameter the <code>Node</code> representing the XACML CombinerParameter element + * @return a new <code>CombinerParameter</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static CombinerParameter newInstance(Node nodeCombinerParameter) throws DOMStructureException { + Element elementCombinerParameter = DOMUtil.getElement(nodeCombinerParameter); + boolean bLenient = DOMProperties.isLenient(); + + DOMCombinerParameter combinerParameter = new DOMCombinerParameter(); + + try { + NodeList children = elementCombinerParameter.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) { + if (combinerParameter.getAttributeValue() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameter); + } else { + combinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null)); + } + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameter); + } + } + } + } + + if (combinerParameter.getAttributeValue() == null && !bLenient) { + throw DOMUtil.newMissingElementException(elementCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + combinerParameter.setName(DOMUtil.getStringAttribute(elementCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient)); + } catch (DOMStructureException ex) { + combinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return combinerParameter; + } + + public static boolean repair(Node nodeCombinerParameter) throws DOMStructureException { + Element elementCombinerParameter = DOMUtil.getElement(nodeCombinerParameter); + boolean result = false; + + NodeList children = elementCombinerParameter.getChildNodes(); + int numChildren; + boolean sawAttributeValue = false; + + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) { + if (sawAttributeValue) { + logger.warn("Unexpected element " + child.getNodeName()); + elementCombinerParameter.removeChild(child); + result = true; + } else { + result = DOMAttributeValue.repair(child) || result; + sawAttributeValue = true; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementCombinerParameter.removeChild(child); + result = true; + } + } + } + } + + if (!sawAttributeValue) { + throw DOMUtil.newMissingElementException(elementCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + + result = DOMUtil.repairStringAttribute(elementCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result; + + return result; + } + + /** + * Creates a <code>List</code> of <code>CombinerParameter</code>s by parsing the given <code>Node</code> representing a + * XACML CombinerParameters element. + * + * @param nodeCombinerParameters the <code>Node</code> representing the XACML CombinerParameters element + * @return a <code>List</code> of <code>CombinerParameter</code>s parsed from the given <code>Node</code>. + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static List<CombinerParameter> newList(Node nodeCombinerParameters) throws DOMStructureException { + Element elementCombinerParameters = DOMUtil.getElement(nodeCombinerParameters); + boolean bLenient = DOMProperties.isLenient(); + + List<CombinerParameter> listCombinerParameters = new ArrayList<CombinerParameter>(); + + NodeList children = elementCombinerParameters.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_COMBINERPARAMETER.equals(child.getLocalName())) { + listCombinerParameters.add(DOMCombinerParameter.newInstance(child)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameters); + } + } + } + } + return listCombinerParameters; + } + + public static boolean repairList(Node nodeCombinerParameters) throws DOMStructureException { + Element elementCombinerParameters = DOMUtil.getElement(nodeCombinerParameters); + boolean result = false; + + NodeList children = elementCombinerParameters.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_COMBINERPARAMETER.equals(child.getLocalName())) { + result = DOMCombinerParameter.repair(child) || result; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementCombinerParameters.removeChild(child); + result = true; + } + } + } + } + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java new file mode 100755 index 0000000..f25e6cd --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java
@@ -0,0 +1,70 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; + +/** + * DOMDocumentRepair extends {@link com.att.research.xacml.std.dom.DOMDocumentRepair} to repair Policy documents as well as + * Request and Response documents. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class DOMDocumentRepair extends com.att.research.xacml.std.dom.DOMDocumentRepair { + protected boolean repairPolicy(Node nodePolicy) throws DOMStructureException { + return DOMPolicy.repair(nodePolicy); + } + + protected boolean repairPolicySet(Node nodePolicySet) throws DOMStructureException { + return DOMPolicySet.repair(nodePolicySet); + } + + public DOMDocumentRepair() { + } + + /** + * Determines what kind of XACML document is represented by the given <code>Document</code> and + * attempts to repair it. + * + * @param document the <code>Document</code> to check + * @return true if any repairs were made in the <code>Document</code>, else false + * @throws DOMStructureException if there were unrecoverable errors found + * @throws UnsupportedDocumentTypeException if the root element is not a XACML Request or Response. + */ + public boolean repair(Document document) throws DOMStructureException, UnsupportedDocumentTypeException { + Node firstChild = DOMUtil.getFirstChildElement(document); + if (firstChild == null || !DOMUtil.isElement(firstChild)) { + return false; + } + + if (!DOMUtil.isInNamespace(firstChild, XACML3.XMLNS)) { + throw new UnsupportedDocumentTypeException("Not a XACML document: " + DOMUtil.getNodeLabel(firstChild)); + } + if (XACML3.ELEMENT_REQUEST.equals(firstChild.getLocalName())) { + return this.repairRequest(firstChild); + } else if (XACML3.ELEMENT_RESPONSE.equals(firstChild.getLocalName())) { + return this.repairResponse(firstChild); + } else if (XACML3.ELEMENT_POLICY.equals(firstChild.getLocalName())) { + return this.repairPolicy(firstChild); + } else if (XACML3.ELEMENT_POLICYSET.equals(firstChild.getLocalName())) { + return this.repairPolicySet(firstChild); + } else { + throw new UnsupportedDocumentTypeException("Not a XACML Request or Response: " + DOMUtil.getNodeLabel(firstChild)); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java new file mode 100755 index 0000000..b9b1ac7 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java
@@ -0,0 +1,120 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMAttributeValue; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.Expression; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.expressions.AttributeValueExpression; +import com.att.research.xacmlatt.pdp.policy.expressions.Function; +import com.att.research.xacmlatt.pdp.policy.expressions.VariableReference; + +/** + * DOMExpression extends {@link com.att.research.xacmlatt.pdp.policy.Expression} with methods for creation + * from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public abstract class DOMExpression extends Expression { + private static final Log logger = LogFactory.getLog(DOMExpression.class); + + protected DOMExpression() { + } + + public static boolean isExpression(Node nodeExpression) { + String nodeName = nodeExpression.getLocalName(); + return (XACML3.ELEMENT_APPLY.equals(nodeName) || + XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(nodeName) || + XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(nodeName) || + XACML3.ELEMENT_ATTRIBUTEVALUE.equals(nodeName) || + XACML3.ELEMENT_FUNCTION.equals(nodeName) || + XACML3.ELEMENT_VARIABLEREFERENCE.equals(nodeName) + ); + } + + /** + * Creates a new <code>Expression</code> of the appropriate sub-type based on the name of the given <code>Node</code>. + * + * @param nodeExpression the <code>Node</code> to parse + * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} containing the Expression element + * @return a new <code>Expression</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static Expression newInstance(Node nodeExpression, Policy policy) throws DOMStructureException { + Element elementExpression = DOMUtil.getElement(nodeExpression); + boolean bLenient = DOMProperties.isLenient(); + + if (DOMUtil.isInNamespace(elementExpression, XACML3.XMLNS)) { + if (elementExpression.getLocalName().equals(XACML3.ELEMENT_APPLY)) { + return DOMApply.newInstance(elementExpression, policy); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEDESIGNATOR)) { + return DOMAttributeDesignator.newInstance(elementExpression); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTESELECTOR)) { + return DOMAttributeSelector.newInstance(elementExpression); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEVALUE)) { + AttributeValue<?> attributeValue = null; + try { + attributeValue = DOMAttributeValue.newInstance(elementExpression, null); + } catch (DOMStructureException ex) { + return new AttributeValueExpression(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } + return new AttributeValueExpression(attributeValue); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_FUNCTION)) { + return new Function(DOMUtil.getIdentifierAttribute(elementExpression, XACML3.ATTRIBUTE_FUNCTIONID)); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_VARIABLEREFERENCE)) { + return new VariableReference(policy, DOMUtil.getStringAttribute(elementExpression, XACML3.ATTRIBUTE_VARIABLEID)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(nodeExpression); + } else { + return null; + } + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(nodeExpression); + } else { + return null; + } + } + + public static boolean repair(Node nodeExpression) throws DOMStructureException { + Element elementExpression = DOMUtil.getElement(nodeExpression); + if (DOMUtil.isInNamespace(elementExpression, XACML3.XMLNS)) { + if (elementExpression.getLocalName().equals(XACML3.ELEMENT_APPLY)) { + return DOMApply.repair(elementExpression); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEDESIGNATOR)) { + return DOMAttributeDesignator.repair(elementExpression); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTESELECTOR)) { + return DOMAttributeSelector.repair(elementExpression); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEVALUE)) { + return DOMAttributeValue.repair(elementExpression); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_FUNCTION)) { + return DOMUtil.repairIdentifierAttribute(elementExpression, XACML3.ATTRIBUTE_FUNCTIONID, XACML3.ID_FUNCTION_STRING_EQUAL, logger); + } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_VARIABLEREFERENCE)) { + return DOMUtil.repairStringAttribute(elementExpression, XACML3.ATTRIBUTE_VARIABLEID, "variableId", logger); + } else { + throw DOMUtil.newUnexpectedElementException(nodeExpression); + } + } else { + throw DOMUtil.newUnexpectedElementException(nodeExpression); + } + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java new file mode 100755 index 0000000..756750a --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java
@@ -0,0 +1,173 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMAttributeValue; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.Match; + +/** + * DOMMatch extends {@link com.att.research.xacmlatt.pdp.policy.Match} with methods for creation from + * DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class DOMMatch extends Match { + private static Log logger = LogFactory.getLog(DOMMatch.class); + + protected DOMMatch() { + } + + /** + * Creates a new <code>DOMMatch</code> by parsing the given <code>Node</code> representing a XACML Match element. + * + * @param nodeMatch the <code>Node</code> representing the XACML Match element + * @return a new <code>DOMMatch</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the given <code>Node</code> + */ + public static Match newInstance(Node nodeMatch) throws DOMStructureException { + Element elementMatch = DOMUtil.getElement(nodeMatch); + boolean bLenient = DOMProperties.isLenient(); + + DOMMatch domMatch = new DOMMatch(); + + try { + NodeList children = elementMatch.getChildNodes(); + int numChildren; + + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_ATTRIBUTEVALUE.equals(childName)) { + domMatch.setAttributeValue(DOMAttributeValue.newInstance(child, null)); + } else if (XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(childName)) { + if (domMatch.getAttributeRetrievalBase() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeMatch); + } + domMatch.setAttributeRetrievalBase(DOMAttributeDesignator.newInstance(child)); + } else if (XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(childName)) { + if (domMatch.getAttributeRetrievalBase() != null) { + throw DOMUtil.newUnexpectedElementException(child, nodeMatch); + } + domMatch.setAttributeRetrievalBase(DOMAttributeSelector.newInstance(child)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeMatch); + } + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeMatch); + } + } + } + } + + /* + * We have to see exactly one of these + */ + if (domMatch.getAttributeRetrievalBase() == null && !bLenient) { + throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEDESIGNATOR + " or " + XACML3.ELEMENT_ATTRIBUTESELECTOR); + } else if (domMatch.getAttributeValue() == null && !bLenient) { + throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + + domMatch.setMatchId(DOMUtil.getIdentifierAttribute(elementMatch, XACML3.ATTRIBUTE_MATCHID, !bLenient)); + + } catch (DOMStructureException ex) { + domMatch.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + return domMatch; + } + + public static boolean repair(Node nodeMatch) throws DOMStructureException { + Element elementMatch = DOMUtil.getElement(nodeMatch); + boolean result = false; + + NodeList children = elementMatch.getChildNodes(); + int numChildren; + boolean sawAttributeRetrievalBase = false; + boolean sawAttributeValue = false; + + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_ATTRIBUTEVALUE.equals(childName)) { + if (sawAttributeValue) { + logger.warn("Unexpected element " + child.getNodeName()); + elementMatch.removeChild(child); + result = true; + } else { + result = DOMAttributeValue.repair(child) || result; + sawAttributeValue = true; + } + } else if (XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(childName)) { + if (sawAttributeRetrievalBase) { + logger.warn("Unexpected element " + child.getNodeName()); + elementMatch.removeChild(child); + result = true; + } else { + result = DOMAttributeDesignator.repair(child) || result; + sawAttributeRetrievalBase = true; + } + } else if (XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(childName)) { + if (sawAttributeRetrievalBase) { + logger.warn("Unexpected element " + child.getNodeName()); + elementMatch.removeChild(child); + result = true; + } else { + result = DOMAttributeSelector.repair(child) || result; + sawAttributeRetrievalBase = true; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementMatch.removeChild(child); + result = true; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementMatch.removeChild(child); + result = true; + } + } + } + } + + /* + * We have to see exactly one of these + */ + if (!sawAttributeRetrievalBase) { + throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEDESIGNATOR + " or " + XACML3.ELEMENT_ATTRIBUTESELECTOR); + } else if (!sawAttributeValue) { + throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + result = DOMUtil.repairIdentifierAttribute(elementMatch, XACML3.ATTRIBUTE_MATCHID, logger) || result; + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java new file mode 100755 index 0000000..7f5832c --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java
@@ -0,0 +1,195 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.ObligationExpression; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.RuleEffect; + +/** + * DOMObligationExpression extends {@link com.att.research.xacmlatt.pdp.policy.ObligationExpression} with methods + * for creation from {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class DOMObligationExpression extends ObligationExpression { + private static final Log logger = LogFactory.getLog(DOMObligationExpression.class); + + protected DOMObligationExpression() { + } + + /** + * Creates a new <code>ObligationExpression</code> by parsing the given <code>Node</code> representing a XACML ObligationExpression element. + * + * @param nodeObligationExpression the <code>Node</code> representing the XACML ObligationExpression element + * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the ObligationExpression element + * @return a new <code>ObligationExpression</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static ObligationExpression newInstance(Node nodeObligationExpression, Policy policy) throws DOMStructureException { + Element elementObligationExpression = DOMUtil.getElement(nodeObligationExpression); + boolean bLenient = DOMProperties.isLenient(); + + DOMObligationExpression domObligationExpression = new DOMObligationExpression(); + + try { + NodeList children = elementObligationExpression.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) { + domObligationExpression.addAttributeAssignmentExpression(DOMAttributeAssignmentExpression.newInstance(child, policy)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeObligationExpression); + } + } + } + } + + domObligationExpression.setObligationId(DOMUtil.getIdentifierAttribute(elementObligationExpression, XACML3.ATTRIBUTE_OBLIGATIONID, !bLenient)); + + String string = DOMUtil.getStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON, !bLenient); + RuleEffect ruleEffectType = RuleEffect.getRuleEffect(string); + if (ruleEffectType == null) { + if (!bLenient) { + throw new DOMStructureException(nodeObligationExpression, "Invalid EffectType \"" + string + "\" in \"" + DOMUtil.getNodeLabel(nodeObligationExpression) + "\""); + } + } else { + domObligationExpression.setRuleEffect(ruleEffectType); + } + } catch (DOMStructureException ex) { + domObligationExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + return domObligationExpression; + } + + public static boolean repair(Node nodeObligationExpression) throws DOMStructureException { + Element elementObligationExpression = DOMUtil.getElement(nodeObligationExpression); + boolean result = false; + + NodeList children = elementObligationExpression.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) { + result = DOMAttributeAssignmentExpression.repair(child) || result; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementObligationExpression.removeChild(child); + result = true; + } + } + } + } + + result = DOMUtil.repairIdentifierAttribute(elementObligationExpression, XACML3.ATTRIBUTE_OBLIGATIONID, logger) || result; + result = DOMUtil.repairStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON, RuleEffect.DENY.getName(), logger) || result; + + String string = DOMUtil.getStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON); + RuleEffect ruleEffectType = RuleEffect.getRuleEffect(string); + if (ruleEffectType == null) { + logger.warn("Setting invalid RuleEffect " + string + " to " + RuleEffect.DENY.getName()); + elementObligationExpression.setAttribute(XACML3.ATTRIBUTE_FULFILLON, RuleEffect.DENY.getName()); + result = true; + } + + return result; + } + + /** + * Creates a <code>List</code> of <code>ObligationExpression</code>s by parsing the given <code>Node</code> + * representing a XACML ObligationExpressions element. + * + * @param nodeObligationExpressions the <code>Node</code> representing the XACML ObligationExpressions element + * @param policy the <code>Policy</code> encompassing the ObligationExpressions element + * @return a new <code>List</code> of <code>ObligationExpression</code>s parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static List<ObligationExpression> newList(Node nodeObligationExpressions, Policy policy) throws DOMStructureException { + Element elementObligationExpressions = DOMUtil.getElement(nodeObligationExpressions); + boolean bLenient = DOMProperties.isLenient(); + + List<ObligationExpression> listObligationExpressions = new ArrayList<ObligationExpression>(); + + NodeList children = elementObligationExpressions.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_OBLIGATIONEXPRESSION.equals(child.getLocalName())) { + listObligationExpressions.add(DOMObligationExpression.newInstance(child, policy)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, elementObligationExpressions); + } + } + } + } + + if (listObligationExpressions.size() == 0 && !bLenient) { + throw DOMUtil.newMissingElementException(elementObligationExpressions, XACML3.XMLNS, XACML3.ELEMENT_OBLIGATIONEXPRESSION); + } + + return listObligationExpressions; + } + + public static boolean repairList(Node nodeObligationExpressions) throws DOMStructureException { + Element elementObligationExpressions = DOMUtil.getElement(nodeObligationExpressions); + boolean result = false; + + boolean sawObligationExpression = false; + NodeList children = elementObligationExpressions.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_OBLIGATIONEXPRESSION.equals(child.getLocalName())) { + result = DOMObligationExpression.repair(child) || result; + sawObligationExpression = true; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementObligationExpressions.removeChild(child); + result = true; + } + } + } + } + if (!sawObligationExpression) { + throw DOMUtil.newMissingElementException(elementObligationExpressions, XACML3.XMLNS, XACML3.ELEMENT_OBLIGATIONEXPRESSION); + } + + return result; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java new file mode 100755 index 0000000..b248325 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java
@@ -0,0 +1,315 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.io.File; +import java.util.Iterator; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; +import com.att.research.xacmlatt.pdp.policy.PolicySet; +import com.att.research.xacmlatt.pdp.policy.Rule; + +/** + * DOMPolicy extends {@link com.att.research.xacmlatt.pdp.policy.Policy} with methods for creation from a + * DOM {@link org.w3c.dom.Node}. + * + * @author car + * @version $Revision: 1.4 $ + */ +public class DOMPolicy { + private static final Log logger = LogFactory.getLog(DOMPolicy.class); + + /** + * Creates a new <code>DOMPolicy</code> to be configured from a DOM <code>Node</code>. + */ + protected DOMPolicy() { + } + + /** + * Creates a new <code>DOMPolicy</code> by parsing the given <code>Node</code> representing a XACML Policy element. + * + * @param nodePolicy the <code>Node</code> representing the Policy element + * @param policyDefaultsParent the <code>PolicyDefaults</code> of the parent element of the Policy element or null if this is the root + * @return a new <code>DOMPolicy</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static Policy newInstance(Node nodePolicy, PolicySet policySetParent, PolicyDefaults policyDefaultsParent) throws DOMStructureException { + Element elementPolicy = DOMUtil.getElement(nodePolicy); + boolean bLenient = DOMProperties.isLenient(); + + Policy domPolicy = new Policy(policySetParent); + + Identifier identifier; + Integer integer; + Iterator<?> iterator; + + try { + NodeList children = elementPolicy.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + /* + * Run through once, quickly, to set the PolicyDefaults for the new DOMPolicySet + */ + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isNamespaceElement(child, XACML3.XMLNS) && XACML3.ELEMENT_POLICYDEFAULTS.equals(child.getLocalName())) { + if (domPolicy.getPolicyDefaults() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicy); + } + domPolicy.setPolicyDefaults(DOMPolicyDefaults.newInstance(child, policyDefaultsParent)); + } + } + if (domPolicy.getPolicyDefaults() == null) { + domPolicy.setPolicyDefaults(policyDefaultsParent); + } + + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) { + if (domPolicy.getDescription() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicy); + } + domPolicy.setDescription(child.getTextContent()); + } else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) { + if (domPolicy.getPolicyIssuer() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicy); + } + domPolicy.setPolicyIssuer(DOMPolicyIssuer.newInstance(child)); + } else if (XACML3.ELEMENT_POLICYDEFAULTS.equals(childName)) { + } else if (XACML3.ELEMENT_TARGET.equals(childName)) { + if (domPolicy.getTarget() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicy); + } + domPolicy.setTarget(DOMTarget.newInstance(child)); + } else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) { + domPolicy.addCombinerParameters(DOMCombinerParameter.newList(child)); + } else if (XACML3.ELEMENT_RULECOMBINERPARAMETERS.equals(childName)) { + domPolicy.addRuleCombinerParameter(DOMRuleCombinerParameters.newInstance(child)); + } else if (XACML3.ELEMENT_VARIABLEDEFINITION.equals(childName)) { + domPolicy.addVariableDefinition(DOMVariableDefinition.newInstance(child, domPolicy)); + } else if (XACML3.ELEMENT_RULE.equals(childName)) { + domPolicy.addRule(DOMRule.newInstance(child, domPolicy)); + } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) { + if ((iterator = domPolicy.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicy); + } + domPolicy.setObligationExpressions(DOMObligationExpression.newList(child, domPolicy)); + } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) { + if ((iterator = domPolicy.getAdviceExpressions())!= null && iterator.hasNext() && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicy); + } + domPolicy.setAdviceExpressions(DOMAdviceExpression.newList(child, domPolicy)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicy); + } + } + } + } + } + domPolicy.setIdentifier(DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_POLICYID, !bLenient)); + domPolicy.setVersion(DOMUtil.getVersionAttribute(elementPolicy, XACML3.ATTRIBUTE_VERSION, !bLenient)); + + identifier = DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID, !bLenient); + CombiningAlgorithm<Rule> combiningAlgorithmRule = null; + try { + combiningAlgorithmRule = CombiningAlgorithmFactory.newInstance().getRuleCombiningAlgorithm(identifier); + } catch (FactoryException ex) { + if (!bLenient) { + throw new DOMStructureException("Failed to get CombiningAlgorithm", ex); + } + } + if (combiningAlgorithmRule == null && !bLenient) { + throw new DOMStructureException(elementPolicy, "Unknown rule combining algorithm \"" + identifier.toString() + "\" in \"" + DOMUtil.getNodeLabel(nodePolicy)); + } else { + domPolicy.setRuleCombiningAlgorithm(combiningAlgorithmRule); + } + + + if ((integer = DOMUtil.getIntegerAttribute(elementPolicy, XACML3.ATTRIBUTE_MAXDELEGATIONDEPTH)) != null) { + domPolicy.setMaxDelegationDepth(integer); + } + } catch (DOMStructureException ex) { + domPolicy.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domPolicy; + } + + public static boolean repair(Node nodePolicy) throws DOMStructureException { + Element elementPolicy = DOMUtil.getElement(nodePolicy); + boolean result = false; + + NodeList children = elementPolicy.getChildNodes(); + int numChildren; + boolean sawDescription = false; + boolean sawIssuer = false; + boolean sawTarget = false; + boolean sawPolicyDefaults = false; + boolean sawObligationExprs = false; + boolean sawAdviceExprs = false; + + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) { + if (sawDescription) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicy.removeChild(child); + result = true; + } else { + sawDescription = true; + } + } else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) { + if (sawIssuer) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicy.removeChild(child); + result = true; + } else { + sawDescription = true; + result = DOMPolicyIssuer.repair(child) || result; + } + } else if (XACML3.ELEMENT_POLICYDEFAULTS.equals(childName)) { + if (sawPolicyDefaults) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicy.removeChild(child); + result = true; + } else { + sawPolicyDefaults = true; + result = DOMPolicyDefaults.repair(child) || result; + } + } else if (XACML3.ELEMENT_TARGET.equals(childName)) { + if (sawTarget) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicy.removeChild(child); + result = true; + } else { + sawTarget = true; + result = DOMTarget.repair(child) || result; + } + } else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) { + result = DOMCombinerParameter.repair(child) || result; + } else if (XACML3.ELEMENT_RULECOMBINERPARAMETERS.equals(childName)) { + result = DOMRuleCombinerParameters.repair(child) || result; + } else if (XACML3.ELEMENT_VARIABLEDEFINITION.equals(childName)) { + result = DOMVariableDefinition.repair(child) || result; + } else if (XACML3.ELEMENT_RULE.equals(childName)) { + result = DOMRule.repair(child) || result; + } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) { + if (sawObligationExprs) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicy.removeChild(child); + result = true; + } else { + sawObligationExprs = true; + result = DOMObligationExpression.repairList(child) || result; + } + } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) { + if (sawAdviceExprs) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicy.removeChild(child); + result = true; + } else { + sawAdviceExprs = true; + result = DOMAdviceExpression.repairList(child) || result; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicy.removeChild(child); + result = true; + } + } + } + } + } + result = DOMUtil.repairIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_POLICYID, logger) || result; + result = DOMUtil.repairVersionAttribute(elementPolicy, XACML3.ATTRIBUTE_VERSION, logger) || result; + result = DOMUtil.repairIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID, XACML3.ID_RULE_DENY_OVERRIDES, logger) || result; + + Identifier identifier = DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID); + CombiningAlgorithm<Rule> combiningAlgorithmRule = null; + try { + combiningAlgorithmRule = CombiningAlgorithmFactory.newInstance().getRuleCombiningAlgorithm(identifier); + } catch (FactoryException ex) { + combiningAlgorithmRule = null; + } + if(combiningAlgorithmRule == null) { + logger.warn("Setting invalid " + XACML3.ATTRIBUTE_RULECOMBININGALGID + " attribute " + identifier.stringValue() + " to " + XACML3.ID_RULE_DENY_OVERRIDES.stringValue()); + elementPolicy.setAttribute(XACML3.ATTRIBUTE_RULECOMBININGALGID, XACML3.ID_RULE_DENY_OVERRIDES.stringValue()); + result = true; + } + return result; + } + + public static void main(String args[]) { + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + + for (String fileName: args) { + File filePolicy = new File(fileName); + if (filePolicy.exists() && filePolicy.canRead()) { + try { + Document documentPolicy = documentBuilder.parse(filePolicy); + if (documentPolicy.getFirstChild() == null) { + System.err.println(fileName + ": Error: No Policy found"); + } else if (!XACML3.ELEMENT_POLICY.equals(documentPolicy.getFirstChild().getLocalName())) { + System.err.println(fileName + ": Error: Not a Policy documnt"); + } else { + Policy policy = DOMPolicy.newInstance(documentPolicy.getFirstChild(), null, null); + System.out.println(fileName + ": validate()=" + policy.validate()); + System.out.println(StringUtils.prettyPrint(policy.toString())); + } + } catch (Exception ex) { + System.err.println("Exception processing policy file \"" + fileName + "\""); + ex.printStackTrace(System.err); + } + } else { + System.err.println("Cannot read policy file \"" + fileName + "\""); + } + } + } catch (Exception ex) { + ex.printStackTrace(System.err); + System.exit(1); + } + System.exit(0); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java new file mode 100755 index 0000000..041769f --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java
@@ -0,0 +1,124 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMAttributeValue; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; +import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter; + +/** + * DOMPolicyCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} for + * {@link com.att.research.xacmlatt.pdp.policy.Policy}s with methods for creation from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMPolicyCombinerParameter extends TargetedCombinerParameter<Identifier, PolicySetChild> { + private static final Log logger = LogFactory.getLog(DOMPolicyCombinerParameter.class); + + protected DOMPolicyCombinerParameter() { + + } + + /** + * Creates a new <code>TargetedCombinerParameter</code> for <code>Policy</code>s by parsing the given <code>Node</code> + * representing a XACML PolicyCombinerParameter element. + * + * @param nodeCombinerParameter the <code>Node</code> representing the XACML PolicyCombinerParameter element + * @return a new <code>TargetedCombinerParameter</code> for <code>Policy</code>s parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static TargetedCombinerParameter<Identifier,PolicySetChild> newInstance(Node nodeCombinerParameter) throws DOMStructureException { + Element elementPolicyCombinerParameter = DOMUtil.getElement(nodeCombinerParameter); + boolean bLenient = DOMProperties.isLenient(); + + DOMPolicyCombinerParameter domPolicyCombinerParameter = new DOMPolicyCombinerParameter(); + + try { + NodeList children = elementPolicyCombinerParameter.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) { + domPolicyCombinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter); + } + } + } + } + if (domPolicyCombinerParameter.getAttributeValue() == null && !bLenient) { + throw DOMUtil.newMissingElementException(nodeCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + domPolicyCombinerParameter.setName(DOMUtil.getStringAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient)); + domPolicyCombinerParameter.setTargetId(DOMUtil.getIdentifierAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_POLICYIDREF, !bLenient)); + + } catch (DOMStructureException ex) { + domPolicyCombinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domPolicyCombinerParameter; + + } + public static boolean repair(Node nodePolicyCombinerParameter) throws DOMStructureException { + Element elementPolicyCombinerParameter = DOMUtil.getElement(nodePolicyCombinerParameter); + boolean result = false; + + NodeList children = elementPolicyCombinerParameter.getChildNodes(); + int numChildren; + boolean sawAttributeValue = false; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) { + if (sawAttributeValue) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicyCombinerParameter.removeChild(child); + result = true; + } else { + sawAttributeValue = true; + result = DOMAttributeValue.repair(child) || result; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicyCombinerParameter.removeChild(child); + result = true; + } + } + } + } + if (!sawAttributeValue) { + throw DOMUtil.newMissingElementException(nodePolicyCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + result = DOMUtil.repairStringAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result; + result = DOMUtil.repairIdentifierAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_POLICYIDREF, logger) || result; + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java new file mode 100755 index 0000000..45fbc17 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java
@@ -0,0 +1,129 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.io.File; +import java.io.InputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.PolicySet; + +/** + * DOMPolicyDef extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} with methods for loading them from a <code>File</code>. + * + * @author car + * @version $Revision: 1.2 $ + */ +public abstract class DOMPolicyDef { + protected DOMPolicyDef() { + } + + protected static PolicyDef newInstance(Document document, PolicySet policySetParent) throws DOMStructureException { + PolicyDef policyDef = null; + try { + Node rootNode = document.getFirstChild(); + if (rootNode == null) { + throw new Exception("No child in document"); + } + + if (DOMUtil.isInNamespace(rootNode, XACML3.XMLNS)) { + if (XACML3.ELEMENT_POLICY.equals(rootNode.getLocalName())) { + policyDef = DOMPolicy.newInstance(rootNode, policySetParent, null); + if (policyDef == null) { + throw new DOMStructureException("Failed to parse Policy"); + } + } else if (XACML3.ELEMENT_POLICYSET.equals(rootNode.getLocalName())) { + policyDef = DOMPolicySet.newInstance(rootNode, policySetParent, null); + if (policyDef == null) { + throw new DOMStructureException("Failed to parse PolicySet"); + } + } else { + throw DOMUtil.newUnexpectedElementException(rootNode); + } + } else { + throw DOMUtil.newUnexpectedElementException(rootNode); + } + } catch (Exception ex) { + throw new DOMStructureException("Exception parsing Policy: " + ex.getMessage(), ex); + } + return policyDef; + } + + public static PolicyDef load(InputStream inputStream) throws DOMStructureException { + /* + * Get the DocumentBuilderFactory + */ + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + if (documentBuilderFactory == null) { + throw new DOMStructureException("No XML DocumentBuilderFactory configured"); + } + documentBuilderFactory.setNamespaceAware(true); + + /* + * Get the DocumentBuilder + */ + DocumentBuilder documentBuilder = null; + try { + documentBuilder = documentBuilderFactory.newDocumentBuilder(); + } catch (Exception ex) { + throw new DOMStructureException("Exception creating DocumentBuilder: " + ex.getMessage(), ex); + } + + /* + * Parse the XML file + */ + PolicyDef policyDef = null; + try { + Document document = documentBuilder.parse(inputStream); + if (document == null) { + throw new Exception("Null document returned"); + } + policyDef = newInstance(document, null); + } catch (Exception ex) { + throw new DOMStructureException("Exception loading Policy from input stream: " + ex.getMessage(), ex); + } + return policyDef; + } + + /** + * Creates a new <code>PolicyDef</code> derived object by loading the given <code>File</code> containing a XACML 3.0 + * Policy or PolicySet. + * + * @param filePolicy the <code>File</code> containing the XACML Policy or PolicySet + * @return the newly created <code>PolicyDef</code> + * @throws DOMStructureException if there is an error loading the <code>PolicyDef</code> + */ + public static PolicyDef load(File filePolicy) throws DOMStructureException { + /* + * Parse the XML file + */ + PolicyDef policyDef = null; + try { + Document document = DOMUtil.loadDocument(filePolicy); + if (document == null) { + throw new Exception("Null document returned"); + } + policyDef = newInstance(document, null); + } catch (Exception ex) { + throw new DOMStructureException("Exception loading Policy file \"" + filePolicy.getAbsolutePath() + "\": " + ex.getMessage(), ex); + } + return policyDef; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java new file mode 100755 index 0000000..65a78b1 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java
@@ -0,0 +1,103 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.net.URI; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; + +/** + * DOMPolicyDefaults extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDefaults} with methods for creation from + * DOM {@org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMPolicyDefaults extends PolicyDefaults { + private static final Log logger = LogFactory.getLog(DOMPolicyDefaults.class); + + protected DOMPolicyDefaults(URI xpathVersionIn, PolicyDefaults policyDefaultsParentIn) { + super(xpathVersionIn, policyDefaultsParentIn); + } + + /** + * Creates a new <code>DOMPolicyDefaults</code> by parsing the given <code>Node</code> representing a XACML PolicyDefaults element. + * + * @param nodePolicyDefaults the <code>Node</code> representing the PolicyDefaults element. + * @param policyDefaultsParent the <code>PolicyDefaults</code> parent for the new <code>DOMPolicyDefaults</code> + * @return a new <code>DOMPolicyDefaults</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if the conversion is not possible + */ + public static PolicyDefaults newInstance(Node nodePolicyDefaults, PolicyDefaults policyDefaultsParent) throws DOMStructureException { + Element elementPolicyDefaults = DOMUtil.getElement(nodePolicyDefaults); + boolean bLenient = DOMProperties.isLenient(); + + URI uriXPathVersion = null; + + NodeList children = elementPolicyDefaults.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_XPATHVERSION.equals(child.getLocalName())) { + uriXPathVersion = DOMUtil.getURIContent(child); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicyDefaults); + } + } + } + } + return new DOMPolicyDefaults(uriXPathVersion, policyDefaultsParent); + } + + public static boolean repair(Node nodePolicyDefaults) throws DOMStructureException { + Element elementPolicyDefaults = DOMUtil.getElement(nodePolicyDefaults); + boolean result = false; + + NodeList children = elementPolicyDefaults.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_XPATHVERSION.equals(child.getLocalName())) { + try { + DOMUtil.getURIContent(child); + } catch (DOMStructureException ex) { + logger.warn("Setting invalid " + XACML3.ELEMENT_XPATHVERSION + " attribute " + child.getTextContent() + " to " + XACML.XPATHVERSION_2_0); + child.setTextContent(XACML.XPATHVERSION_2_0); + result = true; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicyDefaults.removeChild(child); + result = true; + } + } + } + } + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java new file mode 100755 index 0000000..3aa9870 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java
@@ -0,0 +1,59 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.w3c.dom.Node; + +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMIdReferenceMatch; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacmlatt.pdp.policy.PolicyIdReference; +import com.att.research.xacmlatt.pdp.policy.PolicySet; + +/** + * DOMPolicyIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReference} with methods for creation + * from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMPolicyIdReference { + + protected DOMPolicyIdReference() { + } + + /** + * Creates a new <code>PolicyIdReference</code> parsed from the given <code>Node</code> representing a XACML PolicyIdReference element. + * + * @param nodePolicyIdReference the <code>Node</code> representing the XACML PolicyIdReference element + * @return a new <code>PolicyIdReference</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static PolicyIdReference newInstance(Node nodePolicyIdReference, PolicySet policySetParent) throws DOMStructureException { + PolicyIdReference domPolicyIdReference = new PolicyIdReference(policySetParent); + + try { + domPolicyIdReference.setIdReferenceMatch(DOMIdReferenceMatch.newInstance(nodePolicyIdReference)); + } catch (DOMStructureException ex) { + domPolicyIdReference.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domPolicyIdReference; + } + + public static boolean repair(Node nodePolicyIdReference) throws DOMStructureException { + return DOMIdReferenceMatch.repair(nodePolicyIdReference); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java new file mode 100755 index 0000000..d1e4089 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java
@@ -0,0 +1,126 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMAttribute; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.PolicyIssuer; + +/** + * DOMPolicyIssuer extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIsser} with methods for creation from + * DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMPolicyIssuer extends PolicyIssuer { + private static Log logger = LogFactory.getLog(DOMPolicyIssuer.class); + private static Identifier identifierCategoryPolicyIssuer = new IdentifierImpl("urn:att:names:tc:xacml:3.0:policy-issuer"); + + protected DOMPolicyIssuer() { + super(); + } + + /** + * Creates a new <code>DOMPolicyIssuer</code> by parsing the given <code>Node</code> representing a XACML PolicyIssuer element. + * + * @param nodePolicyIssuer the <code>Node</code> representing the PolicyIssuer element + * @return the new <code>DOMPolicyIssuer</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if the conversion is not possible + */ + public static PolicyIssuer newInstance(Node nodePolicyIssuer) throws DOMStructureException { + Element elementPolicyIssuer = DOMUtil.getElement(nodePolicyIssuer); + boolean bLenient = DOMProperties.isLenient(); + + DOMPolicyIssuer domPolicyIssuer = new DOMPolicyIssuer(); + + try { + NodeList children = elementPolicyIssuer.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_CONTENT.equals(childName)) { + if (domPolicyIssuer.getContent() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicyIssuer); + } + domPolicyIssuer.setContent(child); + } else if (XACML3.ELEMENT_ATTRIBUTE.equals(childName)) { + domPolicyIssuer.add(DOMAttribute.newInstance(identifierCategoryPolicyIssuer, child)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicyIssuer); + } + } + } + } + } + } catch (DOMStructureException ex) { + domPolicyIssuer.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domPolicyIssuer; + } + + public static boolean repair(Node nodePolicyIssuer) throws DOMStructureException { + Element elementPolicyIssuer = DOMUtil.getElement(nodePolicyIssuer); + boolean result = false; + + boolean sawContent = false; + NodeList children = elementPolicyIssuer.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_CONTENT.equals(childName)) { + if (sawContent) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicyIssuer.removeChild(child); + result = true; + } else { + sawContent = true; + } + } else if (XACML3.ELEMENT_ATTRIBUTE.equals(childName)) { + result = DOMAttribute.repair(child) || result; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicyIssuer.removeChild(child); + result = true; + } + } + } + } + } + + return result; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java new file mode 100755 index 0000000..20cff15 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java
@@ -0,0 +1,113 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.dom.DOMUtil; + +/** + * DOMPolicyRepair is an application for reading a XACML Policy or PolicySet document and ensuring it has the required attributes and then writing + * the repaired Policy or PolicySet to an output file. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class DOMPolicyRepair { + private static final String DEFAULT_VERSION = "1.0"; + + public static void main(String[] args) { + InputStream inputStream = System.in; + OutputStream outputStream = System.out; + + for (int i = 0 ; i < args.length ; ) { + if (args[i].equals("-i")) { + if (i+1 < args.length) { + try { + inputStream = new FileInputStream(args[i+1]); + } catch (IOException ex) { + System.err.println("IOException opening \"" + args[i+1] + "\" for reading."); + System.exit(1); + } + i += 2; + } else { + i++; + } + } else if (args[i].equals("-o")) { + if (i+1 < args.length){ + try { + outputStream = new FileOutputStream(args[i+1]); + } catch (IOException ex) { + System.err.println("IOException opening \"" + args[i+1] + "\" for writing."); + ex.printStackTrace(System.err); + System.exit(1);; + } + i += 2; + } else { + i++; + } + } else { + System.err.println("Unrecognized command line option \"" + args[i] + "\""); + System.exit(1); + } + } + + /* + * Get the XML Parser for the input file + */ + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + try { + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document documentInput = documentBuilder.parse(inputStream); + Element elementRoot = DOMUtil.getFirstChildElement(documentInput); + if (elementRoot == null) { + System.err.println("No root element"); + System.exit(1); + } else if (!XACML3.ELEMENT_POLICY.equals(elementRoot.getLocalName()) && !XACML3.ELEMENT_POLICYSET.equals(elementRoot.getLocalName())) { + System.err.println("Root element is not a Policy or PolicySet"); + System.exit(1); + } + + /* + * Make sure there is a Version attribute + */ + Node nodeVersion = DOMUtil.getAttribute(elementRoot, XACML3.ATTRIBUTE_VERSION); + if (nodeVersion == null) { + System.out.println("Adding Version attribute with value \"" + DEFAULT_VERSION + "\""); + elementRoot.setAttribute(XACML3.ATTRIBUTE_VERSION, DEFAULT_VERSION); + } + + /* + * Write out the updated document + */ + String newDocument = DOMUtil.toString(documentInput); + outputStream.write(newDocument.getBytes()); + } catch (Exception ex) { + ex.printStackTrace(System.err); + System.exit(1); + } + System.exit(0); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java new file mode 100755 index 0000000..c69a921 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java
@@ -0,0 +1,349 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.io.File; +import java.util.Iterator; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; +import com.att.research.xacmlatt.pdp.policy.PolicySet; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; + +/** + * DOMPolicySet extends {@link com.att.research.xacmlatt.pdp.policy.PolicySet} with methods for creation + * from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.4 $ + */ +public class DOMPolicySet { + private static final Log logger = LogFactory.getLog(DOMPolicySet.class); + + protected DOMPolicySet() { + } + + /** + * Creates a new <code>PolicySet</code> by parsing the given <code>Node</code> representing a XACML PolicySet element. + * + * @param nodePolicySet the <code>Node</code> representing the XACML PolicySetelement + * @param policyDefaultsParent the {@link com.att.research.xacmlatt.pdp.policy.PolicyDefaults} from the parent element + * @return a new <code>PolicySet</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static PolicySet newInstance(Node nodePolicySet, PolicySet policySetParent, PolicyDefaults policyDefaultsParent) throws DOMStructureException { + Element elementPolicySet = DOMUtil.getElement(nodePolicySet); + boolean bLenient = DOMProperties.isLenient(); + + PolicySet domPolicySet = new PolicySet(policySetParent); + + Iterator<?> iterator; + Identifier identifier; + Integer integer; + + try { + NodeList children = elementPolicySet.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + /* + * Run through once, quickly, to set the PolicyDefaults for the new DOMPolicySet + */ + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isNamespaceElement(child, XACML3.XMLNS) && XACML3.ELEMENT_POLICYDEFAULTS.equals(child.getLocalName())) { + if (domPolicySet.getPolicyDefaults() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicySet); + } + domPolicySet.setPolicyDefaults(DOMPolicyDefaults.newInstance(child, policyDefaultsParent)); + } + } + if (domPolicySet.getPolicyDefaults() == null) { + domPolicySet.setPolicyDefaults(policyDefaultsParent); + } + + /* + * Now process the other elements so we can pull up the parent policy defaults + */ + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) { + if (domPolicySet.getDescription() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicySet); + } + domPolicySet.setDescription(child.getTextContent()); + } else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) { + if (domPolicySet.getPolicyIssuer() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicySet); + } + domPolicySet.setPolicyIssuer(DOMPolicyIssuer.newInstance(child)); + } else if (XACML3.ELEMENT_POLICYSETDEFAULTS.equals(childName)) { + } else if (XACML3.ELEMENT_TARGET.equals(childName)) { + if (domPolicySet.getTarget() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicySet); + } + domPolicySet.setTarget(DOMTarget.newInstance(child)); + } else if (XACML3.ELEMENT_POLICYSET.equals(childName)) { + domPolicySet.addChild(DOMPolicySet.newInstance(child, domPolicySet, domPolicySet.getPolicyDefaults())); + } else if (XACML3.ELEMENT_POLICY.equals(childName)) { + domPolicySet.addChild(DOMPolicy.newInstance(child, domPolicySet, domPolicySet.getPolicyDefaults())); + } else if (XACML3.ELEMENT_POLICYIDREFERENCE.equals(childName)) { + domPolicySet.addChild(DOMPolicyIdReference.newInstance(child, domPolicySet)); + } else if (XACML3.ELEMENT_POLICYSETIDREFERENCE.equals(childName)) { + domPolicySet.addChild(DOMPolicySetIdReference.newInstance(child, domPolicySet)); + } else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) { + domPolicySet.addCombinerParameters(DOMCombinerParameter.newList(child)); + } else if (XACML3.ELEMENT_POLICYCOMBINERPARAMETERS.equals(childName)) { + domPolicySet.addPolicyCombinerParameter(DOMPolicyCombinerParameter.newInstance(child)); + } else if (XACML3.ELEMENT_POLICYSETCOMBINERPARAMETERS.equals(childName)) { + domPolicySet.addPolicyCombinerParameter(DOMPolicySetCombinerParameter.newInstance(child)); + } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) { + if ((iterator = domPolicySet.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicySet); + } + domPolicySet.setObligationExpressions(DOMObligationExpression.newList(child, null)); + } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) { + if ((iterator = domPolicySet.getAdviceExpressions()) != null && iterator.hasNext() && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicySet); + } + domPolicySet.setAdviceExpressions(DOMAdviceExpression.newList(child, null)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicySet); + } + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodePolicySet); + } + } + } + } + if (domPolicySet.getTarget() == null && !bLenient) { + throw DOMUtil.newMissingElementException(nodePolicySet, XACML3.XMLNS, XACML3.ELEMENT_TARGET); + } + + /* + * Get the attributes + */ + domPolicySet.setIdentifier(DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYSETID, !bLenient)); + domPolicySet.setVersion(DOMUtil.getVersionAttribute(elementPolicySet, XACML3.ATTRIBUTE_VERSION, !bLenient)); + + identifier = DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID, !bLenient); + CombiningAlgorithm<PolicySetChild> combiningAlgorithm = null; + try { + combiningAlgorithm = CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(identifier); + } catch (FactoryException ex) { + if (!bLenient) { + throw new DOMStructureException("Failed to get CombinginAlgorithm", ex); + } + } + if (combiningAlgorithm == null && !bLenient) { + throw new DOMStructureException(elementPolicySet, "Unknown policy combining algorithm \"" + identifier.toString() + "\" in \"" + DOMUtil.getNodeLabel(nodePolicySet)); + } else { + domPolicySet.setPolicyCombiningAlgorithm(combiningAlgorithm); + } + + if ((integer = DOMUtil.getIntegerAttribute(elementPolicySet, XACML3.ATTRIBUTE_MAXDELEGATIONDEPTH)) != null) { + domPolicySet.setMaxDelegationDepth(integer); + } + } catch (DOMStructureException ex) { + domPolicySet.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domPolicySet; + } + + public static boolean repair(Node nodePolicySet) throws DOMStructureException { + Element elementPolicySet = DOMUtil.getElement(nodePolicySet); + boolean result = false; + + NodeList children = elementPolicySet.getChildNodes(); + int numChildren; + boolean sawDescription = false; + boolean sawPolicyIssuer = false; + boolean sawPolicyDefaults = false; + boolean sawTarget = false; + boolean sawObligationExprs = false; + boolean sawAdviceExprs = false; + + if (children != null && (numChildren = children.getLength()) > 0) { + /* + * Now process the other elements so we can pull up the parent policy defaults + */ + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) { + if (sawDescription) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySet.removeChild(child); + result = true; + } else { + sawDescription = true; + } + } else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) { + if (sawPolicyIssuer) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySet.removeChild(child); + result = true; + } else { + sawPolicyIssuer = true; + result = DOMPolicyIssuer.repair(child) || result; + } + } else if (XACML3.ELEMENT_POLICYSETDEFAULTS.equals(childName)) { + if (sawPolicyDefaults) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySet.removeChild(child); + result = true; + } else { + sawPolicyDefaults = true; + result = DOMPolicyDefaults.repair(child) || result; + } + } else if (XACML3.ELEMENT_TARGET.equals(childName)) { + if (sawTarget) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySet.removeChild(child); + result = true; + } else { + sawTarget = true; + result = DOMTarget.repair(child) || result; + } + } else if (XACML3.ELEMENT_POLICYSET.equals(childName)) { + result = DOMPolicySet.repair(child) || result; + } else if (XACML3.ELEMENT_POLICY.equals(childName)) { + result = DOMPolicy.repair(child) || result; + } else if (XACML3.ELEMENT_POLICYIDREFERENCE.equals(childName)) { + result = DOMPolicyIdReference.repair(child) || result; + } else if (XACML3.ELEMENT_POLICYSETIDREFERENCE.equals(childName)) { + result = DOMPolicySetIdReference.repair(child) || result; + } else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) { + result = DOMCombinerParameter.repair(child) || result; + } else if (XACML3.ELEMENT_POLICYCOMBINERPARAMETERS.equals(childName)) { + result = DOMPolicyCombinerParameter.repair(child) || result; + } else if (XACML3.ELEMENT_POLICYSETCOMBINERPARAMETERS.equals(childName)) { + result = DOMPolicySetCombinerParameter.repair(child) || result; + } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) { + if (sawObligationExprs) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySet.removeChild(child); + result = true; + } else { + sawObligationExprs = true; + result = DOMObligationExpression.repairList(child) || result; + } + } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) { + if (sawAdviceExprs) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySet.removeChild(child); + result = true; + } else { + sawAdviceExprs = true; + result = DOMAdviceExpression.repairList(child) || result; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySet.removeChild(child); + result = true; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySet.removeChild(child); + result = true; + } + } + } + } + if (!sawTarget) { + throw DOMUtil.newMissingElementException(nodePolicySet, XACML3.XMLNS, XACML3.ELEMENT_TARGET); + } + + /* + * Get the attributes + */ + result = DOMUtil.repairIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYSETID, logger) || result; + result = DOMUtil.repairVersionAttribute(elementPolicySet, XACML3.ATTRIBUTE_VERSION, logger) || result; + result = DOMUtil.repairIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID, XACML3.ID_POLICY_DENY_OVERRIDES, logger) || result; + + Identifier identifier = DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID); + CombiningAlgorithm<PolicySetChild> combiningAlgorithm = null; + try { + combiningAlgorithm = CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(identifier); + } catch (FactoryException ex) { + combiningAlgorithm = null; + } + if (combiningAlgorithm == null) { + logger.warn("Setting invalid " + XACML3.ATTRIBUTE_POLICYCOMBININGALGID + " attribute " + identifier.stringValue() + " to " + XACML3.ID_POLICY_DENY_OVERRIDES.stringValue()); + elementPolicySet.setAttribute(XACML3.ATTRIBUTE_POLICYCOMBININGALGID, XACML3.ID_POLICY_DENY_OVERRIDES.stringValue()); + result = true; + } + + return result; + } + + public static void main(String args[]) { + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + + for (String fileName: args) { + File filePolicy = new File(fileName); + if (filePolicy.exists() && filePolicy.canRead()) { + try { + Document documentPolicy = documentBuilder.parse(filePolicy); + if (documentPolicy.getFirstChild() == null) { + System.err.println(fileName + ": Error: No PolicySet found"); + } else if (!XACML3.ELEMENT_POLICYSET.equals(documentPolicy.getFirstChild().getLocalName())) { + System.err.println(fileName + ": Error: Not a PolicySet document"); + } else { + PolicySet policySet = DOMPolicySet.newInstance(documentPolicy.getFirstChild(), null, null); + System.out.println(fileName + ": validate()=" + policySet.validate()); + System.out.println(StringUtils.prettyPrint(policySet.toString())); + } + } catch (Exception ex) { + System.err.println("Exception processing policy set file \"" + fileName + "\""); + ex.printStackTrace(System.err); + } + } else { + System.err.println("Cannot read policy set file \"" + fileName + "\""); + } + } + } catch (Exception ex) { + ex.printStackTrace(System.err); + System.exit(1); + } + System.exit(0); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java new file mode 100755 index 0000000..42d856c --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java
@@ -0,0 +1,126 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMAttributeValue; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; +import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter; + +/** + * DOMPolicySetCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} for + * {@link com.att.research.xacmlatt.pdp.policy.PolicySet}s with methods for creation from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMPolicySetCombinerParameter extends TargetedCombinerParameter<Identifier, PolicySetChild> { + public static final Log logger = LogFactory.getLog(DOMPolicySetCombinerParameter.class); + + protected DOMPolicySetCombinerParameter() { + + } + + /** + * Creates a new <code>TargetedCombinerParameter</code> for <code>PolicySet</code>s by parsing the given <code>Node</code> + * representing a XACML PolicySetCombinerParameter element. + * + * @param nodeCombinerParameter the <code>Node</code> representing the XACML PolicySetCombinerParameter element + * @return a new <code>TargetedCombinerParameter</code> for <code>PolicySet</code>s parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static TargetedCombinerParameter<Identifier,PolicySetChild> newInstance(Node nodeCombinerParameter) throws DOMStructureException { + Element elementPolicySetCombinerParameter = DOMUtil.getElement(nodeCombinerParameter); + boolean bLenient = DOMProperties.isLenient(); + + DOMPolicySetCombinerParameter domPolicySetCombinerParameter = new DOMPolicySetCombinerParameter(); + + try { + NodeList children = elementPolicySetCombinerParameter.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) { + if (domPolicySetCombinerParameter.getAttributeValue() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter); + } + domPolicySetCombinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter); + } + } + } + } + if (domPolicySetCombinerParameter.getAttributeValue() == null && !bLenient) { + throw DOMUtil.newMissingElementException(elementPolicySetCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + domPolicySetCombinerParameter.setName(DOMUtil.getStringAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient)); + domPolicySetCombinerParameter.setTargetId(DOMUtil.getIdentifierAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_POLICYSETIDREF, !bLenient)); + } catch (DOMStructureException ex) { + domPolicySetCombinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domPolicySetCombinerParameter; + + } + + public static boolean repair(Node nodeCombinerParameter) throws DOMStructureException { + Element elementPolicySetCombinerParameter = DOMUtil.getElement(nodeCombinerParameter); + boolean result = false; + + NodeList children = elementPolicySetCombinerParameter.getChildNodes(); + int numChildren; + boolean sawAttributeValue = false; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) { + if (sawAttributeValue) { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySetCombinerParameter.removeChild(child); + result = true; + } else { + sawAttributeValue = true; + result = DOMAttributeValue.repair(child) || result; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementPolicySetCombinerParameter.removeChild(child); + result = true; + } + } + } + } + if (!sawAttributeValue) { + throw DOMUtil.newMissingElementException(elementPolicySetCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + result = DOMUtil.repairStringAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result; + result = DOMUtil.repairIdentifierAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_POLICYSETIDREF, logger) || result; + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java new file mode 100755 index 0000000..0f45c43 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java
@@ -0,0 +1,58 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.w3c.dom.Node; + +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMIdReferenceMatch; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacmlatt.pdp.policy.PolicySet; +import com.att.research.xacmlatt.pdp.policy.PolicySetIdReference; + +/** + * DOMPolicySetIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicySetIdReference} with methods for creation + * from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMPolicySetIdReference { + protected DOMPolicySetIdReference() { + } + + /** + * Creates a new <code>PolicySetIdReference</code> parsed from the given <code>Node</code> representing a XACML PolicySetIdReference element. + * + * @param nodePolicySetIdReference the <code>Node</code> representing the XACML PolicySetIdReference element + * @return a new <code>PolicySetIdReference</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static PolicySetIdReference newInstance(Node nodePolicySetIdReference, PolicySet policySetParent) throws DOMStructureException { + PolicySetIdReference domPolicySetIdReference = new PolicySetIdReference(policySetParent); + + try { + domPolicySetIdReference.setIdReferenceMatch(DOMIdReferenceMatch.newInstance(nodePolicySetIdReference)); + } catch (DOMStructureException ex) { + domPolicySetIdReference.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domPolicySetIdReference; + } + + public static boolean repair(Node nodePolicySetIdReference) throws DOMStructureException { + return DOMIdReferenceMatch.repair(nodePolicySetIdReference); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java new file mode 100755 index 0000000..102f546 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java
@@ -0,0 +1,221 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import java.util.Iterator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.Condition; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.Rule; +import com.att.research.xacmlatt.pdp.policy.RuleEffect; + +/** + * DOMRule extends {@link com.att.research.xacmlatt.pdp.policy.Rule} with methods for creation from + * DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class DOMRule extends Rule { + private static final Log logger = LogFactory.getLog(DOMRule.class); + + protected DOMRule() { + } + + /** + * Creates a new <code>Rule</code> by parsing the given <code>Node</code> representing a XACML Rule element. + * + * @param nodeRule the <code>Node</code> representing the XACML Rule element + * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the Rule element + * @return a new <code>Rule</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static Rule newInstance(Node nodeRule, Policy policy) throws DOMStructureException { + Element elementRule = DOMUtil.getElement(nodeRule); + boolean bLenient = DOMProperties.isLenient(); + + DOMRule domRule = new DOMRule(); + + domRule.setPolicy(policy); + + Iterator<?> iterator; + + try { + NodeList children = elementRule.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) { + if (domRule.getDescription() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeRule); + } + domRule.setDescription(child.getTextContent()); + } else if (XACML3.ELEMENT_TARGET.equals(childName)) { + if (domRule.getTarget() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeRule); + } + domRule.setTarget(DOMTarget.newInstance(child)); + } else if (XACML3.ELEMENT_CONDITION.equals(childName)) { + if (domRule.getCondition() != null && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeRule); + } + Node nodeExpression = DOMUtil.getFirstChildElement(child); + if (nodeExpression == null && !bLenient) { + throw DOMUtil.newMissingElementException(child, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION); + } + domRule.setCondition(new Condition(DOMExpression.newInstance(nodeExpression, policy))); + } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) { + if ((iterator = domRule.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeRule); + } + domRule.setObligationExpressions(DOMObligationExpression.newList(child, policy)); + } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) { + if ((iterator = domRule.getAdviceExpressions()) != null && iterator.hasNext() && !bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeRule); + } + domRule.setAdviceExpressions(DOMAdviceExpression.newList(child, policy)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeRule); + } + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeRule); + } + } + } + } + + domRule.setRuleId(DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_RULEID, !bLenient)); + String string = DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT, !bLenient); + RuleEffect ruleEffect = RuleEffect.getRuleEffect(string); + if (ruleEffect == null && !bLenient) { + throw new DOMStructureException(elementRule, "Unknown RuleEffect \"" + string + "\" in \"" + DOMUtil.getNodeLabel(nodeRule) + "\""); + } + domRule.setRuleEffect(ruleEffect); + + } catch (DOMStructureException ex) { + domRule.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + return domRule; + } + + public static boolean repair(Node nodeRule) throws DOMStructureException { + Element elementRule = DOMUtil.getElement(nodeRule); + boolean result = false; + + NodeList children = elementRule.getChildNodes(); + int numChildren; + boolean sawDescription = false; + boolean sawTarget = false; + boolean sawCondition = false; + boolean sawObligationExpressions = false; + boolean sawAdviceExpressions = false; + + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) { + String childName = child.getLocalName(); + if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) { + if (sawDescription) { + logger.warn("Unexpected element " + child.getNodeName()); + elementRule.removeChild(child); + result = true; + } else { + sawDescription = true; + } + } else if (XACML3.ELEMENT_TARGET.equals(childName)) { + if (sawTarget) { + logger.warn("Unexpected element " + child.getNodeName()); + elementRule.removeChild(child); + result = true; + } else { + sawTarget = true; + result = DOMTarget.repair(child) || result; + } + } else if (XACML3.ELEMENT_CONDITION.equals(childName)) { + if (sawCondition) { + logger.warn("Unexpected element " + child.getNodeName()); + elementRule.removeChild(child); + result = true; + } else { + sawCondition = true; + Node nodeExpression = DOMUtil.getFirstChildElement(child); + if (nodeExpression == null) { + throw DOMUtil.newMissingElementException(child, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION); + } + result = DOMExpression.repair(nodeExpression) || result; + } + } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) { + if (sawObligationExpressions) { + logger.warn("Unexpected element " + child.getNodeName()); + elementRule.removeChild(child); + result = true; + } else { + sawObligationExpressions = true; + result = DOMObligationExpression.repairList(child) || result; + } + } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) { + if (sawAdviceExpressions) { + logger.warn("Unexpected element " + child.getNodeName()); + elementRule.removeChild(child); + result = true; + } else { + sawAdviceExpressions = true; + result = DOMAdviceExpression.repairList(child) || result; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementRule.removeChild(child); + result = true; + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementRule.removeChild(child); + result = true; + } + } + } + } + + result = DOMUtil.repairStringAttribute(elementRule, XACML3.ATTRIBUTE_RULEID, IdentifierImpl.gensym().stringValue(), logger) || result; + result = DOMUtil.repairStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT, RuleEffect.DENY.getName(), logger) || result; + + String string = DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT); + RuleEffect ruleEffect = RuleEffect.getRuleEffect(string); + if (ruleEffect == null) { + logger.warn("Setting invalid " + XACML3.ATTRIBUTE_EFFECT + " attribute " + string + " to " + RuleEffect.DENY.getName()); + elementRule.setAttribute(XACML3.ATTRIBUTE_EFFECT, RuleEffect.DENY.getName()); + result = true; + } + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java new file mode 100755 index 0000000..732c8b5 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java
@@ -0,0 +1,123 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMAttributeValue; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.Rule; +import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter; + +/** + * DOMRuleCombinerParameters extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} with methods + * for creation from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMRuleCombinerParameters extends TargetedCombinerParameter<String,Rule> { + private static final Log logger = LogFactory.getLog(DOMRuleCombinerParameters.class); + + protected DOMRuleCombinerParameters() { + } + + /** + * Creates a new <code>TargetedCombinerParameter</code> for {@link com.att.research.xacmlatt.pdp.policy.Rule}s by parsing the + * given <code>Node</code> representing a XACML RuleCombinerParameters element. + * + * @param nodeRuleCombinerParameters the <code>Node</code> representing the XACML RuleCombinerParameters element. + * @return a new <code>TargetedCombinerParameter</code> for <code>Rule</code>s parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code>. + */ + public static TargetedCombinerParameter<String,Rule> newInstance(Node nodeRuleCombinerParameters) throws DOMStructureException { + Element elementRuleCombinerParameters = DOMUtil.getElement(nodeRuleCombinerParameters); + boolean bLenient = DOMProperties.isLenient(); + + DOMRuleCombinerParameters domRuleCombinerParameters = new DOMRuleCombinerParameters(); + + try { + NodeList children = elementRuleCombinerParameters.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) { + if (domRuleCombinerParameters.getAttributeValue() != null) { + throw DOMUtil.newUnexpectedElementException(child, nodeRuleCombinerParameters); + } + domRuleCombinerParameters.setAttributeValue(DOMAttributeValue.newInstance(child, null)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeRuleCombinerParameters); + } + } + } + } + if (domRuleCombinerParameters.getAttributeValue() == null && !bLenient) { + throw DOMUtil.newMissingElementException(nodeRuleCombinerParameters, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + domRuleCombinerParameters.setName(DOMUtil.getStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient)); + domRuleCombinerParameters.setTargetId(DOMUtil.getStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_RULEIDREF, !bLenient)); + } catch (DOMStructureException ex) { + domRuleCombinerParameters.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + return domRuleCombinerParameters; + } + + public static boolean repair(Node nodeRuleCombinerParameters) throws DOMStructureException { + Element elementRuleCombinerParameters = DOMUtil.getElement(nodeRuleCombinerParameters); + boolean result = false; + + NodeList children = elementRuleCombinerParameters.getChildNodes(); + int numChildren; + boolean sawAttributeValue = false; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) { + if (sawAttributeValue) { + logger.warn("Unexpected element " + child.getNodeName()); + elementRuleCombinerParameters.removeChild(child); + result = true; + } else { + sawAttributeValue = true; + result = result || DOMAttributeValue.repair(child); + } + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementRuleCombinerParameters.removeChild(child); + result = true; + } + } + } + } + if (!sawAttributeValue) { + throw DOMUtil.newMissingElementException(nodeRuleCombinerParameters, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE); + } + result = result || DOMUtil.repairStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger); + result = result || DOMUtil.repairIdentifierAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_RULEIDREF, logger); + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java new file mode 100755 index 0000000..599dfa5 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java
@@ -0,0 +1,102 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.Target; + +/** + * DOMTarget extends {@link com.att.research.xacmlatt.pdp.policy.Target} with methods for creation from + * DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class DOMTarget extends Target { + private static final Log logger = LogFactory.getLog(DOMTarget.class); + + /** + * Creates an empty <code>DOMTarget</code>. + */ + protected DOMTarget() { + } + + /** + * Creates a new <code>DOMTarget</code> by parsing the given <code>Node</code> representing a XACML Target element. + * + * @param nodeTarget the <code>Node</code> representing the XACML Target element + * @return a new <code>DOMTarget</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static Target newInstance(Node nodeTarget) throws DOMStructureException { + Element elementTarget = DOMUtil.getElement(nodeTarget); + boolean bLenient = DOMProperties.isLenient(); + + DOMTarget domTarget = new DOMTarget(); + try { + NodeList children = elementTarget.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ANYOF.equals(child.getLocalName())) { + domTarget.addAnyOf(DOMAnyOf.newInstance(child)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(child, nodeTarget); + } + } + } + } + } catch (DOMStructureException ex) { + domTarget.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + + return domTarget; + } + + public static boolean repair(Node nodeTarget) throws DOMStructureException { + Element elementTarget = DOMUtil.getElement(nodeTarget); + boolean result = false; + + NodeList children = elementTarget.getChildNodes(); + int numChildren; + if (children != null && (numChildren = children.getLength()) > 0) { + for (int i = 0 ; i < numChildren ; i++) { + Node child = children.item(i); + if (DOMUtil.isElement(child)) { + if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ANYOF.equals(child.getLocalName())) { + result = DOMAnyOf.repair(child) || result; + } else { + logger.warn("Unexpected element " + child.getNodeName()); + elementTarget.removeChild(child); + result = true; + } + } + } + } + + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java new file mode 100755 index 0000000..d1d32f3 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java
@@ -0,0 +1,94 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.dom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.VariableDefinition; + +/** + * DOMVariableDefinition extends {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition} with methods + * for creation from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class DOMVariableDefinition extends VariableDefinition { + private static final Log logger = LogFactory.getLog(DOMVariableDefinition.class); + + protected DOMVariableDefinition() { + } + + /** + * Creates a new <code>VariableDefinition</code> by parsing the given <code>Node</code> representing a XACML VariableDefinition element. + * + * @param nodeVariableDefinition the <code>Node</code> representing the XACML VariableDefinition element + * @param policy the <code>Policy</code> encompassing the VariableDefinition element + * @return a new <code>VariableDefinition</code> parsed from the given <code>Node</code> + * @throws DOMStructureException if there is an error parsing the <code>Node</code> + */ + public static VariableDefinition newInstance(Node nodeVariableDefinition, Policy policy) throws DOMStructureException { + Element elementVariableDefinition = DOMUtil.getElement(nodeVariableDefinition); + boolean bLenient = DOMProperties.isLenient(); + + DOMVariableDefinition domVariableDefinition = new DOMVariableDefinition(); + + try { + Element elementExpression = DOMUtil.getFirstChildElement(elementVariableDefinition); + if (elementExpression != null) { + if (DOMExpression.isExpression(elementExpression)) { + domVariableDefinition.setExpression(DOMExpression.newInstance(elementExpression, policy)); + } else if (!bLenient) { + throw DOMUtil.newUnexpectedElementException(elementExpression, elementVariableDefinition); + } + } else if (!bLenient) { + throw DOMUtil.newMissingElementException(elementVariableDefinition, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION); + } + domVariableDefinition.setId(DOMUtil.getStringAttribute(elementVariableDefinition, XACML3.ATTRIBUTE_VARIABLEID, !bLenient)); + } catch (DOMStructureException ex) { + domVariableDefinition.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + if (DOMProperties.throwsExceptions()) { + throw ex; + } + } + return domVariableDefinition; + } + + public static boolean repair(Node nodeVariableDefinition) throws DOMStructureException { + Element elementVariableDefinition = DOMUtil.getElement(nodeVariableDefinition); + boolean result = false; + + Element elementExpression = DOMUtil.getFirstChildElement(elementVariableDefinition); + if (elementExpression != null) { + if (DOMExpression.isExpression(elementExpression)) { + result = result || DOMExpression.repair(elementExpression); + } else { + logger.warn("Unexpected element " + elementExpression.getNodeName()); + elementVariableDefinition.removeChild(elementExpression); + result = true; + } + } else { + throw DOMUtil.newMissingElementException(elementVariableDefinition, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION); + } + + result = result || DOMUtil.repairStringAttribute(elementVariableDefinition, XACML3.ATTRIBUTE_VARIABLEID, "variable", logger); + return result; + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java new file mode 100755 index 0000000..f42ce1e --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java
@@ -0,0 +1,20 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.policy.dom; + +/** + * com.att.research.xacmlatt.pdp.policy.dom contains class definitions that extend {@link com.att.research.xacmlatt.pdp.policy} classes + * with methods for creation from DOM {@link org.w3c.dom.Node}s. + * + * @author car + * @version $Revision: 1.1 $ + */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java new file mode 100755 index 0000000..08064fd --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java
@@ -0,0 +1,170 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.expressions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.policy.Expression; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentExpression; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; + +/** + * Apply extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML Apply Expression element. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class Apply extends Expression { + private Identifier functionId; + private FunctionDefinition functionDefinition; + private String description; + private List<Expression> arguments = new ArrayList<Expression>(); + + protected List<Expression> getArgumentList() { + return this.arguments; + } + + protected void clearArgumentList() { + this.getArgumentList().clear(); + } + + public Apply(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public Apply(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public Apply() { + } + + public Apply(Identifier functionIdIn, String descriptionIn, Collection<Expression> argumentsIn) { + this.functionId = functionIdIn; + this.description = descriptionIn; + if (argumentsIn != null) { + this.arguments.addAll(argumentsIn); + } + } + + public Identifier getFunctionId() { + return this.functionId; + } + + public void setFunctionId(Identifier identifier) { + this.functionId = identifier; + this.functionDefinition = null; + } + + /** + * Gets and caches the {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} matching the + * <code>Identifier</code> for the FunctionId in this <code>Apply</code>. + * + * @return the <code>FunctionDefinition</code> for the <code>Identifier</code> for the Function Id for this <code>Apply</code> + */ + public FunctionDefinition getFunctionDefinition() { + if (this.functionDefinition == null) { + Identifier thisFunctionId = this.getFunctionId(); + if (thisFunctionId != null) { + try { + this.functionDefinition = FunctionDefinitionFactory.newInstance().getFunctionDefinition(thisFunctionId); + } catch (FactoryException ex) { + this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "FactoryException getting FunctionDefinition"); + } + } + } + return this.functionDefinition; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String string) { + this.description = string; + } + + public Iterator<Expression> getArguments() { + return this.getArgumentList().iterator(); + } + + public void setArguments(Collection<Expression> listExpressions) { + this.clearArgumentList(); + if (listExpressions != null) { + this.addArguments(listExpressions); + } + } + + public void addArgument(Expression expression) { + this.getArgumentList().add(expression); + } + + public void addArguments(Collection<Expression> listExpressions) { + this.getArgumentList().addAll(listExpressions); + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + /* + * Get the FunctionDefinition + */ + FunctionDefinition thisFunctionDefinition = this.getFunctionDefinition(); + if (thisFunctionDefinition == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Unknown Function \"" + this.getFunctionId().toString() + "\"")); + } + + /* + * Get all of the arguments and convert them into FunctionArgument objects. + */ + List<FunctionArgument> listFunctionArguments = new ArrayList<FunctionArgument>(); + Iterator<Expression> iterExpressionArguments = this.getArguments(); + if (iterExpressionArguments != null) { + while (iterExpressionArguments.hasNext()) { + listFunctionArguments.add(new FunctionArgumentExpression(iterExpressionArguments.next(), evaluationContext, policyDefaults)); + } + } + + /* + * Apply the FunctionDefinition to the arguments + */ + return thisFunctionDefinition.evaluate(evaluationContext, listFunctionArguments); + } + + @Override + protected boolean validateComponent() { + if (this.getFunctionId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FunctionId"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java new file mode 100755 index 0000000..2a3e530 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java
@@ -0,0 +1,215 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.expressions; + +import java.util.Collection; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.MissingAttributeDetail; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.api.StatusDetail; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPRequest; +import com.att.research.xacml.api.pip.PIPResponse; +import com.att.research.xacml.std.StdMutableMissingAttributeDetail; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.StdStatusDetail; +import com.att.research.xacml.std.pip.StdPIPRequest; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; + +/** + * AttributeDesignator extends {@link com.att.research.xacmlatt.pdp.policy.expression.AttributeRetrievalBase} to represent the + * XACML AttributeDesignator element. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class AttributeDesignator extends AttributeRetrievalBase { + private Identifier attributeId; + private String issuer; + private PIPRequest pipRequestCached; + private MissingAttributeDetail missingAttributeDetail; + private StatusDetail statusDetail; + + protected PIPRequest getPIPRequest() { + if (this.pipRequestCached == null) { + this.pipRequestCached = new StdPIPRequest(this.getCategory(), this.getAttributeId(), this.getDataTypeId(), this.getIssuer()); + } + return this.pipRequestCached; + } + + protected MissingAttributeDetail getMissingAttributeDetail() { + if (this.missingAttributeDetail == null) { + this.missingAttributeDetail = new StdMutableMissingAttributeDetail(this.getCategory(), this.getAttributeId(), this.getDataTypeId(), this.getIssuer()); + } + return this.missingAttributeDetail; + } + + protected StatusDetail getStatusDetail() { + if (this.statusDetail == null) { + this.statusDetail = new StdStatusDetail(this.getMissingAttributeDetail()); + } + return this.statusDetail; + } + + public AttributeDesignator(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public AttributeDesignator(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public AttributeDesignator() { + } + + public Identifier getAttributeId() { + return this.attributeId; + } + + public void setAttributeId(Identifier identifierAttributeId) { + this.attributeId = identifierAttributeId; + } + + public String getIssuer() { + return this.issuer; + } + + public void setIssuer(String issuerIn) { + this.issuer = issuerIn; + } + + @Override + protected boolean validateComponent() { + if (!super.validateComponent()) { + return false; + } else if (this.getAttributeId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeId"); + return false; + } else { + return true; + } + } + + /** + * Determines if the given <code>Attribute</code> has the same category, attribute id, and issuer as this + * <code>AttributeDesignator</code>. + * + * @param attribute the <code>Attribute</code> to test + * @return true if the <code>Attribute</code> matches, else false + */ + protected boolean match(Attribute attribute) { + if (!this.getCategory().equals(attribute.getCategory())) { + return false; + } else if (!this.getAttributeId().equals(attribute.getAttributeId())) { + return false; + } else if (this.getIssuer() != null && !this.getIssuer().equals(attribute.getIssuer())) { + return false; + } else { + return true; + } + } + + /** + * Determines if the given <code>AttributeValue</code> has the same data type id as this + * <code>AttributeDesignator</code>. + * + * @param attributeValue the <code>AttributeValue</code> to test + * @return true if the <code>AttributeValue</code> maches, else false + */ + protected boolean match(AttributeValue<?> attributeValue) { + if (!this.getDataTypeId().equals(attributeValue.getDataTypeId())) { + return false; + } else { + return true; + } + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return ExpressionResult.newInstance(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + /* + * Set up the PIPRequest representing this + */ + PIPRequest pipRequest = this.getPIPRequest(); + assert(pipRequest != null); + + /* + * Query the evaluation context for results + */ + PIPResponse pipResponse = null; + try { + pipResponse = evaluationContext.getAttributes(pipRequest); + } catch (PIPException ex) { + throw new EvaluationException("PIPException getting Attributes", ex); + } + assert(pipResponse != null); + + /* + * See if the request was successful + */ + Status pipStatus = pipResponse.getStatus(); + if (pipStatus != null && !pipStatus.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newInstance(pipStatus); + } + + /* + * See if there were any results + */ + Bag bagAttributeValues = new Bag(); + Collection<Attribute> listAttributes = pipResponse.getAttributes(); + for (Attribute attribute : listAttributes) { + if (this.match(attribute)) { + for (AttributeValue<?> attributeValue: attribute.getValues()) { + if (this.match(attributeValue)) { + bagAttributeValues.add(attributeValue); + } + } + } + } + if (this.getMustBePresent() && bagAttributeValues.size() == 0) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE, "Missing required attribute", new StdStatusDetail(this.getMissingAttributeDetail()))); + } else { + return ExpressionResult.newBag(bagAttributeValues); + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getAttributeId()) != null) { + stringBuilder.append(",attributeId="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getIssuer()) != null) { + stringBuilder.append(",issuer="); + stringBuilder.append((String)objectToDump); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java new file mode 100755 index 0000000..21ac724 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java
@@ -0,0 +1,170 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.expressions; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.api.StatusDetail; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Expression; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; + +/** + * AttributeRetrievalBase extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and + * implements {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} to serve as an abstract base class + * for the {@link com.att.research.xacmlatt.pdp.policy.AttributeSelector} and {@link com.att.research.xacmlatt.pdp.policy.AttributeDesignator} + * classes. + * + * @author car + * @version $Revision: 1.1 $ + */ +public abstract class AttributeRetrievalBase extends Expression { + private Identifier category; + private Identifier dataTypeId; + private Boolean mustBePresent; + + protected AttributeRetrievalBase(StatusCode statusCodeIn, + String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + protected AttributeRetrievalBase(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + protected AttributeRetrievalBase() { + } + + protected AttributeRetrievalBase(Identifier categoryIn, Identifier dataTypeIdIn, Boolean mustBePresentIn) { + this.category = categoryIn; + this.dataTypeId = dataTypeIdIn; + this.mustBePresent = mustBePresentIn; + } + + /** + * Gets the {@link com.att.research.xacml.api.Identifier} for the category associated with this + * <code>AttributeRetrievalBase</code>. + * + * @return the <code>Identifier</code> for the category of this <code>AttributeRetrievalBase</code>. + */ + public Identifier getCategory() { + return this.category; + } + + /** + * Sets the <code>Identifier</code> for the category associated with this <code>AttributeRetrievalBase</code>. + * + * @param categoryIn the <code>Identifier</code> for the category associated with this <code>AttributeRetrievalBase</code> + */ + public void setCategory(Identifier categoryIn) { + this.category = categoryIn; + } + + /** + * Gets the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>. + * + * @return the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code> + */ + public Identifier getDataTypeId() { + return this.dataTypeId; + } + + /** + * Sets the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>. + * + * @param dataTypeIn the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code> + */ + public void setDataTypeId(Identifier dataTypeIn) { + // allow old-style Ids for Durations since there is no structural or semantic changes, just a different Id. + if (dataTypeIn.equals(XACML.ID_DATATYPE_WD_DAYTIMEDURATION)) { + dataTypeIn = DataTypes.DT_DAYTIMEDURATION.getId(); + } else if (dataTypeIn.equals(XACML.ID_DATATYPE_WD_YEARMONTHDURATION)) { + dataTypeIn = DataTypes.DT_YEARMONTHDURATION.getId(); + } + this.dataTypeId = dataTypeIn; + } + + /** + * Determines if a value must be found for this <code>AttributeRetrievalBase</code> when it is evaluated. If true, + * and no value is found, an indeterminate result is returned, otherwise an empty bag is returned. + * + * @return true if the value of this <code>AttributeRetrievalBase</code> must be found, else false + */ + public Boolean getMustBePresent() { + return this.mustBePresent; + } + + /** + * Sets the flag indicating whether a value must be found for this <code>AttributeRetrievalBase</code>. + * + * @param b the boolean value for the flag + */ + public void setMustBePresent(boolean b) { + this.mustBePresent = b; + } + + @Override + protected boolean validateComponent() { + if (this.getCategory() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Category"); + return false; + } else if (this.getDataTypeId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing DataType"); + return false; + } else if (this.getMustBePresent() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing MustBePresent"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getCategory()) != null) { + stringBuilder.append(",category="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getDataTypeId()) != null) { + stringBuilder.append(",dataType="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getMustBePresent()) != null) { + stringBuilder.append(",mustBePresent="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + + /** + * Creates the appropriate {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} for an empty list based + * on the <code>getMustBePresent</code> value. + * + * @return an appropriate <code>ExpressionResult</code> + */ + protected ExpressionResult getEmptyResult(String statusMessage, StatusDetail statusDetail) { + if (this.getMustBePresent() != null && this.getMustBePresent().booleanValue()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE, statusMessage, statusDetail)); + } else { + return ExpressionResult.newEmpty(); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java new file mode 100755 index 0000000..d5f94e2 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java
@@ -0,0 +1,283 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.expressions; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.DataTypeFactory; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.RequestAttributes; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.NodeNamespaceContext; +import com.att.research.xacml.std.datatypes.XPathExpressionWrapper; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.dom.DOMUtil; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; + +/** + * AttributeSelector extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeRetrievalBase} to implement + * the XACML AttributeSelector element. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class AttributeSelector extends AttributeRetrievalBase { + private Identifier contextSelectorId; + private String path; + @SuppressWarnings("unused") + private DataType<?> dataType; + + protected DataType<?> getDataType() { + Identifier dataTypeIdThis = this.getDataTypeId(); + if (dataTypeIdThis == null) { + return null; + } else { + DataTypeFactory dataTypeFactory = null; + try { + dataTypeFactory = DataTypeFactory.newInstance(); + if (dataTypeFactory == null) { + return null; + } + } catch (FactoryException ex) { + return null; + } + return (this.dataType = dataTypeFactory.getDataType(dataTypeIdThis)); + } + } + + public AttributeSelector(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public AttributeSelector(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public AttributeSelector() { + } + + public Identifier getContextSelectorId() { + return this.contextSelectorId; + } + + public void setContextSelectorId(Identifier identifier) { + this.contextSelectorId = identifier; + } + + public String getPath() { + return this.path; + } + + public void setPath(String pathIn) { + this.path = pathIn; + } + + @Override + protected boolean validateComponent() { + if (!super.validateComponent()) { + return false; + } else if (this.getPath() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Path"); + return false; + } else { + return true; + } + } + + /** + * If there is a context selector ID, get the attributes from the given <code>RequestAttributes</code> with that + * ID, ensure they are <code>XPathExpression</code>s and return them. + * + * @param requestAttributes + * @return + */ + protected List<XPathExpression> getContextSelectorValues(RequestAttributes requestAttributes) { + Identifier thisContextSelectorId = this.getContextSelectorId(); + if (thisContextSelectorId == null) { + return null; + } + List<XPathExpression> listXPathExpressions = null; + Iterator<Attribute> iterAttributes = requestAttributes.getAttributes(thisContextSelectorId); + if (iterAttributes != null) { + while (iterAttributes.hasNext()) { + Attribute attribute = iterAttributes.next(); + Iterator<AttributeValue<XPathExpressionWrapper>> iterXPathExpressions = attribute.findValues(DataTypes.DT_XPATHEXPRESSION); + if (iterXPathExpressions != null && iterXPathExpressions.hasNext()) { + if (listXPathExpressions == null) { + listXPathExpressions = new ArrayList<XPathExpression>(); + } + listXPathExpressions.add(iterXPathExpressions.next().getValue()); + } + } + } + return listXPathExpressions; + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + /* + * Get the DataType for this AttributeSelector for converting the resulting nodes into AttributeValues + */ + DataType<?> thisDataType = this.getDataType(); + + /* + * Get the Request so we can find the XPathExpression to locate the root node and to find the Content element + * of the requested category. + */ + Request request = evaluationContext.getRequest(); + assert(request != null); + + /* + * Get the RequestAttributes objects for our Category. If none are found, then we abort quickly with either + * an empty or indeterminate result. + */ + Iterator<RequestAttributes> iterRequestAttributes = request.getRequestAttributes(this.getCategory()); + if (iterRequestAttributes == null || !iterRequestAttributes.hasNext()) { + return this.getEmptyResult("No Attributes with Category " + this.getCategory().toString(), null); + } + + /* + * Section 5.30 of the XACML 3.0 specification is a little vague about how to use the + * ContextSelectorId in the face of having multiple Attributes elements with the same CategoryId. My interpretation + * is that each is distinct, so we look for an attribute matching the ContextSelectorId in each matching Attributes element + * and use that to search the Content in that particular Attributes element. If either an Attribute matching the context selector id + * is not found or there is no Content, then that particular Attributes element is skipped. + */ + Bag bagAttributeValues = new Bag(); + StdStatus statusFirstError = null; + while (iterRequestAttributes.hasNext()) { + RequestAttributes requestAttributes = iterRequestAttributes.next(); + + /* + * See if we have a Content element to query. + */ + Node nodeContentRoot = requestAttributes.getContentRoot(); + if (nodeContentRoot != null) { + List<Node> listNodesToQuery = new ArrayList<Node>(); + List<XPathExpression> listXPathExpressions = this.getContextSelectorValues(requestAttributes); + if (listXPathExpressions == null) { + listNodesToQuery.add(nodeContentRoot); + } else { + Iterator<XPathExpression> iterXPathExpressions = listXPathExpressions.iterator(); + while (iterXPathExpressions.hasNext()) { + XPathExpression xpathExpression = iterXPathExpressions.next(); + Node nodeContent = requestAttributes.getContentNodeByXpathExpression(xpathExpression); + if (nodeContent != null) { + listNodesToQuery.add(nodeContent); + } + } + } + + /* + * If there are any nodes to query, do so now and add the results + */ + if (listNodesToQuery.size() > 0) { + for (Node nodeToQuery : listNodesToQuery) { + NodeList nodeList = null; + try { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.setNamespaceContext(new NodeNamespaceContext(nodeToQuery.getOwnerDocument())); + XPathExpression xPathExpression = xPath.compile(this.getPath()); + Node nodeToQueryDocumentRoot = null; + try { + nodeToQueryDocumentRoot = DOMUtil.getDirectDocumentChild(nodeToQuery); + } catch (DOMStructureException ex) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Exception processing context node: " + ex.getMessage())); + } + nodeList = (NodeList)xPathExpression.evaluate(nodeToQueryDocumentRoot, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + if (statusFirstError == null) { + statusFirstError = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "XPathExpressionException: " + ex.getMessage()); + } + } + if (nodeList != null && nodeList.getLength() > 0) { + for (int i = 0 ; i < nodeList.getLength() ; i++) { + AttributeValue<?> attributeValueNode = null; + try { + attributeValueNode = thisDataType.createAttributeValue(nodeList.item(i)); + } catch (DataTypeException ex) { + if (statusFirstError == null) { + statusFirstError = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()); + } + } + if (attributeValueNode != null) { + bagAttributeValues.add(attributeValueNode); + } else if (statusFirstError == null) { + statusFirstError = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Unable to convert node to " + this.getDataTypeId().toString()); + } + } + } + } + } + } + + } + + if (bagAttributeValues.size() == 0) { + if (statusFirstError == null) { + return this.getEmptyResult("No Content found", null); + } else { + return ExpressionResult.newError(statusFirstError); + } + } else { + return ExpressionResult.newBag(bagAttributeValues); + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + Object objectToDump; + if ((objectToDump = this.getContextSelectorId()) != null) { + stringBuilder.append(",contextSelectorId="); + stringBuilder.append(objectToDump.toString()); + } + if ((objectToDump = this.getPath()) != null) { + stringBuilder.append(",path="); + stringBuilder.append((String)objectToDump); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java new file mode 100755 index 0000000..73cf5b8 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java
@@ -0,0 +1,89 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.expressions; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.policy.Expression; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; + +/** + * AttributeValueExpression extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to represent XACML + * AttributeValue elements in an Expression context. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class AttributeValueExpression extends Expression { + private AttributeValue<?> attributeValue; + + public AttributeValueExpression(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public AttributeValueExpression(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public AttributeValueExpression() { + } + + public AttributeValueExpression(AttributeValue<?> attributeValueIn) { + this.attributeValue = attributeValueIn; + } + + public AttributeValue<?> getAttributeValue() { + return this.attributeValue; + } + + public void setAttributeValue(AttributeValue<?> attributeValueIn) { + this.attributeValue = attributeValueIn; + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + return ExpressionResult.newSingle(this.getAttributeValue()); + } + + @Override + protected boolean validateComponent() { + if (this.getAttributeValue() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeValue"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + Object objectToDump; + if ((objectToDump = this.getAttributeValue()) != null) { + stringBuilder.append("attributeValue="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java new file mode 100755 index 0000000..16cf506 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java
@@ -0,0 +1,105 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.expressions; + +import java.net.URI; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.policy.Expression; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; + +/** + * Function extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML Function element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class Function extends Expression { + private Identifier functionId; + private AttributeValue<URI> attributeValue; + private ExpressionResult expressionResultOk; + + protected ExpressionResult getExpressionResultOk() { + if (this.expressionResultOk == null) { + this.expressionResultOk = ExpressionResult.newSingle(this.getAttributeValue()); + } + return this.expressionResultOk; + } + + public Function(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public Function(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public Function() { + } + + public Function(Identifier functionIdIn) { + this.functionId = functionIdIn; + } + + public Identifier getFunctionId() { + return this.functionId; + } + + public void setFunctionId(Identifier identifier) { + this.functionId = identifier; + this.attributeValue = null; + this.expressionResultOk = null; + } + + public AttributeValue<URI> getAttributeValue() { + if (this.attributeValue == null) { + Identifier thisFunctionId = this.getFunctionId(); + if (thisFunctionId != null) { + try { + this.attributeValue = DataTypes.DT_ANYURI.createAttributeValue(thisFunctionId); + } catch (DataTypeException ex) { + this.attributeValue = null; + } + } + } + return this.attributeValue; + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } else { + return this.getExpressionResultOk(); + } + } + + @Override + protected boolean validateComponent() { + if (this.getFunctionId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FunctionId"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java new file mode 100755 index 0000000..be322e9 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java
@@ -0,0 +1,149 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.policy.expressions; + +import com.att.research.xacml.api.StatusCode; +import com.att.research.xacml.api.trace.Traceable; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.trace.StdTraceEvent; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.policy.Expression; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.PolicyDefaults; +import com.att.research.xacmlatt.pdp.policy.VariableDefinition; + +/** + * VariableReference extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML VariableReference + * element. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class VariableReference extends Expression implements Traceable { + private static final ExpressionResult ER_SE_NO_EXPRESSION = ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression for VariableDefinition")); + + private Policy policy; + private String variableId; + private VariableDefinition variableDefinition; + + protected VariableDefinition getVariableDefinition() { + if (this.variableDefinition == null) { + Policy thisPolicy = this.getPolicy(); + if (thisPolicy != null) { + String thisVariableId = this.getVariableId(); + if (thisVariableId != null) { + this.variableDefinition = thisPolicy.getVariableDefinition(thisVariableId); + } + } + } + return this.variableDefinition; + } + + public VariableReference(StatusCode statusCodeIn, String statusMessageIn) { + super(statusCodeIn, statusMessageIn); + } + + public VariableReference(StatusCode statusCodeIn) { + super(statusCodeIn); + } + + public VariableReference() { + } + + public VariableReference(Policy policyIn, String variableIdIn) { + this.policy = policyIn; + this.variableId = variableIdIn; + } + + public Policy getPolicy() { + return this.policy; + } + + public void setPolicy(Policy policyIn) { + this.policy = policyIn; + } + + public String getVariableId() { + return this.variableId; + } + + public void setVariableId(String variableIdIn) { + this.variableId = variableIdIn; + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException { + if (!this.validate()) { + return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage())); + } + + VariableDefinition variableDefinition = this.getVariableDefinition(); + if (variableDefinition == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No VariableDefinition found for \"" + this.getVariableId() + "\"")); + } + Expression expression = variableDefinition.getExpression(); + if (expression == null) { + return ER_SE_NO_EXPRESSION; + } + + ExpressionResult result = expression.evaluate(evaluationContext, policyDefaults); + + if (evaluationContext.isTracing()) { + evaluationContext.trace(new StdTraceEvent<ExpressionResult>("Variable", this, result)); + } + + return result; + } + + @Override + protected boolean validateComponent() { + if (this.getVariableId() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing VariableId"); + return false; + } else if (this.getPolicy() == null) { + this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "VariableReference not in a Policy"); + return false; + } else { + this.setStatus(StdStatusCode.STATUS_CODE_OK, null); + return true; + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + stringBuilder.append("super="); + stringBuilder.append(super.toString()); + + String stringToDump; + if ((stringToDump = this.getVariableId()) != null) { + stringBuilder.append(",variableId="); + stringBuilder.append(stringToDump); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + + @Override + public String getTraceId() { + return this.variableId; + } + + @Override + public Traceable getCause() { + return this.policy; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java new file mode 100755 index 0000000..0abd0ec --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java
@@ -0,0 +1,20 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.policy.expressions; + +/** + * com.att.research.xacmlatt.pdp.policy.expressions contains class definitions that represent specific XACML elements sub-typed from + * the Expression element. + * + * @author car + * @version $Revision: 1.1 $ + */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java new file mode 100755 index 0000000..bb4a5ba --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java
@@ -0,0 +1,20 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.policy; + +/** + * com.att.research.xacmlatt.pdp.policy contains class definitions that represent a XACML 3.0 Policy such that it can be + * used to implement the {@link com.att.research.xacml.pdp.PDPEngine} <code>decide</code> method. + * + * @author car + * @version $Revision: 1.1 $ + */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java new file mode 100755 index 0000000..9312e31 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java
@@ -0,0 +1,89 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; +import com.att.research.xacmlatt.pdp.policy.Rule; + +/** + * StdCombiningAlgorithmFactory extends {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory} to implement + * a mapping from {@link com.att.research.xacml.api.Identifier}s to + * the standard {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} implementations. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class StdCombiningAlgorithmFactory extends CombiningAlgorithmFactory { + private static Map<Identifier,CombiningAlgorithm<Rule>> mapRuleCombiningAlgorithms + = new HashMap<Identifier,CombiningAlgorithm<Rule>>(); + private static Map<Identifier,CombiningAlgorithm<PolicySetChild>> mapPolicyCombiningAlgorithms + = new HashMap<Identifier,CombiningAlgorithm<PolicySetChild>>(); + private static boolean needInit = true; + + protected static void registerRuleCombiningAlgorithm(CombiningAlgorithm<Rule> ruleCombiningAlgorithm) { + mapRuleCombiningAlgorithms.put(ruleCombiningAlgorithm.getId(), ruleCombiningAlgorithm); + } + + protected static void registerPolicyCombiningAlgorithm(CombiningAlgorithm<PolicySetChild> policyCombiningAlgorithm) { + mapPolicyCombiningAlgorithms.put(policyCombiningAlgorithm.getId(), policyCombiningAlgorithm); + } + + @SuppressWarnings("unchecked") + private static void initMap() { + if (needInit) { + synchronized(mapRuleCombiningAlgorithms) { + if (needInit) { + needInit = false; + Field[] declaredFields = StdCombiningAlgorithms.class.getFields(); + for (Field field : declaredFields) { + if (Modifier.isStatic(field.getModifiers()) && + Modifier.isPublic(field.getModifiers()) && + field.getName().startsWith(StdCombiningAlgorithms.PREFIX_CA) && + CombiningAlgorithm.class.isAssignableFrom(field.getType()) + ) { + try { + if (field.getName().startsWith(StdCombiningAlgorithms.PREFIX_RULE)) { + registerRuleCombiningAlgorithm((CombiningAlgorithm<Rule>)field.get(null)); + } else if (field.getName().startsWith(StdCombiningAlgorithms.PREFIX_POLICY)) { + registerPolicyCombiningAlgorithm((CombiningAlgorithm<PolicySetChild>)field.get(null)); + } + } catch (IllegalAccessException ex) { + + } + } + } + } + } + } + } + + public StdCombiningAlgorithmFactory() { + initMap(); + } + + @Override + public CombiningAlgorithm<Rule> getRuleCombiningAlgorithm(Identifier combiningAlgorithmId) { + return mapRuleCombiningAlgorithms.get(combiningAlgorithmId); + } + + @Override + public CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm(Identifier combiningAlgorithmId) { + return mapPolicyCombiningAlgorithms.get(combiningAlgorithmId); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java new file mode 100755 index 0000000..450c1f2 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java
@@ -0,0 +1,125 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import com.att.research.xacml.api.XACML1; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; +import com.att.research.xacmlatt.pdp.policy.Rule; +import com.att.research.xacmlatt.pdp.std.combiners.CombinedPermitOverrides; +import com.att.research.xacmlatt.pdp.std.combiners.DenyOverrides; +import com.att.research.xacmlatt.pdp.std.combiners.DenyUnlessPermit; +import com.att.research.xacmlatt.pdp.std.combiners.FirstApplicable; +import com.att.research.xacmlatt.pdp.std.combiners.LegacyDenyOverridesPolicy; +import com.att.research.xacmlatt.pdp.std.combiners.LegacyDenyOverridesRule; +import com.att.research.xacmlatt.pdp.std.combiners.LegacyPermitOverridesPolicy; +import com.att.research.xacmlatt.pdp.std.combiners.LegacyPermitOverridesRule; +import com.att.research.xacmlatt.pdp.std.combiners.OnlyOneApplicable; +import com.att.research.xacmlatt.pdp.std.combiners.PermitOverrides; +import com.att.research.xacmlatt.pdp.std.combiners.PermitUnlessDeny; +import com.att.research.xacmlatt.pdp.util.ATTPDPProperties; + +/** + * StdCombiningAlgorithms contains single instances of each of the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} + * implementations in the {@link com.att.research.xacmlatt.pdp.std.combiners} package. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class StdCombiningAlgorithms { + + protected StdCombiningAlgorithms() { + } + + public static final String PREFIX_CA = "CA_"; + public static final String PREFIX_RULE = PREFIX_CA + "RULE_"; + public static final String PREFIX_POLICY = PREFIX_CA + "POLICY_"; + + // C.2 Deny-overrides + public static final CombiningAlgorithm<Rule> CA_RULE_DENY_OVERRIDES + = new DenyOverrides<Rule>(XACML3.ID_RULE_DENY_OVERRIDES); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_DENY_OVERRIDES + = new DenyOverrides<PolicySetChild>(XACML3.ID_POLICY_DENY_OVERRIDES); + + // C.3 Ordered-deny-overrides + public static final CombiningAlgorithm<Rule> CA_RULE_ORDERED_DENY_OVERRIDES + = new DenyOverrides<Rule>(XACML3.ID_RULE_ORDERED_DENY_OVERRIDES); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ORDERED_DENY_OVERRIDES + = new DenyOverrides<PolicySetChild>(XACML3.ID_POLICY_ORDERED_DENY_OVERRIDES); + + // C.4 Permit-overrides + public static final CombiningAlgorithm<Rule> CA_RULE_PERMIT_OVERRIDES + = new PermitOverrides<Rule>(XACML3.ID_RULE_PERMIT_OVERRIDES); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_PERMIT_OVERRIDES + = new PermitOverrides<PolicySetChild>(XACML3.ID_POLICY_PERMIT_OVERRIDES); + + // C.5 Ordered-permit-overrides + public static final CombiningAlgorithm<Rule> CA_RULE_ORDERED_PERMIT_OVERRIDES + = new PermitOverrides<Rule>(XACML3.ID_RULE_ORDERED_PERMIT_OVERRIDES); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ORDERED_PERMIT_OVERRIDES + = new PermitOverrides<PolicySetChild>(XACML3.ID_POLICY_ORDERED_PERMIT_OVERRIDES); + + // C.6 Deny-unless-permit + public static final CombiningAlgorithm<Rule> CA_RULE_DENY_UNLESS_PERMIT + = new DenyUnlessPermit<Rule>(XACML3.ID_RULE_DENY_UNLESS_PERMIT); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_DENY_UNLESS_PERMIT + = new DenyUnlessPermit<PolicySetChild>(XACML3.ID_POLICY_DENY_UNLESS_PERMIT); + + // C.7 Permit-unles-deny + public static final CombiningAlgorithm<Rule> CA_RULE_PERMIT_UNLESS_DENY + = new PermitUnlessDeny<Rule>(XACML3.ID_RULE_PERMIT_UNLESS_DENY); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_PERMIT_UNLESS_DENY + = new PermitUnlessDeny<PolicySetChild>(XACML3.ID_POLICY_PERMIT_UNLESS_DENY); + + // C.8 First-applicable + public static final CombiningAlgorithm<Rule> CA_RULE_FIRST_APPLICABLE + = new FirstApplicable<Rule>(XACML1.ID_RULE_FIRST_APPLICABLE); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_FIRST_APPLICABLE + = new FirstApplicable<PolicySetChild>(XACML1.ID_POLICY_FIRST_APPLICABLE); + + // C.9 Only-one-applicable + //public static final CombiningAlgorithm<Rule> CA_RULE_ONLY_ONE_APPLICABLE + // = new OnlyOneApplicable<Rule>(XACML1.ID_RULE_ONLY_ONE_APPLICABLE); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ONLY_ONE_APPLICABLE + = new OnlyOneApplicable(XACML1.ID_POLICY_ONLY_ONE_APPLICABLE); + + // C.10 Legacy Deny-overrides + public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_DENY_OVERRIDES + = new LegacyDenyOverridesRule(XACML1.ID_RULE_DENY_OVERRIDES); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_DENY_OVERRIDES + = new LegacyDenyOverridesPolicy(XACML1.ID_POLICY_DENY_OVERRIDES); + + // C.11 Legacy Ordered-deny-overrides + public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_ORDERED_DENY_OVERRIDES + = new LegacyDenyOverridesRule(XACML1.ID_RULE_ORDERED_DENY_OVERRIDES); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_ORDERED_DENY_OVERRIDES + = new LegacyDenyOverridesPolicy(XACML1.ID_POLICY_ORDERED_DENY_OVERRIDES); + + // C.12 Legacy Permit-overrides + public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_PERMIT_OVERRIDES + = new LegacyPermitOverridesRule(XACML1.ID_RULE_PERMIT_OVERRIDES); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_PERMIT_OVERRIDES + = new LegacyPermitOverridesPolicy(XACML1.ID_POLICY_PERMIT_OVERRIDES); + + // C.13 Legacy Ordered-permit-overrides + public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_ORDERED_PERMIT_OVERRIDES + = new LegacyPermitOverridesRule(XACML1.ID_RULE_ORDERED_PERMIT_OVERRIDES); + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_ORDERED_PERMIT_OVERRIDES + = new LegacyPermitOverridesPolicy(XACML1.ID_POLICY_ORDERED_PERMIT_OVERRIDES); + + // + // Custom AT&T Policy Combing Algorithms + // + public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_COMBINED_PERMIT_OVERRIDES + = new CombinedPermitOverrides<PolicySetChild>(ATTPDPProperties.ID_POLICY_COMBINEDPERMITOVERRIDES); + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java new file mode 100755 index 0000000..7266227 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java
@@ -0,0 +1,150 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import com.att.research.xacml.api.IdReferenceMatch; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.pip.*; +import com.att.research.xacml.api.trace.TraceEngine; +import com.att.research.xacml.api.trace.TraceEngineFactory; +import com.att.research.xacml.api.trace.TraceEvent; +import com.att.research.xacml.std.pip.engines.RequestEngine; +import com.att.research.xacml.std.pip.finders.RequestFinder; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.*; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Collection; +import java.util.Properties; + +/** + * StdEvaluationContext implements the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} interface using + * default factories to load the XACML policies, and get the PIP engines. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class StdEvaluationContext implements EvaluationContext { + private Log logger = LogFactory.getLog(this.getClass()); + private Properties properties; + private Request request; + private RequestFinder requestFinder; + private PolicyFinder policyFinder; + private TraceEngine traceEngine; + + /** + * Creates a new <code>StdEvaluationContext</code> with the given {@link com.att.research.xacml.api.Request} and + * {@link com.att.research.xacmlatt.pdp.policy.PolicyDef}. + * + * @param requestIn the <code>Request</code> + * @param policyDef the <code>PolicyDef</code> + */ + public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder, TraceEngine traceEngineIn, Properties properties) { + this.properties = properties; + this.request = requestIn; + this.policyFinder = policyFinderIn; + if (traceEngineIn != null) { + this.traceEngine = traceEngineIn; + } else { + try { + if (this.properties == null) { + this.traceEngine = TraceEngineFactory.newInstance().getTraceEngine(); + } else { + this.traceEngine = TraceEngineFactory.newInstance(this.properties).getTraceEngine(this.properties); + } + } catch (FactoryException ex) { + this.logger.error("FactoryException creating TraceEngine: " + ex.toString(), ex); + } + } + + if (pipFinder == null) { + this.requestFinder = new RequestFinder(null, new RequestEngine(requestIn)); + } else { + if (pipFinder instanceof RequestFinder) { + this.requestFinder = (RequestFinder)pipFinder; + } else { + this.requestFinder = new RequestFinder(pipFinder, new RequestEngine(requestIn)); + } + } + } + + public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder, TraceEngine traceEngineIn) { + this(requestIn, policyFinderIn, pipFinder, traceEngineIn, null); + } + + public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder) { + this(requestIn, policyFinderIn, pipFinder, null); + } + + @Override + public Request getRequest() { + return this.request; + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest) throws PIPException { + return this.requestFinder.getAttributes(pipRequest, null); + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + return this.requestFinder.getAttributes(pipRequest, exclude); + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderRoot) throws PIPException { + return this.requestFinder.getAttributes(pipRequest, exclude, pipFinderRoot); + } + + @Override + public PolicyFinderResult<PolicyDef> getRootPolicyDef() { + return this.policyFinder.getRootPolicyDef(this); + } + + @Override + public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch) { + return this.policyFinder.getPolicy(idReferenceMatch); + } + + @Override + public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch) { + return this.policyFinder.getPolicySet(idReferenceMatch); + } + + @Override + public void trace(TraceEvent<?> traceEvent) { + if (this.traceEngine != null) { + this.traceEngine.trace(traceEvent); + } + } + + @Override + public boolean isTracing() { + return (this.traceEngine == null ? false : this.traceEngine.isTracing()); + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + return this.requestFinder.getMatchingAttributes(pipRequest, exclude); + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return this.requestFinder.getMatchingAttributes(pipRequest, exclude, pipFinderParent); + } + + @Override + public Collection<PIPEngine> getPIPEngines() { + return this.requestFinder.getPIPEngines(); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java new file mode 100755 index 0000000..ea68162 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java
@@ -0,0 +1,163 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPFinderFactory; +import com.att.research.xacml.api.trace.TraceEngine; +import com.att.research.xacml.api.trace.TraceEngineFactory; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory; +import com.att.research.xacmlatt.pdp.policy.PolicyFinder; +import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory; + +/** + * StdEvaluationContextFactory extends {@link com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory} to implement + * the <code>getEvaluationContext</code> method with a standard {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class StdEvaluationContextFactory extends EvaluationContextFactory { + private Log logger = LogFactory.getLog(this.getClass()); + private PolicyFinder policyFinder; + private PIPFinder pipFinder; + private TraceEngine traceEngine; + + /** + * Should this properties file be passed onward when instantiating the PolicyFinder + * and the PIPFinder? + * + * If yes, then we are assuming that the given properties were not just meant to + * configure the evaluation context, but all the other engines that get created. + * + * If no, then we are assuming the given properties were only meant for the evaluation + * context. But this implementation as of 7/14 does not even need the properties for + * configuring itseof. + * + * The problem is, the caller does not have the ability to instantiate the PIPFinder + * and PolicyFinder engines. This is done internally by the evaluation context. So how + * can they have the ability to customize PIP/Policy factories with their own properties + * object if the properties file isn't passed on? + * + * Thus, this class will pass on the properties file if given in the constructor. + * + */ + protected Properties properties = null; + + protected PolicyFinder getPolicyFinder() { + if (this.policyFinder == null) { + synchronized(this) { + if (this.policyFinder == null) { + try { + if (this.properties == null) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("getting Policy finder using default properties"); + } + PolicyFinderFactory policyFinderFactory = PolicyFinderFactory.newInstance(); + this.policyFinder = policyFinderFactory.getPolicyFinder(); + } else { + if (this.logger.isDebugEnabled()) { + this.logger.debug("getting Policy finder using properties: " + this.properties); + } + PolicyFinderFactory policyFinderFactory = PolicyFinderFactory.newInstance(this.properties); + this.policyFinder = policyFinderFactory.getPolicyFinder(this.properties); + } + } catch (Exception ex) { + this.logger.error("Exception getting PolicyFinder: " + ex.getMessage(), ex); + } + } + } + } + return this.policyFinder; + } + + protected PIPFinder getPIPFinder() { + if (this.pipFinder == null) { + synchronized(this) { + if (this.pipFinder == null) { + try { + if (this.properties == null) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("getting PIP finder using default properties"); + } + PIPFinderFactory pipFinderFactory = PIPFinderFactory.newInstance(); + this.pipFinder = pipFinderFactory.getFinder(); + } else { + if (this.logger.isDebugEnabled()) { + this.logger.debug("getting PIP finder using properties: " + this.properties); + } + PIPFinderFactory pipFinderFactory = PIPFinderFactory.newInstance(this.properties); + this.pipFinder = pipFinderFactory.getFinder(this.properties); + } + } catch (Exception ex) { + this.logger.error("Exception getting PIPFinder: " + ex.toString(), ex); + } + } + } + } + return this.pipFinder; + } + + protected TraceEngine getTraceEngine() { + if (this.traceEngine == null) { + synchronized(this) { + if (this.traceEngine == null) { + try { + if (this.properties == null) { + TraceEngineFactory traceEngineFactory = TraceEngineFactory.newInstance(); + this.traceEngine = traceEngineFactory.getTraceEngine(); + } else { + TraceEngineFactory traceEngineFactory = TraceEngineFactory.newInstance(this.properties); + this.traceEngine = traceEngineFactory.getTraceEngine(this.properties); + } + } catch (Exception ex) { + this.logger.error("Exception getting TraceEngine: " + ex.toString(), ex); + } + } + } + } + return this.traceEngine; + } + + public StdEvaluationContextFactory() { + } + + public StdEvaluationContextFactory(Properties properties) { + this.properties = properties; + } + + @Override + public EvaluationContext getEvaluationContext(Request request) { + if (this.properties == null) { + return new StdEvaluationContext(request, this.getPolicyFinder(), this.getPIPFinder(), this.getTraceEngine()); + } else { + return new StdEvaluationContext(request, this.getPolicyFinder(), this.getPIPFinder(), this.getTraceEngine(), this.properties); + } + } + + @Override + public void setPolicyFinder(PolicyFinder policyFinderIn) { + this.policyFinder = policyFinderIn; + } + + @Override + public void setPIPFinder(PIPFinder pipFinderIn) { + this.pipFinder = pipFinderIn; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java new file mode 100755 index 0000000..04f8001 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java
@@ -0,0 +1,70 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory; + +/** + * StdFunctionDefinitionFactory is the default {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory} implementation + * used if no other <code>FunctionDefinitionFactory</code> implementation is supplied. It contains all of the standard XACML 3.0 + * functions. + * + * @author car + * @version $Revision: 1.2 $ + */ +public class StdFunctionDefinitionFactory extends FunctionDefinitionFactory { + private static Map<Identifier,FunctionDefinition> mapFunctionDefinitions = new HashMap<Identifier,FunctionDefinition>(); + private static boolean needMapInit = true; + + private static void register(FunctionDefinition functionDefinition) { + mapFunctionDefinitions.put(functionDefinition.getId(), functionDefinition); + } + + private static void initMap() { + if (needMapInit) { + synchronized(mapFunctionDefinitions) { + if (needMapInit) { + needMapInit = false; + Field[] declaredFields = StdFunctions.class.getDeclaredFields(); + for (Field field : declaredFields) { + if (Modifier.isStatic(field.getModifiers()) && + field.getName().startsWith(StdFunctions.FD_PREFIX) && + FunctionDefinition.class.isAssignableFrom(field.getType()) && + Modifier.isPublic(field.getModifiers()) + ) { + try { + register((FunctionDefinition)(field.get(null))); + } catch (IllegalAccessException ex) { + + } + } + } + } + } + } + } + + public StdFunctionDefinitionFactory() { + initMap(); + } + + @Override + public FunctionDefinition getFunctionDefinition(Identifier functionId) { + return mapFunctionDefinitions.get(functionId); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java new file mode 100755 index 0000000..b46dab1 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java
@@ -0,0 +1,479 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import java.math.BigInteger; +import java.net.URI; + +import javax.security.auth.x500.X500Principal; + +import com.att.research.xacml.api.XACML1; +import com.att.research.xacml.api.XACML2; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.Base64Binary; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.HexBinary; +import com.att.research.xacml.std.datatypes.IPAddress; +import com.att.research.xacml.std.datatypes.ISO8601Date; +import com.att.research.xacml.std.datatypes.ISO8601DateTime; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacml.std.datatypes.RFC2396DomainName; +import com.att.research.xacml.std.datatypes.RFC822Name; +import com.att.research.xacml.std.datatypes.XPathDayTimeDuration; +import com.att.research.xacml.std.datatypes.XPathYearMonthDuration; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionAccessPermitted; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionArithmetic; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBag; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagIsIn; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAndOnly; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagSize; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionComparison; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionDateTimeArithmetic; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionEquality; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHigherOrderBag; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionLogical; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionNumberTypeConversion; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionRFC822NameMatch; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionRegexpMatch; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSet; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringConversion; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringEqualIgnoreCase; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringNormalize; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionTimeInRange; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionURIStringConcatenate; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionX500NameMatch; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionXPath; + +/** + * StdFunctions contains the {@link com.att.research.xacml.api.Identifier} values for the standard XACML functions. + * + * @author car + * @version $Revision: 1.2 $ + */ +@SuppressWarnings("deprecation") +public class StdFunctions { + protected StdFunctions() { + } + + public static final String FD_PREFIX = "FD_"; + + /* + * A.3.1 Equality predicates + */ + + public static final FunctionDefinition FD_STRING_EQUAL = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_EQUAL_IGNORE_CASE = new FunctionDefinitionStringEqualIgnoreCase(XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE); + public static final FunctionDefinition FD_BOOLEAN_EQUAL = new FunctionDefinitionEquality<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_EQUAL, DataTypes.DT_BOOLEAN); + public static final FunctionDefinition FD_INTEGER_EQUAL = new FunctionDefinitionEquality<BigInteger>(XACML3.ID_FUNCTION_INTEGER_EQUAL, DataTypes.DT_INTEGER); + public static final FunctionDefinition FD_DOUBLE_EQUAL = new FunctionDefinitionEquality<Double>(XACML3.ID_FUNCTION_DOUBLE_EQUAL, DataTypes.DT_DOUBLE); + public static final FunctionDefinition FD_DATE_EQUAL = new FunctionDefinitionEquality<ISO8601Date>(XACML3.ID_FUNCTION_DATE_EQUAL, DataTypes.DT_DATE); + public static final FunctionDefinition FD_TIME_EQUAL = new FunctionDefinitionEquality<ISO8601Time>(XACML3.ID_FUNCTION_TIME_EQUAL, DataTypes.DT_TIME); + public static final FunctionDefinition FD_DATETIME_EQUAL = new FunctionDefinitionEquality<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_EQUAL, DataTypes.DT_DATETIME); + + // only difference between R3 and older (R1) versions of durations seem to be the identifiers, so send calls to the same place in either case + public static final FunctionDefinition FD_DAYTIMEDURATION_EQUAL_VERSION1 = new FunctionDefinitionEquality<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_EQUAL, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_DAYTIMEDURATION_EQUAL = new FunctionDefinitionEquality<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_EQUAL_VERSION1 = new FunctionDefinitionEquality<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_EQUAL, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_EQUAL = new FunctionDefinitionEquality<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL, DataTypes.DT_YEARMONTHDURATION); + + // continue on with latest versions + public static final FunctionDefinition FD_ANYURI_EQUAL = new FunctionDefinitionEquality<URI>(XACML3.ID_FUNCTION_ANYURI_EQUAL, DataTypes.DT_ANYURI); + public static final FunctionDefinition FD_X500NAME_EQUAL = new FunctionDefinitionEquality<X500Principal>(XACML3.ID_FUNCTION_X500NAME_EQUAL, DataTypes.DT_X500NAME); + public static final FunctionDefinition FD_RFC822NAME_EQUAL = new FunctionDefinitionEquality<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_EQUAL, DataTypes.DT_RFC822NAME); + public static final FunctionDefinition FD_HEXBINARY_EQUAL = new FunctionDefinitionEquality<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_EQUAL, DataTypes.DT_HEXBINARY); + public static final FunctionDefinition FD_BASE64BINARY_EQUAL = new FunctionDefinitionEquality<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_EQUAL, DataTypes.DT_BASE64BINARY); + + + + + /* + * Arithmetic Functions (See A.3.2) + */ + + public static final FunctionDefinition FD_INTEGER_ADD = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ADD, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.ADD, 2); + public static final FunctionDefinition FD_DOUBLE_ADD = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_ADD, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ADD, 2); + public static final FunctionDefinition FD_INTEGER_SUBTRACT = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_SUBTRACT, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.SUBTRACT, 2); + public static final FunctionDefinition FD_DOUBLE_SUBTRACT = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_SUBTRACT, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.SUBTRACT, 2); + public static final FunctionDefinition FD_INTEGER_MULTIPLY = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_MULTIPLY, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.MULTIPLY, 2); + public static final FunctionDefinition FD_DOUBLE_MULTIPLY = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_MULTIPLY, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.MULTIPLY, 2); + public static final FunctionDefinition FD_INTEGER_DIVIDE = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_DIVIDE, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.DIVIDE, 2); + public static final FunctionDefinition FD_DOUBLE_DIVIDE = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_DIVIDE, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.DIVIDE, 2); + public static final FunctionDefinition FD_INTEGER_MOD = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_MOD, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.MOD, 2); + public static final FunctionDefinition FD_INTEGER_ABS = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ABS, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.ABS, 1); + public static final FunctionDefinition FD_DOUBLE_ABS = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_ABS, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ABS, 1); + public static final FunctionDefinition FD_ROUND = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_ROUND, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ROUND, 1); + public static final FunctionDefinition FD_FLOOR = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_FLOOR, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.FLOOR, 1); + + + + + /* + * String Conversion Functions (See A.3.3) + */ + public static final FunctionDefinition FD_STRING_NORMALIZE_SPACE = new FunctionDefinitionStringNormalize(XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE, FunctionDefinitionStringNormalize.OPERATION.SPACE); + public static final FunctionDefinition FD_STRING_NORMALIZE_TO_LOWER_CASE = new FunctionDefinitionStringNormalize(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE, FunctionDefinitionStringNormalize.OPERATION.LOWER_CASE); + + /* + * Numeric Data-Type Conversion Functions (See A.3.4) + */ + public static final FunctionDefinition FD_DOUBLE_TO_INTEGER = new FunctionDefinitionNumberTypeConversion<BigInteger,Double>(XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER, DataTypes.DT_INTEGER, DataTypes.DT_DOUBLE); + public static final FunctionDefinition FD_INTEGER_TO_DOUBLE = new FunctionDefinitionNumberTypeConversion<Double,BigInteger>(XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE, DataTypes.DT_DOUBLE, DataTypes.DT_INTEGER); + + + /* + * Logical Functions (See A.3.5) + */ + public static final FunctionDefinition FD_OR = new FunctionDefinitionLogical(XACML3.ID_FUNCTION_OR, FunctionDefinitionLogical.OPERATION.OR); + public static final FunctionDefinition FD_AND = new FunctionDefinitionLogical(XACML3.ID_FUNCTION_AND, FunctionDefinitionLogical.OPERATION.AND); + public static final FunctionDefinition FD_N_OF = new FunctionDefinitionLogical(XACML3.ID_FUNCTION_N_OF, FunctionDefinitionLogical.OPERATION.N_OF); + public static final FunctionDefinition FD_NOT = new FunctionDefinitionLogical(XACML3.ID_FUNCTION_NOT, FunctionDefinitionLogical.OPERATION.NOT); + + + /* + * Numeric Comparison Functions (See A.3.6 of xacml-3.0-core-spec-os-en.doc) + */ + public static final FunctionDefinition FD_INTEGER_GREATER_THAN = new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.GREATER_THAN); + public static final FunctionDefinition FD_INTEGER_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL); + public static final FunctionDefinition FD_INTEGER_LESS_THAN = new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_LESS_THAN, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.LESS_THAN); + public static final FunctionDefinition FD_INTEGER_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL); + public static final FunctionDefinition FD_DOUBLE_GREATER_THAN = new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.GREATER_THAN); + public static final FunctionDefinition FD_DOUBLE_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL); + public static final FunctionDefinition FD_DOUBLE_LESS_THAN = new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.LESS_THAN); + public static final FunctionDefinition FD_DOUBLE_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL); + + + /* + * Date and Time Arithmetic Functions (See A.3.7) + */ + public static final FunctionDefinition FD_DATETIME_ADD_DAYTIMEDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD); + public static final FunctionDefinition FD_DATETIME_ADD_DAYTIMEDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD); + public static final FunctionDefinition FD_DATETIME_ADD_YEARMONTHDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD); + public static final FunctionDefinition FD_DATETIME_ADD_YEARMONTHDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD); + + public static final FunctionDefinition FD_DATETIME_SUBTRACT_DAYTIMEDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT); + public static final FunctionDefinition FD_DATETIME_SUBTRACT_DAYTIMEDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT); + public static final FunctionDefinition FD_DATETIME_SUBTRACT_YEARMONTHDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT); + public static final FunctionDefinition FD_DATETIME_SUBTRACT_YEARMONTHDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT); + + public static final FunctionDefinition FD_DATE_ADD_YEARMONTHDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD); + public static final FunctionDefinition FD_DATE_ADD_YEARMONTHDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD); + public static final FunctionDefinition FD_DATE_SUBTRACT_YEARMONTHDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT); + public static final FunctionDefinition FD_DATE_SUBTRACT_YEARMONTHDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT); + + + /* + * Non Numeric Comparison Functions (See A.3.8) + */ + public static final FunctionDefinition FD_STRING_GREATER_THAN = new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_GREATER_THAN, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.GREATER_THAN); + public static final FunctionDefinition FD_STRING_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL); + public static final FunctionDefinition FD_STRING_LESS_THAN = new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_LESS_THAN, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.LESS_THAN); + public static final FunctionDefinition FD_STRING_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL); + public static final FunctionDefinition FD_TIME_GREATER_THAN = new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_GREATER_THAN, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN); + public static final FunctionDefinition FD_TIME_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL); + public static final FunctionDefinition FD_TIME_LESS_THAN = new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_LESS_THAN, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.LESS_THAN); + public static final FunctionDefinition FD_TIME_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL); + public static final FunctionDefinition FD_TIME_IN_RANGE = new FunctionDefinitionTimeInRange<ISO8601Time>(XACML3.ID_FUNCTION_TIME_IN_RANGE, DataTypes.DT_TIME); + public static final FunctionDefinition FD_DATE_GREATER_THAN = new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_GREATER_THAN, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.GREATER_THAN); + public static final FunctionDefinition FD_DATE_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL); + public static final FunctionDefinition FD_DATE_LESS_THAN = new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_LESS_THAN, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.LESS_THAN); + public static final FunctionDefinition FD_DATE_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL); + public static final FunctionDefinition FD_DATETIME_GREATER_THAN = new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN); + public static final FunctionDefinition FD_DATETIME_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL); + public static final FunctionDefinition FD_DATETIME_LESS_THAN = new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_LESS_THAN, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.LESS_THAN); + public static final FunctionDefinition FD_DATETIME_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL); + + + + /* + * String functions (See A.3.9 of xacml-3.0-core-spec-os-en.doc) + */ + public static final FunctionDefinition FD_BOOLEAN_FROM_STRING = new FunctionDefinitionStringConversion<Boolean,String>(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_BOOLEAN = new FunctionDefinitionStringConversion<String,Boolean>(XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN, DataTypes.DT_STRING, DataTypes.DT_BOOLEAN); + public static final FunctionDefinition FD_INTEGER_FROM_STRING = new FunctionDefinitionStringConversion<BigInteger,String>(XACML3.ID_FUNCTION_INTEGER_FROM_STRING, DataTypes.DT_INTEGER, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_INTEGER = new FunctionDefinitionStringConversion<String,BigInteger>(XACML3.ID_FUNCTION_STRING_FROM_INTEGER, DataTypes.DT_STRING, DataTypes.DT_INTEGER); + public static final FunctionDefinition FD_DOUBLE_FROM_STRING = new FunctionDefinitionStringConversion<Double,String>(XACML3.ID_FUNCTION_DOUBLE_FROM_STRING, DataTypes.DT_DOUBLE, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_DOUBLE = new FunctionDefinitionStringConversion<String,Double>(XACML3.ID_FUNCTION_STRING_FROM_DOUBLE, DataTypes.DT_STRING, DataTypes.DT_DOUBLE); + public static final FunctionDefinition FD_TIME_FROM_STRING = new FunctionDefinitionStringConversion<ISO8601Time,String>(XACML3.ID_FUNCTION_TIME_FROM_STRING, DataTypes.DT_TIME, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_TIME = new FunctionDefinitionStringConversion<String,ISO8601Time>(XACML3.ID_FUNCTION_STRING_FROM_TIME, DataTypes.DT_STRING, DataTypes.DT_TIME); + public static final FunctionDefinition FD_DATE_FROM_STRING = new FunctionDefinitionStringConversion<ISO8601Date,String>(XACML3.ID_FUNCTION_DATE_FROM_STRING, DataTypes.DT_DATE, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_DATE = new FunctionDefinitionStringConversion<String,ISO8601Date>(XACML3.ID_FUNCTION_STRING_FROM_DATE, DataTypes.DT_STRING, DataTypes.DT_DATE); + public static final FunctionDefinition FD_DATETIME_FROM_STRING = new FunctionDefinitionStringConversion<ISO8601DateTime,String>(XACML3.ID_FUNCTION_DATETIME_FROM_STRING, DataTypes.DT_DATETIME, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_DATETIME = new FunctionDefinitionStringConversion<String,ISO8601DateTime>(XACML3.ID_FUNCTION_STRING_FROM_DATETIME, DataTypes.DT_STRING, DataTypes.DT_DATETIME); + public static final FunctionDefinition FD_ANYURI_FROM_STRING = new FunctionDefinitionStringConversion<URI,String>(XACML3.ID_FUNCTION_ANYURI_FROM_STRING, DataTypes.DT_ANYURI, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_ANYURI = new FunctionDefinitionStringConversion<String,URI>(XACML3.ID_FUNCTION_STRING_FROM_ANYURI, DataTypes.DT_STRING, DataTypes.DT_ANYURI); + public static final FunctionDefinition FD_DAYTIMEDURATION_FROM_STRING = new FunctionDefinitionStringConversion<XPathDayTimeDuration,String>(XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_DAYTIMEDURATION = new FunctionDefinitionStringConversion<String,XPathDayTimeDuration>(XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION, DataTypes.DT_STRING, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_FROM_STRING = new FunctionDefinitionStringConversion<XPathYearMonthDuration,String>(XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_YEARMONTHDURATION = new FunctionDefinitionStringConversion<String,XPathYearMonthDuration>(XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION, DataTypes.DT_STRING, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_X500NAME_FROM_STRING = new FunctionDefinitionStringConversion<X500Principal,String>(XACML3.ID_FUNCTION_X500NAME_FROM_STRING, DataTypes.DT_X500NAME, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_X500NAME = new FunctionDefinitionStringConversion<String,X500Principal>(XACML3.ID_FUNCTION_STRING_FROM_X500NAME, DataTypes.DT_STRING, DataTypes.DT_X500NAME); + public static final FunctionDefinition FD_RFC822NAME_FROM_STRING = new FunctionDefinitionStringConversion<RFC822Name,String>(XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING, DataTypes.DT_RFC822NAME, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_RFC822NAME = new FunctionDefinitionStringConversion<String,RFC822Name>(XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME, DataTypes.DT_STRING, DataTypes.DT_RFC822NAME); + public static final FunctionDefinition FD_IPADDRESS_FROM_STRING = new FunctionDefinitionStringConversion<IPAddress,String>(XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING, DataTypes.DT_IPADDRESS, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_IPADDRESS = new FunctionDefinitionStringConversion<String,IPAddress>(XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS, DataTypes.DT_STRING, DataTypes.DT_IPADDRESS); + public static final FunctionDefinition FD_DNSNAME_FROM_STRING = new FunctionDefinitionStringConversion<RFC2396DomainName,String>(XACML3.ID_FUNCTION_DNSNAME_FROM_STRING, DataTypes.DT_DNSNAME, DataTypes.DT_STRING); + public static final FunctionDefinition FD_STRING_FROM_DNSNAME = new FunctionDefinitionStringConversion<String,RFC2396DomainName>(XACML3.ID_FUNCTION_STRING_FROM_DNSNAME, DataTypes.DT_STRING, DataTypes.DT_DNSNAME); + + // String Functions not converting Strings to/from DataType objects + public static final FunctionDefinition FD_STRING_CONCATENATE = new FunctionDefinitionStringFunctions<String,String>(XACML3.ID_FUNCTION_STRING_CONCATENATE, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.CONCATENATE); + public static final FunctionDefinition FD_STRING_STARTS_WITH = new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_STARTS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.STARTS_WITH); + public static final FunctionDefinition FD_ANYURI_STARTS_WITH = new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_STARTS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.STARTS_WITH); + public static final FunctionDefinition FD_STRING_ENDS_WITH = new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_ENDS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.ENDS_WITH); + public static final FunctionDefinition FD_ANYURI_ENDS_WITH = new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_ENDS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.ENDS_WITH); + public static final FunctionDefinition FD_STRING_CONTAINS = new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_CONTAINS, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.CONTAINS); + public static final FunctionDefinition FD_ANYURI_CONTAINS = new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_CONTAINS, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.CONTAINS); + public static final FunctionDefinition FD_STRING_SUBSTRING = new FunctionDefinitionStringFunctions<String,String>(XACML3.ID_FUNCTION_STRING_SUBSTRING, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.SUBSTRING); + public static final FunctionDefinition FD_ANYURI_SUBSTRING = new FunctionDefinitionStringFunctions<String, URI>(XACML3.ID_FUNCTION_ANYURI_SUBSTRING, DataTypes.DT_STRING, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.SUBSTRING); + + /* + * Bag functions (See A.3.10) + */ + public static final FunctionDefinition FD_STRING_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<String>(XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY, DataTypes.DT_STRING); + public static final FunctionDefinition FD_BOOLEAN_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY, DataTypes.DT_BOOLEAN); + public static final FunctionDefinition FD_INTEGER_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY, DataTypes.DT_INTEGER); + public static final FunctionDefinition FD_DOUBLE_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<Double>(XACML3.ID_FUNCTION_DOUBLE_ONE_AND_ONLY, DataTypes.DT_DOUBLE); + public static final FunctionDefinition FD_TIME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<ISO8601Time>(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY, DataTypes.DT_TIME); + public static final FunctionDefinition FD_DATE_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<ISO8601Date>(XACML3.ID_FUNCTION_DATE_ONE_AND_ONLY, DataTypes.DT_DATE); + public static final FunctionDefinition FD_DATETIME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_ONE_AND_ONLY, DataTypes.DT_DATETIME); + public static final FunctionDefinition FD_ANYURI_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<URI>(XACML3.ID_FUNCTION_ANYURI_ONE_AND_ONLY, DataTypes.DT_ANYURI); + public static final FunctionDefinition FD_HEXBINARY_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_ONE_AND_ONLY, DataTypes.DT_HEXBINARY); + public static final FunctionDefinition FD_BASE64BINARY_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_ONE_AND_ONLY, DataTypes.DT_BASE64BINARY); + public static final FunctionDefinition FD_DAYTIMEDURATION_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_ONE_AND_ONLY, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_DAYTIMEDURATION_ONE_AND_ONLY_VERSION1 = new FunctionDefinitionBagOneAndOnly<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_ONE_AND_ONLY, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_ONE_AND_ONLY, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_ONE_AND_ONLY_VERSION1 = new FunctionDefinitionBagOneAndOnly<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_ONE_AND_ONLY, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_X500NAME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<X500Principal>(XACML3.ID_FUNCTION_X500NAME_ONE_AND_ONLY, DataTypes.DT_X500NAME); + public static final FunctionDefinition FD_RFC822NAME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_ONE_AND_ONLY, DataTypes.DT_RFC822NAME); + public static final FunctionDefinition FD_IPADDRESS_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_ONE_AND_ONLY, DataTypes.DT_IPADDRESS); + public static final FunctionDefinition FD_DNSNAME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_ONE_AND_ONLY, DataTypes.DT_DNSNAME); + + public static final FunctionDefinition FD_STRING_BAG_SIZE = new FunctionDefinitionBagSize<String>(XACML3.ID_FUNCTION_STRING_BAG_SIZE, DataTypes.DT_STRING); + public static final FunctionDefinition FD_BOOLEAN_BAG_SIZE = new FunctionDefinitionBagSize<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_BAG_SIZE, DataTypes.DT_BOOLEAN); + public static final FunctionDefinition FD_INTEGER_BAG_SIZE = new FunctionDefinitionBagSize<BigInteger>(XACML3.ID_FUNCTION_INTEGER_BAG_SIZE, DataTypes.DT_INTEGER); + public static final FunctionDefinition FD_DOUBLE_BAG_SIZE = new FunctionDefinitionBagSize<Double>(XACML3.ID_FUNCTION_DOUBLE_BAG_SIZE, DataTypes.DT_DOUBLE); + public static final FunctionDefinition FD_TIME_BAG_SIZE = new FunctionDefinitionBagSize<ISO8601Time>(XACML3.ID_FUNCTION_TIME_BAG_SIZE, DataTypes.DT_TIME); + public static final FunctionDefinition FD_DATE_BAG_SIZE = new FunctionDefinitionBagSize<ISO8601Date>(XACML3.ID_FUNCTION_DATE_BAG_SIZE, DataTypes.DT_DATE); + public static final FunctionDefinition FD_DATETIME_BAG_SIZE = new FunctionDefinitionBagSize<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_BAG_SIZE, DataTypes.DT_DATETIME); + public static final FunctionDefinition FD_ANYURI_BAG_SIZE = new FunctionDefinitionBagSize<URI>(XACML3.ID_FUNCTION_ANYURI_BAG_SIZE, DataTypes.DT_ANYURI); + public static final FunctionDefinition FD_HEXBINARY_BAG_SIZE = new FunctionDefinitionBagSize<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_BAG_SIZE, DataTypes.DT_HEXBINARY); + public static final FunctionDefinition FD_BASE64BINARY_BAG_SIZE = new FunctionDefinitionBagSize<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_BAG_SIZE, DataTypes.DT_BASE64BINARY); + public static final FunctionDefinition FD_DAYTIMEDURATION_BAG_SIZE = new FunctionDefinitionBagSize<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG_SIZE, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_DAYTIMEDURATION_BAG_SIZE_VERSION1 = new FunctionDefinitionBagSize<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_BAG_SIZE, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_BAG_SIZE = new FunctionDefinitionBagSize<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG_SIZE, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_BAG_SIZE_VERSION1 = new FunctionDefinitionBagSize<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_BAG_SIZE, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_X500NAME_BAG_SIZE = new FunctionDefinitionBagSize<X500Principal>(XACML3.ID_FUNCTION_X500NAME_BAG_SIZE, DataTypes.DT_X500NAME); + public static final FunctionDefinition FD_RFC822NAME_BAG_SIZE = new FunctionDefinitionBagSize<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_BAG_SIZE, DataTypes.DT_RFC822NAME); + public static final FunctionDefinition FD_IPADDRESS_BAG_SIZE = new FunctionDefinitionBagSize<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_BAG_SIZE, DataTypes.DT_IPADDRESS); + public static final FunctionDefinition FD_DNSNAME_BAG_SIZE = new FunctionDefinitionBagSize<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_BAG_SIZE, DataTypes.DT_DNSNAME); + + public static final FunctionDefinition FD_STRING_IS_IN = new FunctionDefinitionBagIsIn<String>(XACML3.ID_FUNCTION_STRING_IS_IN, DataTypes.DT_STRING); + public static final FunctionDefinition FD_BOOLEAN_IS_IN = new FunctionDefinitionBagIsIn<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_IS_IN, DataTypes.DT_BOOLEAN); + public static final FunctionDefinition FD_INTEGER_IS_IN = new FunctionDefinitionBagIsIn<BigInteger>(XACML3.ID_FUNCTION_INTEGER_IS_IN, DataTypes.DT_INTEGER); + public static final FunctionDefinition FD_DOUBLE_IS_IN = new FunctionDefinitionBagIsIn<Double>(XACML3.ID_FUNCTION_DOUBLE_IS_IN, DataTypes.DT_DOUBLE); + public static final FunctionDefinition FD_TIME_IS_IN = new FunctionDefinitionBagIsIn<ISO8601Time>(XACML3.ID_FUNCTION_TIME_IS_IN, DataTypes.DT_TIME); + public static final FunctionDefinition FD_DATE_IS_IN = new FunctionDefinitionBagIsIn<ISO8601Date>(XACML3.ID_FUNCTION_DATE_IS_IN, DataTypes.DT_DATE); + public static final FunctionDefinition FD_DATETIME_IS_IN = new FunctionDefinitionBagIsIn<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_IS_IN, DataTypes.DT_DATETIME); + public static final FunctionDefinition FD_ANYURI_IS_IN = new FunctionDefinitionBagIsIn<URI>(XACML3.ID_FUNCTION_ANYURI_IS_IN, DataTypes.DT_ANYURI); + public static final FunctionDefinition FD_HEXBINARY_IS_IN = new FunctionDefinitionBagIsIn<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_IS_IN, DataTypes.DT_HEXBINARY); + public static final FunctionDefinition FD_BASE64BINARY_IS_IN = new FunctionDefinitionBagIsIn<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_IS_IN, DataTypes.DT_BASE64BINARY); + public static final FunctionDefinition FD_DAYTIMEDURATION_IS_IN = new FunctionDefinitionBagIsIn<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_IS_IN, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_DAYTIMEDURATION_IS_IN_VERSION1 = new FunctionDefinitionBagIsIn<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_IS_IN, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_IS_IN = new FunctionDefinitionBagIsIn<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_IS_IN, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_IS_IN_VERSION1 = new FunctionDefinitionBagIsIn<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_IS_IN, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_X500NAME_IS_IN = new FunctionDefinitionBagIsIn<X500Principal>(XACML3.ID_FUNCTION_X500NAME_IS_IN, DataTypes.DT_X500NAME); + public static final FunctionDefinition FD_RFC822NAME_IS_IN = new FunctionDefinitionBagIsIn<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_IS_IN, DataTypes.DT_RFC822NAME); + public static final FunctionDefinition FD_IPADDRESS_IS_IN = new FunctionDefinitionBagIsIn<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_IS_IN, DataTypes.DT_IPADDRESS); + public static final FunctionDefinition FD_DNSNAME_IS_IN = new FunctionDefinitionBagIsIn<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_IS_IN, DataTypes.DT_DNSNAME); + + public static final FunctionDefinition FD_STRING_BAG = new FunctionDefinitionBag<String>(XACML3.ID_FUNCTION_STRING_BAG, DataTypes.DT_STRING); + public static final FunctionDefinition FD_BOOLEAN_BAG = new FunctionDefinitionBag<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_BAG, DataTypes.DT_BOOLEAN); + public static final FunctionDefinition FD_INTEGER_BAG = new FunctionDefinitionBag<BigInteger>(XACML3.ID_FUNCTION_INTEGER_BAG, DataTypes.DT_INTEGER); + public static final FunctionDefinition FD_DOUBLE_BAG = new FunctionDefinitionBag<Double>(XACML3.ID_FUNCTION_DOUBLE_BAG, DataTypes.DT_DOUBLE); + public static final FunctionDefinition FD_TIME_BAG = new FunctionDefinitionBag<ISO8601Time>(XACML3.ID_FUNCTION_TIME_BAG, DataTypes.DT_TIME); + public static final FunctionDefinition FD_DATE_BAG = new FunctionDefinitionBag<ISO8601Date>(XACML3.ID_FUNCTION_DATE_BAG, DataTypes.DT_DATE); + public static final FunctionDefinition FD_DATETIME_BAG = new FunctionDefinitionBag<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_BAG, DataTypes.DT_DATETIME); + public static final FunctionDefinition FD_ANYURI_BAG = new FunctionDefinitionBag<URI>(XACML3.ID_FUNCTION_ANYURI_BAG, DataTypes.DT_ANYURI); + public static final FunctionDefinition FD_HEXBINARY_BAG = new FunctionDefinitionBag<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_BAG, DataTypes.DT_HEXBINARY); + public static final FunctionDefinition FD_BASE64BINARY_BAG = new FunctionDefinitionBag<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_BAG, DataTypes.DT_BASE64BINARY); + public static final FunctionDefinition FD_DAYTIMEDURATION_BAG = new FunctionDefinitionBag<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_DAYTIMEDURATION_BAG_VERSION1 = new FunctionDefinitionBag<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_BAG, DataTypes.DT_DAYTIMEDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_BAG = new FunctionDefinitionBag<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_YEARMONTHDURATION_BAG_VERSION1 = new FunctionDefinitionBag<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_BAG, DataTypes.DT_YEARMONTHDURATION); + public static final FunctionDefinition FD_X500NAME_BAG = new FunctionDefinitionBag<X500Principal>(XACML3.ID_FUNCTION_X500NAME_BAG, DataTypes.DT_X500NAME); + public static final FunctionDefinition FD_RFC822NAME_BAG = new FunctionDefinitionBag<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_BAG, DataTypes.DT_RFC822NAME); + public static final FunctionDefinition FD_IPADDRESS_BAG = new FunctionDefinitionBag<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_BAG, DataTypes.DT_IPADDRESS); + public static final FunctionDefinition FD_DNSNAME_BAG = new FunctionDefinitionBag<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_BAG, DataTypes.DT_DNSNAME); + + + /* + * Set Functions (See A.3.11) + * + * (According to section 10.2.8, this doesn't seem to include + * IPAddress or DNSName datatype). This is because Xacml 3.0 did NOT + * define an equality operator for these 2 types. See discussion: + * + * https://lists.oasis-open.org/archives/xacml/201104/msg00014.html + * + * Also section 10.2.8 is missing XPathExpression versions of these functions. + * + */ + public static final FunctionDefinition FD_STRING_INTERSECTION = new FunctionDefinitionSet<String,String>(XACML3.ID_FUNCTION_STRING_INTERSECTION, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_BOOLEAN_INTERSECTION = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_INTERSECTION, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_INTEGER_INTERSECTION = new FunctionDefinitionSet<BigInteger,BigInteger>(XACML3.ID_FUNCTION_INTEGER_INTERSECTION, DataTypes.DT_INTEGER, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_DOUBLE_INTERSECTION = new FunctionDefinitionSet<Double,Double>(XACML3.ID_FUNCTION_DOUBLE_INTERSECTION, DataTypes.DT_DOUBLE, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_TIME_INTERSECTION = new FunctionDefinitionSet<ISO8601Time,ISO8601Time>(XACML3.ID_FUNCTION_TIME_INTERSECTION, DataTypes.DT_TIME, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_DATE_INTERSECTION = new FunctionDefinitionSet<ISO8601Date,ISO8601Date>(XACML3.ID_FUNCTION_DATE_INTERSECTION, DataTypes.DT_DATE, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_DATETIME_INTERSECTION = new FunctionDefinitionSet<ISO8601DateTime, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_INTERSECTION, DataTypes.DT_DATETIME, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_ANYURI_INTERSECTION = new FunctionDefinitionSet<URI, URI>(XACML3.ID_FUNCTION_ANYURI_INTERSECTION, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_HEXBINARY_INTERSECTION = new FunctionDefinitionSet<HexBinary,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_INTERSECTION, DataTypes.DT_HEXBINARY, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_BASE64BINARY_INTERSECTION = new FunctionDefinitionSet<Base64Binary,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_INTERSECTION, DataTypes.DT_BASE64BINARY, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_DAYTIMEDURATION_INTERSECTION = new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_INTERSECTION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_DAYTIMEDURATION_INTERSECTION_VERSION1 = new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_INTERSECTION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_YEARMONTHDURATION_INTERSECTION = new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_INTERSECTION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_YEARMONTHDURATION_INTERSECTION_VERSION1 = new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_INTERSECTION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_X500NAME_INTERSECTION = new FunctionDefinitionSet<X500Principal,X500Principal>(XACML3.ID_FUNCTION_X500NAME_INTERSECTION, DataTypes.DT_X500NAME, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.INTERSECTION); + public static final FunctionDefinition FD_RFC822NAME_INTERSECTION = new FunctionDefinitionSet<RFC822Name,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_INTERSECTION, DataTypes.DT_RFC822NAME, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.INTERSECTION); + + public static final FunctionDefinition FD_STRING_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_BOOLEAN_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_INTEGER_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_DOUBLE_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_TIME_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_DATE_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_DATETIME_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_ANYURI_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_HEXBINARY_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_BASE64BINARY_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF_VERSION1 = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF_VERSION1 = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_X500NAME_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + public static final FunctionDefinition FD_RFC822NAME_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF); + + public static final FunctionDefinition FD_STRING_UNION = new FunctionDefinitionSet<String,String>(XACML3.ID_FUNCTION_STRING_UNION, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_BOOLEAN_UNION = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_UNION, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_INTEGER_UNION = new FunctionDefinitionSet<BigInteger,BigInteger>(XACML3.ID_FUNCTION_INTEGER_UNION, DataTypes.DT_INTEGER, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_DOUBLE_UNION = new FunctionDefinitionSet<Double,Double>(XACML3.ID_FUNCTION_DOUBLE_UNION, DataTypes.DT_DOUBLE, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_TIME_UNION = new FunctionDefinitionSet<ISO8601Time,ISO8601Time>(XACML3.ID_FUNCTION_TIME_UNION, DataTypes.DT_TIME, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_DATE_UNION = new FunctionDefinitionSet<ISO8601Date,ISO8601Date>(XACML3.ID_FUNCTION_DATE_UNION, DataTypes.DT_DATE, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_DATETIME_UNION = new FunctionDefinitionSet<ISO8601DateTime, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_UNION, DataTypes.DT_DATETIME, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_ANYURI_UNION = new FunctionDefinitionSet<URI, URI>(XACML3.ID_FUNCTION_ANYURI_UNION, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_HEXBINARY_UNION = new FunctionDefinitionSet<HexBinary,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_UNION, DataTypes.DT_HEXBINARY, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_BASE64BINARY_UNION = new FunctionDefinitionSet<Base64Binary,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_UNION, DataTypes.DT_BASE64BINARY, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_DAYTIMEDURATION_UNION = new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_UNION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_DAYTIMEDURATION_UNION_VERSION1 = new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_UNION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_YEARMONTHDURATION_UNION = new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_UNION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_YEARMONTHDURATION_UNION_VERSION1 = new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_UNION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_X500NAME_UNION = new FunctionDefinitionSet<X500Principal,X500Principal>(XACML3.ID_FUNCTION_X500NAME_UNION, DataTypes.DT_X500NAME, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.UNION); + public static final FunctionDefinition FD_RFC822NAME_UNION = new FunctionDefinitionSet<RFC822Name,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_UNION, DataTypes.DT_RFC822NAME, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.UNION); + + public static final FunctionDefinition FD_STRING_SUBSET = new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_BOOLEAN_SUBSET = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_INTEGER_SUBSET = new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_DOUBLE_SUBSET = new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_TIME_SUBSET = new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_DATE_SUBSET = new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_DATETIME_SUBSET = new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_ANYURI_SUBSET = new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_HEXBINARY_SUBSET = new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_BASE64BINARY_SUBSET = new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_DAYTIMEDURATION_SUBSET = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_DAYTIMEDURATION_SUBSET_VERSION1 = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_YEARMONTHDURATION_SUBSET = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_YEARMONTHDURATION_SUBSET_VERSION1 = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_X500NAME_SUBSET = new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.SUBSET); + public static final FunctionDefinition FD_RFC822NAME_SUBSET = new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.SUBSET); + + public static final FunctionDefinition FD_STRING_SET_EQUALS = new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_BOOLEAN_SET_EQUALS = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_INTEGER_SET_EQUALS = new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_DOUBLE_SET_EQUALS = new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_TIME_SET_EQUALS = new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_DATE_SET_EQUALS = new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_DATETIME_SET_EQUALS = new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_ANYURI_SET_EQUALS = new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_HEXBINARY_SET_EQUALS = new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_BASE64BINARY_SET_EQUALS = new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_DAYTIMEDURATION_SET_EQUALS = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_DAYTIMEDURATION_SET_EQUALS_VERSION1 = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_YEARMONTHDURATION_SET_EQUALS = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_YEARMONTHDURATION_SET_EQUALS_VERSION1 = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_X500NAME_SET_EQUALS = new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.SET_EQUALS); + public static final FunctionDefinition FD_RFC822NAME_SET_EQUALS = new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.SET_EQUALS); + + + /* + * Higher Order Bag functions (See A.3.12) + */ + public static final FunctionDefinition FD_ANY_OF = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF); + public static final FunctionDefinition FD_ANY_OF_VERSION1 = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ANY_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF); + public static final FunctionDefinition FD_ALL_OF = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF); + public static final FunctionDefinition FD_ALL_OF_VERSION1 = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ALL_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF); + public static final FunctionDefinition FD_ANY_OF_ANY = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ANY); + public static final FunctionDefinition FD_ANY_OF_ANY_VERSION1 = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ANY_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ANY); + public static final FunctionDefinition FD_ALL_OF_ANY = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF_ANY); + public static final FunctionDefinition FD_ANY_OF_ALL = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF_ALL, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ALL); + public static final FunctionDefinition FD_ALL_OF_ALL = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF_ALL, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF_ALL); + public static final FunctionDefinition FD_MAP = new FunctionDefinitionHigherOrderBag<Object,Object>(XACML3.ID_FUNCTION_MAP, null, null, FunctionDefinitionHigherOrderBag.OPERATION.MAP); + public static final FunctionDefinition FD_MAP_VERSION1 = new FunctionDefinitionHigherOrderBag<Object,Object>(XACML1.ID_FUNCTION_MAP, null, null, FunctionDefinitionHigherOrderBag.OPERATION.MAP); + + + /* + * Regular Expression functions (See A.3.13) + */ + public static final FunctionDefinition FD_STRING_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<String>(XACML3.ID_FUNCTION_STRING_REGEXP_MATCH, DataTypes.DT_STRING); + public static final FunctionDefinition FD_ANYURI_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<URI>(XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH, DataTypes.DT_ANYURI); + public static final FunctionDefinition FD_IPADDRESS_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH, DataTypes.DT_IPADDRESS); + public static final FunctionDefinition FD_DNSNAME_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH, DataTypes.DT_DNSNAME); + public static final FunctionDefinition FD_RFC822NAME_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH, DataTypes.DT_RFC822NAME); + public static final FunctionDefinition FD_X500NAME_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<X500Principal>(XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH, DataTypes.DT_X500NAME); + + + /* + * Special Match functions (See A.3.14) + */ + public static final FunctionDefinition FD_X500NAME_MATCH = new FunctionDefinitionX500NameMatch(XACML3.ID_FUNCTION_X500NAME_MATCH); + public static final FunctionDefinition FD_RFC822NAME_MATCH = new FunctionDefinitionRFC822NameMatch(XACML3.ID_FUNCTION_RFC822NAME_MATCH); + + /* + * XPath based functions (See A.3.15) + * + * THESE ARE OPTIONAL + * + */ + public static final FunctionDefinition FD_XPATH_NODE_COUNT = new FunctionDefinitionXPath<BigInteger>(XACML3.ID_FUNCTION_XPATH_NODE_COUNT, DataTypes.DT_INTEGER, FunctionDefinitionXPath.OPERATION.COUNT); +// public static final FunctionDefinition FD_XPATH_NODE_COUNT_VERSION1 = new FunctionDefinitionXPath<BigInteger>(XACML1.ID_FUNCTION_XPATH_NODE_COUNT, DataTypes.DT_INTEGER, FunctionDefinitionXPath.OPERATION.COUNT); + public static final FunctionDefinition FD_XPATH_NODE_EQUAL = new FunctionDefinitionXPath<Boolean>(XACML3.ID_FUNCTION_XPATH_NODE_EQUAL, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.EQUAL); +// public static final FunctionDefinition FD_XPATH_NODE_EQUAL_VERSION1 = new FunctionDefinitionXPath<Boolean>(XACML1.ID_FUNCTION_XPATH_NODE_EQUAL, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.EQUAL); + public static final FunctionDefinition FD_XPATH_NODE_MATCH = new FunctionDefinitionXPath<Boolean>(XACML3.ID_FUNCTION_XPATH_NODE_MATCH, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.MATCH); +// public static final FunctionDefinition FD_XPATH_NODE_MATCH_VERSION1 = new FunctionDefinitionXPath<Boolean>(XACML1.ID_FUNCTION_XPATH_NODE_MATCH, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.MATCH); + + + /* + * Other functions (See A.3.16) + * + * THIS ONE IS OPTIONAL + * + */ + public static final FunctionDefinition FD_ACCESS_PERMITTED = new FunctionDefinitionAccessPermitted(XACML3.ID_FUNCTION_ACCESS_PERMITTED); + + + /* + * Deprecated functions (See A.4) + * + */ + public static final FunctionDefinition FD_URI_STRING_CONCATENATE = new FunctionDefinitionURIStringConcatenate(XACML2.ID_FUNCTION_URI_STRING_CONCATENATE); + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java new file mode 100755 index 0000000..4463fba --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java
@@ -0,0 +1,373 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.IdReferenceMatch; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Version; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.MatchResult; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.PolicyFinder; +import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult; +import com.att.research.xacmlatt.pdp.policy.PolicySet; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; +import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef; + +/** + * StdPolicyFinder implements the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinder} interface to look up policies + * by their internal ID or an externally visible ID. + * + * @author car + * @version $Revision: 1.4 $ + */ +public class StdPolicyFinder implements PolicyFinder { + private static final PolicyFinderResult<PolicyDef> PFR_MULTIPLE = new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Multiple applicable root policies")); + private static final PolicyFinderResult<PolicyDef> PFR_NOT_FOUND = new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching root policy found")); + + private static final PolicyFinderResult<Policy> PFR_POLICY_NOT_FOUND = new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching policy found")); + private static final PolicyFinderResult<Policy> PFR_NOT_A_POLICY = new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Not a policy")); + private static final PolicyFinderResult<PolicySet> PFR_POLICYSET_NOT_FOUND = new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching policy set found")); + private static final PolicyFinderResult<PolicySet> PFR_NOT_A_POLICYSET = new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Not a policy set")); + + private Log logger = LogFactory.getLog(this.getClass()); + private List<PolicyDef> listRoots = new ArrayList<PolicyDef>(); + private Map<Identifier,List<PolicyDef>> mapPolicies = new HashMap<Identifier,List<PolicyDef>>(); + + public static class StdPolicyFinderException extends Exception { + private static final long serialVersionUID = -8969282995787463288L; + public StdPolicyFinderException(String msg) { + super(msg); + } + public StdPolicyFinderException(String msg, Throwable cause) { + super(msg, cause); + } + } + + private void storeInPolicyMap(PolicyDef policyDef) { + List<PolicyDef> listPolicyDefs = this.mapPolicies.get(policyDef.getIdentifier()); + if (listPolicyDefs == null) { + listPolicyDefs = new ArrayList<PolicyDef>(); + this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs); + } + listPolicyDefs.add(policyDef); + } + + private <T extends PolicyDef> List<T> getFromPolicyMap(IdReferenceMatch idReferenceMatch, Class<T> classPolicyDef) { + /* + * Get all of the PolicyDefs for the Identifier in the reference match + */ + List<PolicyDef> listPolicyDefForId = this.mapPolicies.get(idReferenceMatch.getId()); + if (listPolicyDefForId == null) { + return null; + } + + /* + * Iterate over all of the PolicyDefs that were found and select only the ones that match + * the version request and the isPolicySet + */ + List<T> listPolicyDefMatches = null; + Iterator<PolicyDef> iterPolicyDefs = listPolicyDefForId.iterator(); + while (iterPolicyDefs.hasNext()) { + PolicyDef policyDef = iterPolicyDefs.next(); + if (classPolicyDef.isInstance(policyDef) && policyDef.matches(idReferenceMatch)) { + if (listPolicyDefMatches == null) { + listPolicyDefMatches = new ArrayList<T>(); + } + listPolicyDefMatches.add(classPolicyDef.cast(policyDef)); + } + } + + return listPolicyDefMatches; + } + + private <T extends PolicyDef> T getBestMatchN(List<T> matches) { + T bestMatch = null; + Version bestVersion = null; + Iterator<T> iterMatches = matches.iterator(); + + while (iterMatches.hasNext()) { + T match = iterMatches.next(); + if (bestMatch == null) { + bestMatch = match; + bestVersion = match.getVersion(); + } else { + Version matchVersion = match.getVersion(); + if (matchVersion != null) { + if (matchVersion.compareTo(bestVersion) > 0) { + bestMatch = match; + bestVersion = matchVersion; + } + } + } + } + return bestMatch; + } + + private <T extends PolicyDef> T getBestMatch(List<T> matches) { + switch(matches.size()) { + case 0: + return null; + case 1: + return matches.get(0); + default: + return this.getBestMatchN(matches); + } + } + + private PolicyDef loadPolicyDefFromURI(URI uri) throws StdPolicyFinderException { + PolicyDef policyDef = null; + InputStream inputStream = null; + try { + this.logger.info("Loading policy from URI " + uri.toString()); + URL url = uri.toURL(); + this.logger.debug("Loading policy from URL " + url.toString()); + + inputStream = url.openStream(); + policyDef = DOMPolicyDef.load(inputStream); + } catch (MalformedURLException ex) { + this.logger.debug("Unknown protocol for URI " + uri.toString()); + return null; + } catch (Exception ex) { + this.logger.error("Exception loading policy definition", ex); + throw new StdPolicyFinderException("Exception loading policy def from \"" + uri.toString() + "\": " + ex.getMessage(), ex); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (Exception ex) { + + } + } + } + return policyDef; + } + + /** + * Looks up the given {@link com.att.research.xacml.api.Identifier} in the map first. If not found, and the <code>Identifier</code> contains + * a URL, then attempts to retrieve the document from the URL and caches it. + * + * @param idReferenceMatch the <code>IdReferenceMatch</code> to look up + * @return a <code>PolicyFinderResult</code> with the requested <code>Policy</code> or an error status + */ + private PolicyFinderResult<Policy> lookupPolicyByIdentifier(IdReferenceMatch idReferenceMatch) { + List<Policy> listCachedPolicies = this.getFromPolicyMap(idReferenceMatch, Policy.class); + if (listCachedPolicies == null) { + Identifier id = idReferenceMatch.getId(); + if (id != null) { + URI uri = id.getUri(); + if (uri != null && uri.isAbsolute()) { + PolicyDef policyDef = null; + try { + policyDef = this.loadPolicyDefFromURI(uri); + } catch (StdPolicyFinderException ex) { + return new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage())); + } + if (policyDef != null) { + if (policyDef instanceof Policy) { + List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>(); + listPolicyDefs.add(policyDef); + this.mapPolicies.put(id, listPolicyDefs); + this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs); + return new StdPolicyFinderResult<Policy>((Policy)policyDef); + } else { + return PFR_NOT_A_POLICY; + } + } else { + return PFR_POLICY_NOT_FOUND; + } + } + } + } + if (listCachedPolicies != null) { + return new StdPolicyFinderResult<Policy>(this.getBestMatch(listCachedPolicies)); + } else { + return PFR_POLICY_NOT_FOUND; + } + } + + /** + * Looks up the given {@link com.att.research.xacml.api.Identifier} in the map first. If not found, and the <code>Identifier</code> contains + * a URL, then attempts to retrieve the document from the URL and caches it. + * + * @param idReferenceMatch the <code>IdReferenceMatch</code> to look up + * @return a <code>PolicyFinderResult</code> with the requested <code>PolicySet</code> or an error status + */ + private PolicyFinderResult<PolicySet> lookupPolicySetByIdentifier(IdReferenceMatch idReferenceMatch) { + List<PolicySet> listCachedPolicySets = this.getFromPolicyMap(idReferenceMatch, PolicySet.class); + if (listCachedPolicySets == null) { + Identifier id = idReferenceMatch.getId(); + if (id != null) { + URI uri = id.getUri(); + if (uri != null && uri.isAbsolute()) { + PolicyDef policyDef = null; + try { + policyDef = this.loadPolicyDefFromURI(uri); + } catch (StdPolicyFinderException ex) { + return new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage())); + } + if (policyDef != null) { + if (policyDef instanceof PolicySet) { + List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>(); + listPolicyDefs.add(policyDef); + this.mapPolicies.put(id, listPolicyDefs); + this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs); + return new StdPolicyFinderResult<PolicySet>((PolicySet)policyDef); + } else { + return PFR_NOT_A_POLICYSET; + } + } else { + return PFR_POLICYSET_NOT_FOUND; + } + } + } + } + if (listCachedPolicySets != null) { + return new StdPolicyFinderResult<PolicySet>(this.getBestMatch(listCachedPolicySets)); + } else { + return PFR_POLICYSET_NOT_FOUND; + } + } + + /** + * Adds the given <code>PolicyDef</code> to the map of loaded <code>PolicyDef</code>s and adds + * its child <code>PolicyDef</code>s recursively. + * + * @param policyDef the <code>PolicyDef</code> to add + */ + private void updatePolicyMap(PolicyDef policyDef) { + this.storeInPolicyMap(policyDef); + if (policyDef instanceof PolicySet) { + Iterator<PolicySetChild> iterChildren = ((PolicySet)policyDef).getChildren(); + if (iterChildren != null) { + while (iterChildren.hasNext()) { + PolicySetChild policySetChild = iterChildren.next(); + if (policySetChild instanceof PolicyDef) { + this.updatePolicyMap((PolicyDef)policySetChild); + } + } + } + } + } + + public StdPolicyFinder(Collection<PolicyDef> listRootPolicies, Collection<PolicyDef> referencedPolicyDefs) { + if (listRootPolicies != null) { + for (PolicyDef policyDef: listRootPolicies) { + this.listRoots.add(policyDef); + this.updatePolicyMap(policyDef); + } + } + if (referencedPolicyDefs != null) { + for (PolicyDef policyDef: referencedPolicyDefs) { + this.storeInPolicyMap(policyDef); + } + } + } + + /** + * Creates a new <code>StdPolicyFinder</code> with the given <code>PolicyDef</code> as the root element. + * + * @param rootPolicyDef the <code>PolicyDef</code> acting as the root element + */ + public StdPolicyFinder(PolicyDef rootPolicyDef, Collection<PolicyDef> referencedPolicyDefs) { + if (rootPolicyDef != null) { + this.listRoots.add(rootPolicyDef); + this.updatePolicyMap(rootPolicyDef); + } + + if (referencedPolicyDefs != null) { + for (PolicyDef policyDef: referencedPolicyDefs) { + this.storeInPolicyMap(policyDef); + } + } + } + + public StdPolicyFinder(List<PolicyDef> rootPolicies, List<PolicyDef> referencedPolicies, Properties properties) { + this(rootPolicies, referencedPolicies); + } + + @Override + public PolicyFinderResult<PolicyDef> getRootPolicyDef(EvaluationContext evaluationContext) { + PolicyDef policyDefFirstMatch = null; + Iterator<PolicyDef> iterRootPolicies = this.listRoots.iterator(); + PolicyFinderResult<PolicyDef> firstIndeterminate = null; + while (iterRootPolicies.hasNext()) { + PolicyDef policyDef = iterRootPolicies.next(); + MatchResult matchResult = null; + try { + matchResult = policyDef.match(evaluationContext); + switch(matchResult.getMatchCode()) { + case INDETERMINATE: + if (firstIndeterminate == null) { + firstIndeterminate = new StdPolicyFinderResult<PolicyDef>(matchResult.getStatus()); + } + break; + case MATCH: + if (policyDefFirstMatch == null) { + policyDefFirstMatch = policyDef; + } else { + return PFR_MULTIPLE; + } + break; + case NOMATCH: + break; + } + } catch (EvaluationException ex) { + if (firstIndeterminate == null) { + firstIndeterminate = new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage())); + } + } + } + + if (policyDefFirstMatch == null) { + if (firstIndeterminate != null) { + return firstIndeterminate; + } else { + return PFR_NOT_FOUND; + } + } else { + return new StdPolicyFinderResult<PolicyDef>(policyDefFirstMatch); + } + } + + @Override + public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch) { + return this.lookupPolicyByIdentifier(idReferenceMatch); + } + + @Override + public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch) { + return this.lookupPolicySetByIdentifier(idReferenceMatch); + } + + public void addReferencedPolicy(PolicyDef policyDef) { + this.updatePolicyMap(policyDef); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java new file mode 100755 index 0000000..365c768 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java
@@ -0,0 +1,224 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.StdVersion; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLProperties; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.PolicyFinder; +import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory; +import com.att.research.xacmlatt.pdp.policy.PolicySet; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; +import com.att.research.xacmlatt.pdp.policy.Target; +import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef; +import com.att.research.xacmlatt.pdp.util.ATTPDPProperties; +import com.google.common.base.Splitter; + +/** + * StdPolicyFinderFactory extends {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory} with the + * <code>getPolicyFinder</code> method to get a single instance of the {@link StdPolicyFinder}. The + * root {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} is loaded from a file whose name is specified as a system property or + * in the $java.home/lib/xacml.properties property set. + * + * @author car + * @version $Revision: 1.3 $ + */ +public class StdPolicyFinderFactory extends PolicyFinderFactory { + public static final String PROP_FILE = ".file"; + public static final String PROP_URL = ".url"; + + private Log logger = LogFactory.getLog(this.getClass()); + private List<PolicyDef> rootPolicies; + private List<PolicyDef> referencedPolicies; + private boolean needsInit = true; + + /** + * Loads the <code>PolicyDef</code> for the given <code>String</code> identifier by looking first + * for a ".file" property associated with the ID and using that to load from a <code>File</code> and + * looking for a ".url" property associated with the ID and using that to load from a <code>URL</code>. + * + * @param policyId the <code>String</code> identifier for the policy + * @return a <code>PolicyDef</code> loaded from the given identifier + */ + protected PolicyDef loadPolicyDef(String policyId, Properties properties) { + String propLocation = properties.getProperty(policyId + PROP_FILE); + if (propLocation != null) { + File fileLocation = new File(propLocation); + if (!fileLocation.exists()) { + this.logger.error("Policy file " + fileLocation.getAbsolutePath() + " does not exist."); + } else if (!fileLocation.canRead()) { + this.logger.error("Policy file " + fileLocation.getAbsolutePath() + " cannot be read."); + } else { + try { + this.logger.info("Loading policy file " + fileLocation); + PolicyDef policyDef = DOMPolicyDef.load(fileLocation); + if (policyDef != null) { + return policyDef; + } + } catch (DOMStructureException ex) { + this.logger.error("Error loading policy file " + fileLocation.getAbsolutePath() + ": " + ex.getMessage(), ex); + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } + } + } + + if ((propLocation = properties.getProperty(policyId + PROP_URL)) != null) { + InputStream is = null; + try { + URL url = new URL(propLocation); + URLConnection urlConnection = url.openConnection(); + this.logger.info("Loading policy file " + url.toString()); + is = urlConnection.getInputStream(); + PolicyDef policyDef = DOMPolicyDef.load(is); + if (policyDef != null) { + return policyDef; + } + } catch (MalformedURLException ex) { + this.logger.error("Invalid URL " + propLocation + ": " + ex.getMessage(), ex); + } catch (IOException ex) { + this.logger.error("IOException opening URL " + propLocation + ": " + ex.getMessage(), ex); + } catch (DOMStructureException ex) { + this.logger.error("Invalid Policy " + propLocation + ": " + ex.getMessage(), ex); + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + this.logger.error("Exception closing InputStream for GET of url " + propLocation + " : " + e.getMessage() + " (May be memory leak)", e); + } + } + } + } + + this.logger.error("No known location for Policy " + policyId); + return null; + } + + /** + * Finds the identifiers for all of the policies referenced by the given property name in the + * <code>XACMLProperties</code> and loads them using the requested loading method. + * + * @param propertyName the <code>String</code> name of the property containing the list of policy identifiers + * @return a <code>List</code> of <code>PolicyDef</code>s loaded from the given property name + */ + protected List<PolicyDef> getPolicyDefs(String propertyName, Properties properties) { + String policyIds = properties.getProperty(propertyName); + if (policyIds == null || policyIds.length() == 0) { + return null; + } + + Iterable<String> policyIdArray = Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds); + if (policyIdArray == null) { + return null; + } + + List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>(); + for (String policyId : policyIdArray) { + PolicyDef policyDef = this.loadPolicyDef(policyId, properties); + if (policyDef != null) { + listPolicyDefs.add(policyDef); + } + } + return listPolicyDefs; + } + + protected synchronized void init(Properties properties) { + if (this.needsInit) { + // + // Check for property that combines root policies into one policyset + // + String combiningAlgorithm = properties.getProperty(ATTPDPProperties.PROP_POLICYFINDERFACTORY_COMBINEROOTPOLICIES); + if (combiningAlgorithm != null) { + try { + logger.info("Combining root policies with " + combiningAlgorithm); + // + // Find the combining algorithm + // + CombiningAlgorithm<PolicySetChild> algorithm = CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(new IdentifierImpl(combiningAlgorithm)); + // + // Create our root policy + // + PolicySet root = new PolicySet(); + root.setIdentifier(new IdentifierImpl(UUID.randomUUID().toString())); + root.setVersion(StdVersion.newInstance("1.0")); + root.setTarget(new Target()); + // + // Set the algorithm + // + root.setPolicyCombiningAlgorithm(algorithm); + // + // Load all our root policies + // + for (PolicyDef policy : this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES, properties)) { + root.addChild(policy); + } + // + // Set this policy as the root + // + this.rootPolicies = new ArrayList<>(); + this.rootPolicies.add(root); + } catch (FactoryException | ParseException e) { + logger.error("Failed to load Combining Algorithm Factory: " + e.getLocalizedMessage()); + } + } else { + this.rootPolicies = this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES, properties); + } + + this.referencedPolicies = this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES, properties); + this.needsInit = false; + } + } + + public StdPolicyFinderFactory() { + } + + public StdPolicyFinderFactory(Properties properties) { + } + + @Override + public PolicyFinder getPolicyFinder() throws FactoryException { + try { + this.init(XACMLProperties.getProperties()); + } catch (IOException e) { + throw new FactoryException(e); + } + return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies); + } + + @Override + public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException { + this.init(properties); + return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java new file mode 100755 index 0000000..0749a8e --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java
@@ -0,0 +1,52 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult; + +/** + * StdPolicyFinderResult implements the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderResult} interface. + * + * @author car + * @version $Revision: 1.1 $ + * @param <T> the java class extending {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} held by the <code>StdPolicyFinderResult</code> + */ +public class StdPolicyFinderResult<T extends PolicyDef> implements PolicyFinderResult<T> { + private Status status; + private T policyDef; + + public StdPolicyFinderResult(Status statusIn, T policyDefIn) { + this.status = (statusIn == null ? StdStatus.STATUS_OK : statusIn); + this.policyDef = policyDefIn; + } + + public StdPolicyFinderResult(Status statusIn) { + this(statusIn, null); + } + + public StdPolicyFinderResult(T policyDefIn) { + this(null, policyDefIn); + } + + @Override + public Status getStatus() { + return this.status; + } + + @Override + public T getPolicyDef() { + return this.policyDef; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java new file mode 100755 index 0000000..ff394ee --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java
@@ -0,0 +1,19 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std; + +import com.att.research.xacmlatt.pdp.util.ATTPDPProperties; + +public class StdProperties extends ATTPDPProperties { + protected StdProperties() { + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java new file mode 100755 index 0000000..c24d2c2 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java
@@ -0,0 +1,117 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2015 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; + +/** + * @author pameladragosh + * + * This algorithm was created to support combining a collection of policies in which the permit's are combined into one decision. PermitOverrides + * itself will stop once a Permit is found. However, some policy makers want every policy in a policy set to be visited by the PDP engine. + * The result of all the Permits that were found are then combined and returned. If no Permits were found then the result is the same semantics as + * the PermitOverrides combining algorithm. + * + * @param <T> + */ +public class CombinedPermitOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> { + + public CombinedPermitOverrides(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, + List<CombiningElement<T>> elements, + List<CombinerParameter> combinerParameters) + throws EvaluationException { + boolean atLeastOneDeny = false; + boolean atLeastOnePermit = false; + + EvaluationResult combinedResultDeny = new EvaluationResult(Decision.DENY); + EvaluationResult combinedResultPermit = new EvaluationResult(Decision.PERMIT); + + EvaluationResult firstIndeterminateD = null; + EvaluationResult firstIndeterminateP = null; + EvaluationResult firstIndeterminateDP = null; + + Iterator<CombiningElement<T>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<T> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + atLeastOneDeny = true; + combinedResultDeny.merge(evaluationResultElement); + break; + case INDETERMINATE: + case INDETERMINATE_DENYPERMIT: + if (firstIndeterminateDP == null) { + firstIndeterminateDP = evaluationResultElement; + } else { + firstIndeterminateDP.merge(evaluationResultElement); + } + break; + case INDETERMINATE_DENY: + if (firstIndeterminateD == null) { + firstIndeterminateD = evaluationResultElement; + } else { + firstIndeterminateD.merge(evaluationResultElement); + } + break; + case INDETERMINATE_PERMIT: + if (firstIndeterminateP == null) { + firstIndeterminateP = evaluationResultElement; + } else { + firstIndeterminateP.merge(evaluationResultElement); + } + break; + case NOTAPPLICABLE: + break; + case PERMIT: + atLeastOnePermit = true; + combinedResultPermit.merge(evaluationResultElement); + break; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + } + + if (atLeastOnePermit) { + return combinedResultPermit; + } + if (firstIndeterminateDP != null) { + return firstIndeterminateDP; + } else if (firstIndeterminateP != null && (firstIndeterminateD != null || atLeastOneDeny)) { + return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus()); + } else if (firstIndeterminateP != null) { + return firstIndeterminateP; + } else if (atLeastOneDeny) { + return combinedResultDeny; + } else if (firstIndeterminateD != null) { + return firstIndeterminateD; + } else { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java new file mode 100755 index 0000000..4993a98 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java
@@ -0,0 +1,40 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm; + +public abstract class CombiningAlgorithmBase<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> implements CombiningAlgorithm<T> { + private Identifier id; + + public CombiningAlgorithmBase(Identifier identifierIn) { + this.id = identifierIn; + } + + @Override + public Identifier getId() { + return this.id; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + + Object objectToDump; + if ((objectToDump = this.getId()) != null) { + stringBuilder.append("id="); + stringBuilder.append(objectToDump.toString()); + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java new file mode 100755 index 0000000..207ec61 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java
@@ -0,0 +1,105 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; + +/** + * DenyOverrides implements the XACML 3.0 "deny-overrides" combining algorithm for both policies and rules. + * + * @author car + * + * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} + * @param <U> the java class for the identifier + */ +public class DenyOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> { + + public DenyOverrides(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException { + boolean atLeastOnePermit = false; + + EvaluationResult combinedResult = new EvaluationResult(Decision.PERMIT); + + EvaluationResult firstIndeterminateD = null; + EvaluationResult firstIndeterminateP = null; + EvaluationResult firstIndeterminateDP = null; + + Iterator<CombiningElement<T>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<T> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + return evaluationResultElement; + case INDETERMINATE: + case INDETERMINATE_DENYPERMIT: + if (firstIndeterminateDP == null) { + firstIndeterminateDP = evaluationResultElement; + } else { + firstIndeterminateDP.merge(evaluationResultElement); + } + break; + case INDETERMINATE_DENY: + if (firstIndeterminateD == null) { + firstIndeterminateD = evaluationResultElement; + } else { + firstIndeterminateD.merge(evaluationResultElement); + } + break; + case INDETERMINATE_PERMIT: + if (firstIndeterminateP == null) { + firstIndeterminateP = evaluationResultElement; + } else { + firstIndeterminateP.merge(evaluationResultElement); + } + break; + case NOTAPPLICABLE: + break; + case PERMIT: + atLeastOnePermit = true; + combinedResult.merge(evaluationResultElement); + break; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + } + + if (firstIndeterminateDP != null) { + return firstIndeterminateDP; + } else if (firstIndeterminateD != null && (firstIndeterminateP != null || atLeastOnePermit)) { + return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus()); + } else if (firstIndeterminateD != null) { + return firstIndeterminateD; + } else if (atLeastOnePermit) { + return combinedResult; + } else if (firstIndeterminateP != null) { + return firstIndeterminateP; + } else { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java new file mode 100755 index 0000000..4c241e6 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java
@@ -0,0 +1,68 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; + +/** + * DenyUnlessPermit implements the XACML 3.0 "deny-unless-permit" combining algorithm for both policies and rules. + * + * @author car + * + * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} + * @param <U> the java class for the identifier + */ +public class DenyUnlessPermit<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> { + + public DenyUnlessPermit(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException { + EvaluationResult combinedResult = new EvaluationResult(Decision.DENY); + + Iterator<CombiningElement<T>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<T> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + combinedResult.merge(evaluationResultElement); + break; + case INDETERMINATE: + case INDETERMINATE_DENYPERMIT: + case INDETERMINATE_DENY: + case INDETERMINATE_PERMIT: + case NOTAPPLICABLE: + break; + case PERMIT: + return evaluationResultElement; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + } + + return combinedResult; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java new file mode 100755 index 0000000..02402a5 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java
@@ -0,0 +1,58 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; + +/** + * PermitOverrides extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the + * XACML 1.0 "first-applicable" combining algorithm for policies and rules. + * + * @author car + * @version $Revision: 1.1 $ + * + * @param <T> the java class of the object to be combined + */ +public class FirstApplicable<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> { + + public FirstApplicable(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, + List<CombiningElement<T>> elements, + List<CombinerParameter> combinerParameters) + throws EvaluationException { + Iterator<CombiningElement<T>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<T> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + if (evaluationResultElement.getDecision() != Decision.NOTAPPLICABLE) { + return evaluationResultElement; + } + } + + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java new file mode 100755 index 0000000..e990b6a --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java
@@ -0,0 +1,78 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; + +/** + * DenyOverrides implements the XACML 1.0 "deny-overrides" combining algorithm for policies and policy sets. + * + * @author car + * + * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} + * @param <U> the java class for the identifier + */ +public class LegacyDenyOverridesPolicy extends CombiningAlgorithmBase<PolicySetChild> { + + public LegacyDenyOverridesPolicy(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<PolicySetChild>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException { + boolean atLeastOnePermit = false; + + EvaluationResult combinedResult = new EvaluationResult(Decision.PERMIT); + + Iterator<CombiningElement<PolicySetChild>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<PolicySetChild> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + return evaluationResultElement; + case INDETERMINATE: + case INDETERMINATE_DENYPERMIT: + case INDETERMINATE_DENY: + case INDETERMINATE_PERMIT: + return new EvaluationResult(Decision.DENY, StdStatus.STATUS_OK); + case NOTAPPLICABLE: + break; + case PERMIT: + atLeastOnePermit = true; + combinedResult.merge(evaluationResultElement); + break; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + } + + if (atLeastOnePermit) { + return combinedResult; + } else { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java new file mode 100755 index 0000000..68e156a --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java
@@ -0,0 +1,91 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; +import com.att.research.xacmlatt.pdp.policy.Rule; +import com.att.research.xacmlatt.pdp.policy.RuleEffect; + +/** + * DenyOverrides implements the XACML 1.0 "deny-overrides" combining algorithm for rules. + * + * @author car + * + * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} + * @param <U> the java class for the identifier + */ +public class LegacyDenyOverridesRule extends CombiningAlgorithmBase<Rule> { + + public LegacyDenyOverridesRule(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<Rule>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException { + boolean atLeastOnePermit = false; + boolean potentialDeny = false; + + EvaluationResult combinedResult = new EvaluationResult(Decision.PERMIT); + EvaluationResult evaluationResultIndeterminate = null; + + Iterator<CombiningElement<Rule>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<Rule> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + return evaluationResultElement; + case INDETERMINATE: + case INDETERMINATE_DENYPERMIT: + case INDETERMINATE_DENY: + case INDETERMINATE_PERMIT: + if (evaluationResultIndeterminate == null) { + evaluationResultIndeterminate = evaluationResultElement; + } else { + evaluationResultIndeterminate.merge(evaluationResultElement); + } + if (combiningElement.getEvaluatable().getRuleEffect() == RuleEffect.DENY) { + potentialDeny = true; + } + case NOTAPPLICABLE: + break; + case PERMIT: + atLeastOnePermit = true; + combinedResult.merge(evaluationResultElement); + break; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + } + + if (potentialDeny) { + return evaluationResultIndeterminate; + } else if (atLeastOnePermit) { + return combinedResult; + } else if (evaluationResultIndeterminate != null) { + return evaluationResultIndeterminate; + } else { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java new file mode 100755 index 0000000..43ed569 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java
@@ -0,0 +1,85 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; + +/** + * LegacyPermitOverridesPolicy extends {@link com.att.research.xacmlatt.pdp.policy.combiners.CombiningAlgorithmBase} for + * {@link com.att.research.xacmlatt.pdp.policy.PolicySetChild} elements implementing the XACML 1.0 permit-overrides policy combining algorithm. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class LegacyPermitOverridesPolicy extends CombiningAlgorithmBase<PolicySetChild> { + + public LegacyPermitOverridesPolicy(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<PolicySetChild>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException { + boolean atLeastOneDeny = false; + + EvaluationResult evaluationResultCombined = new EvaluationResult(Decision.DENY); + EvaluationResult evaluationResultIndeterminate = null; + + Iterator<CombiningElement<PolicySetChild>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<PolicySetChild> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + atLeastOneDeny = true; + evaluationResultCombined.merge(evaluationResultElement); + break; + case INDETERMINATE: + case INDETERMINATE_DENY: + case INDETERMINATE_DENYPERMIT: + case INDETERMINATE_PERMIT: + if (evaluationResultIndeterminate == null) { + evaluationResultIndeterminate = evaluationResultElement; + } else { + evaluationResultIndeterminate.merge(evaluationResultElement); + } + break; + case NOTAPPLICABLE: + break; + case PERMIT: + return evaluationResultElement; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + + } + + if (atLeastOneDeny) { + return evaluationResultCombined; + } else if (evaluationResultIndeterminate != null) { + return evaluationResultIndeterminate; + } else { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java new file mode 100755 index 0000000..446ff35 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java
@@ -0,0 +1,91 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; +import com.att.research.xacmlatt.pdp.policy.Rule; +import com.att.research.xacmlatt.pdp.policy.RuleEffect; + +/** + * LegacyPermitOverridesRule extends {@link com.att.research.xacmlatt.pdp.policy.combiners.CombiningAlgorithmBase} for + * {@link com.att.research.xacmlatt.pdp.policy.Rule}s to implement the XACML 1.0 permit-overrides rule combining algorithm. + * + * @author car + * @version $Revision: 1.1 $ + */ +public class LegacyPermitOverridesRule extends CombiningAlgorithmBase<Rule> { + + public LegacyPermitOverridesRule(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<Rule>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException { + boolean atLeastOneDeny = false; + boolean potentialPermit = false; + + EvaluationResult evaluationResultCombined = new EvaluationResult(Decision.DENY); + EvaluationResult evaluationResultIndeterminate = null; + + Iterator<CombiningElement<Rule>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<Rule> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + atLeastOneDeny = true; + evaluationResultCombined.merge(evaluationResultElement); + break; + case INDETERMINATE: + case INDETERMINATE_DENYPERMIT: + case INDETERMINATE_DENY: + case INDETERMINATE_PERMIT: + if (evaluationResultIndeterminate == null) { + evaluationResultIndeterminate = evaluationResultElement; + } else { + evaluationResultIndeterminate.merge(evaluationResultElement); + } + if (combiningElement.getEvaluatable().getRuleEffect() == RuleEffect.PERMIT) { + potentialPermit = true; + } + break; + case NOTAPPLICABLE: + break; + case PERMIT: + return evaluationResultElement; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + } + + if (potentialPermit) { + return evaluationResultIndeterminate; + } else if (atLeastOneDeny) { + return evaluationResultCombined; + } else if (evaluationResultIndeterminate != null) { + return evaluationResultIndeterminate; + } else { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java new file mode 100755 index 0000000..f5f8f35 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java
@@ -0,0 +1,78 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.eval.MatchResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; +import com.att.research.xacmlatt.pdp.policy.PolicySetChild; + +/** + * OnlyOneApplicable extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the + * XACML 1.0 "only-one-applicable" combining algorithm for policies and rules. + * + * @author car + * @version $Revision: 1.1 $ + * + * @param <T> the java class of the object to be combined + */ +public class OnlyOneApplicable extends CombiningAlgorithmBase<PolicySetChild> { + + public OnlyOneApplicable(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, + List<CombiningElement<PolicySetChild>> elements, + List<CombinerParameter> combinerParameters) + throws EvaluationException { + Iterator<CombiningElement<PolicySetChild>> iterElements = elements.iterator(); + PolicySetChild policySetChildApplicable = null; + while (iterElements.hasNext()) { + CombiningElement<PolicySetChild> combiningElement = iterElements.next(); + MatchResult matchResultElement = combiningElement.getEvaluatable().match(evaluationContext); + + switch(matchResultElement.getMatchCode()) { + case INDETERMINATE: + return new EvaluationResult(Decision.INDETERMINATE, matchResultElement.getStatus()); + case MATCH: + if (policySetChildApplicable == null) { + policySetChildApplicable = combiningElement.getEvaluatable(); + } else { + return new EvaluationResult(Decision.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "More than one applicable policy")); + } + break; + case NOMATCH: + break; + default: + throw new EvaluationException("Illegal Decision: \"" + matchResultElement.getMatchCode().toString()); + } + } + + if (policySetChildApplicable != null) { + return policySetChildApplicable.evaluate(evaluationContext); + } else { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java new file mode 100755 index 0000000..ef34403 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java
@@ -0,0 +1,109 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; + +/** + * PermitOverrides extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the + * XACML 3.0 Permit-overrides combining algorithm for policies and rules. + * + * @author car + * @version $Revision: 1.1 $ + * + * @param <T> the java class of the object to be combined + */ +public class PermitOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> { + + public PermitOverrides(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, + List<CombiningElement<T>> elements, + List<CombinerParameter> combinerParameters) + throws EvaluationException { + boolean atLeastOneDeny = false; + + EvaluationResult combinedResult = new EvaluationResult(Decision.DENY); + + EvaluationResult firstIndeterminateD = null; + EvaluationResult firstIndeterminateP = null; + EvaluationResult firstIndeterminateDP = null; + + Iterator<CombiningElement<T>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<T> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + atLeastOneDeny = true; + combinedResult.merge(evaluationResultElement); + break; + case INDETERMINATE: + case INDETERMINATE_DENYPERMIT: + if (firstIndeterminateDP == null) { + firstIndeterminateDP = evaluationResultElement; + } else { + firstIndeterminateDP.merge(evaluationResultElement); + } + break; + case INDETERMINATE_DENY: + if (firstIndeterminateD == null) { + firstIndeterminateD = evaluationResultElement; + } else { + firstIndeterminateD.merge(evaluationResultElement); + } + break; + case INDETERMINATE_PERMIT: + if (firstIndeterminateP == null) { + firstIndeterminateP = evaluationResultElement; + } else { + firstIndeterminateP.merge(evaluationResultElement); + } + break; + case NOTAPPLICABLE: + break; + case PERMIT: + return evaluationResultElement; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + } + + if (firstIndeterminateDP != null) { + return firstIndeterminateDP; + } else if (firstIndeterminateP != null && (firstIndeterminateD != null || atLeastOneDeny)) { + return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus()); + } else if (firstIndeterminateP != null) { + return firstIndeterminateP; + } else if (atLeastOneDeny) { + return combinedResult; + } else if (firstIndeterminateD != null) { + return firstIndeterminateD; + } else { + return new EvaluationResult(Decision.NOTAPPLICABLE); + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java new file mode 100755 index 0000000..b1b0ee0 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java
@@ -0,0 +1,69 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.combiners; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.eval.EvaluationException; +import com.att.research.xacmlatt.pdp.eval.EvaluationResult; +import com.att.research.xacmlatt.pdp.policy.CombinerParameter; +import com.att.research.xacmlatt.pdp.policy.CombiningElement; + +/** + * PermitUnlessDeny implements the XACML 3.0 "permit-unless-deny" combining algorithm for both policies and rules. + * + * @author car + * + * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} + * @param <U> the java class for the identifier + */ +public class PermitUnlessDeny<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> { + + public PermitUnlessDeny(Identifier identifierIn) { + super(identifierIn); + } + + @Override + public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException { + EvaluationResult combinedResult = new EvaluationResult(Decision.PERMIT); + + Iterator<CombiningElement<T>> iterElements = elements.iterator(); + while (iterElements.hasNext()) { + CombiningElement<T> combiningElement = iterElements.next(); + EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext); + + assert(evaluationResultElement != null); + switch(evaluationResultElement.getDecision()) { + case DENY: + return evaluationResultElement; + case INDETERMINATE: + case INDETERMINATE_DENYPERMIT: + case INDETERMINATE_DENY: + case INDETERMINATE_PERMIT: + break; + case NOTAPPLICABLE: + break; + case PERMIT: + combinedResult.merge(evaluationResultElement); + break; + default: + throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString()); + } + } + + return combinedResult; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java new file mode 100755 index 0000000..db6b8f4 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java
@@ -0,0 +1,20 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.std.combiners; + +/** + * com.att.research.xacmlatt.pdp.std.combiners contains implementations of the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} + * interface. + * + * @author car + * @version $Revision: 1.1 $ + */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java new file mode 100755 index 0000000..9b81539 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java
@@ -0,0 +1,204 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * A ConvertedArgument is the result of processing an {@link com.att.research.xacmlatt.pdp.policy.FunctionArgument} + * to validate its correctness and to convert it into an object of the required type. + * It is returned by the <code>validateArguments</code> method in + * {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} + * and should only be used by other Functions in that same package. + * This is a data holder with no processing. + * It contains two elements: + * <UL> + * <LI> + * A {@link com.att.research.xacml.api.Status} object, and + * <LI> + * An object containing the value of the FunctionArgument processed by validateArguments. + * This object will only exist if status.isOk() (or the isOk() method in this class that calls status.isOk()) is true. + * </UL> + * + * + * @author glenngriffin + * + */ +public class ConvertedArgument<I> { + + // When status != Status.OK, the value is null + private Status status; + + // This is non-null when status == Status.OK + private I value = null; + + /** + * Constructor ensures we have a non-null status, though value will be null if status is not ok. + * + * @param s + * @param v + */ + public ConvertedArgument(Status s, I v) { + status = s; + if (s == null) { + throw new IllegalArgumentException("Status of argument cannot be null"); + } + if (s.isOk()) { + // only set value if status is ok + value = v; + } + } + + /** + * Get the Status object + * + * @return + */ + public Status getStatus() { + return status; + } + + + /** + * Convenience method that directly returns the isOk() state from the status object. + * + * @return + */ + public boolean isOk() { + return status.isOk(); + } + + + /** + * Get the value object. This may be a Bag. + * + * @return + */ + public I getValue() { + return value; + } + + + /** + * Get the value as a Bag. (convenience method) + * + * @return + */ + public Bag getBag() { + return (Bag)value; + } + + + /** + * Returns a shortened version of the given DataType Id, primarily for use with error messages to prevent them from becoming too long. + * This is a simple convenience method to reduce code bloat. + * + * @param identifier expected to have '#' in it, and if no '#' should have ":data-type:" + * @return + */ + public String getShortDataTypeId(Identifier identifier) { + String idString = identifier.stringValue(); + int index = idString.indexOf("#"); + if (index < 0) { + index = idString.indexOf(":data-type:"); + if (index < 0) { + return idString; + } else { + return idString.substring(index + 11); + } + } else { + return idString.substring(index+1); + } + } + + + + /** + * Evaluates the given <code>FunctionArgument</code> and validates that it has the correct <code>DataType</code>. + * The returned object will be either: + * <UL> + * <LI> + * A Status Object indicating an error condition, or + * <LI> + * An Object of the appropriate type containing the value of the function. + * In this case the caller should assume that the Status is Status.OK. + * Note that the object may be a bag if that is what the caller expected. + * </UL> + * + * + * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate + * @param convertedValues the <code>List</code> of <code>U</code> that the converted value is added to. + * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid, + * or an object of the correct DataType containing the value. + */ + @SuppressWarnings("unchecked") // to suppress warning on bag conversion + public ConvertedArgument(FunctionArgument functionArgument, DataType<I> expectedDataType, boolean expectBag) { + + if (functionArgument == null ) { + status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Got null argument"); + return; + } + if ( ! functionArgument.isOk()) { + status = functionArgument.getStatus(); + return; + } + + // bags are valid arguments for some functions + if (expectBag) { + if ( ! functionArgument.isBag()) { + status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected a bag, saw a simple value"); + return; + } + + Bag bag = functionArgument.getBag(); + value = (I) bag; + status = StdStatus.STATUS_OK; + return; + } + + // argument should not be a bag + if (functionArgument.isBag()) { + status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected a simple value, saw a bag"); + return; + } + AttributeValue<?> attributeValue = functionArgument.getValue(); + if (attributeValue == null || attributeValue.getValue() == null) { + status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Got null attribute"); + return; + } + if ( ! attributeValue.getDataTypeId().equals(expectedDataType.getId())) { + status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected data type '" + + getShortDataTypeId(expectedDataType.getId()) + "' saw '" + getShortDataTypeId(attributeValue.getDataTypeId()) + "'"); + return; + } + + try { + value = expectedDataType.convert(attributeValue.getValue()); + status = StdStatus.STATUS_OK; + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, message); + } + } + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java new file mode 100755 index 0000000..c8109ce --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java
@@ -0,0 +1,198 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URI; +import java.util.List; + +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Node; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.RequestAttributes; +import com.att.research.xacml.std.StdRequest; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.dom.DOMRequestAttributes; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionAccessPermitted implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML access-permitted predicate. + * + * WARNING: This code is unfinished. Initially we did not complete the implementation because we did not understand how to handle XML Namespaces + * (from the <Request> or <Policy>). + * Later we understood that any Namespaces used within this function must be explicitly listed in <Content> XML elemement passed to this function. + * However, it is not clear that anyone needs this function. + * The only use anyone has mentioned is in a recursive operation which requires a loop counter of some kind, which we do not have implemented. + * Therefore we have chosen to leave this unimplemented for now. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * access-permitted + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + */ +public class FunctionDefinitionAccessPermitted extends FunctionDefinitionBase<Boolean, URI> { + + + + + /** + * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionAccessPermitted(Identifier idIn) { + super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, false); + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + if (arguments == null || arguments.size() != 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Expected 2 arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + // first arg is URI + FunctionArgument functionArgument = arguments.get(0); + ConvertedArgument<URI> convertedArgument0 = new ConvertedArgument<URI>(functionArgument, DataTypes.DT_ANYURI, false); + if ( ! convertedArgument0.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus())); + } + URI attributesURI = convertedArgument0.getValue(); + // this must be a urn of an attribute category + if ( ! attributesURI.toString().startsWith("urn:") || ! attributesURI.toString().contains(":attribute-category:")) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + + " First argument must be a urn for an attribute-category, not '" + attributesURI.toString() )); + } + + // second argument is of input type + functionArgument = arguments.get(1); + ConvertedArgument<String> convertedArgument1 = new ConvertedArgument<String>(functionArgument, DataTypes.DT_STRING, false); + if ( ! convertedArgument1.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument1.getStatus())); + } + // get the Duration object from the argument which includes all fields, even if the incoming argument does not include them all + String xmlContent = convertedArgument1.getValue(); + + // The spec is fuzzy on whether this string includes the "<Content>" tags or not, so handle it either way + if ( ! xmlContent.trim().toLowerCase().startsWith("<content>") ) { + // incomming is not surrounded by <content> tags, so ad them + xmlContent = "<Content>" + xmlContent + "</Content>"; + } + +//TODO - the next block needs to be uncommented and fixed +//Request req = evaluationContext.getRequest(); +//List<String> xmlAttrList = req.getRequestXMLAttributes(); +//String attrString = " "; +//for (String attr : xmlAttrList) { +// attrString += " " + attr; +//} +// +// // add the Attributes XML element +// xmlContent = "<Attributes Category=\"" + attributesURI + "\" " + attrString + " >" + xmlContent + "</Attributes>"; + +//java.util.Iterator<RequestAttributes> rait = req.getRequestAttributes(); +//while (rait.hasNext()) { +// RequestAttributes ra = rait.next(); +// System.out.println(ra); +//} + + + + // convert the xmlContent into XML Nodes + Node newContentNode = null; +//TODO - need to get Namespace info from original Request? How can I recover the original Namespace from the EvaluationContext? + try (InputStream is = new ByteArrayInputStream(xmlContent.getBytes())) { + DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); + docBuilderFactory.setNamespaceAware(true); + + newContentNode = docBuilderFactory + .newDocumentBuilder() + .parse(is) + .getDocumentElement(); + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + + " Parsing of XML string failed. Cause='" + message + "'" )); + } + // convert the XML Node into a RequestAttributes object +//TODO - If this code is ever completed, the following variable will be used. The annotation is to avoid warnings. +@SuppressWarnings("unused") + RequestAttributes newRequestAttributes = null; + try { + newRequestAttributes = DOMRequestAttributes.newInstance(newContentNode); + } catch (DOMStructureException e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + + " Conversion of XML to RequestAttributes failed. Cause='" + message + "'" )); + } + + + // check the evaluationContext and Request for null + if (evaluationContext == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Got null EvaluationContext")); + } + if (evaluationContext.getRequest() == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Got null Request in EvaluationContext")); + } + + // Create a new Request by: + // - copying the current request, + // - Dropping the Attributes section identified by the attributesURI argument + // - adding a new Attributes section identified by the attributesURI arg and with a Content section containing the xmlContent argument + Request originalRequest = evaluationContext.getRequest(); + +//TODO - If this code is ever completed, the following variable will be used. The annotation is to avoid warnings. +@SuppressWarnings("unused") + Request newRequest = new StdRequest(originalRequest); + + + +// ???? nameingContext???? + + // Now create a new EvaluationContext matching the one passed to this method except for the Request +//TODO + + // Run the PDP on the new EvaluationContext +//TODO + + +return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Not Implemented")); + + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java new file mode 100755 index 0000000..03bd34f --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java
@@ -0,0 +1,196 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionArithmetic extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to + * implement the XACML Arithmetic predicates as functions taking one or two arguments of the same data type and returning a single value of the same type. + * + * In Java there is no way to do arithmetic operations generically, so we need to have individual code for each operation on each class within this class. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * integer-add + * double-add + * integer-subtract + * double-subtract + * integer-multiply + * double-multiply + * integer-divide + * double-divide + * integer-mod + * integer-abs + * double-abs + * round + * floor + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <T> the java class for the data type of the function arguments + */ +public class FunctionDefinitionArithmetic<T extends Number> extends FunctionDefinitionHomogeneousSimple<T,T> { + + /** + * List of arithmetic operations. + * + * @author glenngriffin + * + */ + public enum OPERATION {ADD, SUBTRACT, MULTIPLY, DIVIDE, MOD, ABS, ROUND, FLOOR }; + + // operation to be used in this instance of the Arightmetic class + private final OPERATION operation; + + // result variables used by all functions, one for each type + private AttributeValue<BigInteger> integerResult; + private AttributeValue<Double> doubleResult; + + /** + * Constructor + * + * @param idIn + * @param dataTypeArgsIn + * @param op + */ + public FunctionDefinitionArithmetic(Identifier idIn, DataType<T> dataTypeArgsIn, OPERATION op, int nArgs) { + // for Arithmetic functions, the output type is the same as the input type (no mixing of Ints and Doubles!) + super(idIn, dataTypeArgsIn, dataTypeArgsIn, nArgs); + + // save the operation to be used in this instance + operation = op; + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + List<T> convertedArguments = new ArrayList<T>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + /* + * Now perform the requested operation. + */ + ExpressionResult expressionResult = null; + + try { + switch (operation) { + case ADD: + if (this.getDataType() == DataTypes.DT_INTEGER) { + integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).add( (BigInteger)convertedArguments.get(1)) ); + expressionResult = ExpressionResult.newSingle(integerResult); + } else { + doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) + (Double)convertedArguments.get(1)); + expressionResult = ExpressionResult.newSingle(doubleResult); + } + break; + case SUBTRACT: + if (this.getDataType() == DataTypes.DT_INTEGER) { + integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).subtract( (BigInteger)convertedArguments.get(1)) ); + expressionResult = ExpressionResult.newSingle(integerResult); + } else { + doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) - (Double)convertedArguments.get(1)); + expressionResult = ExpressionResult.newSingle(doubleResult); + } + break; + case MULTIPLY: + if (this.getDataType() == DataTypes.DT_INTEGER) { + integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).multiply((BigInteger)convertedArguments.get(1)) ); + expressionResult = ExpressionResult.newSingle(integerResult); + } else { + doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) * (Double)convertedArguments.get(1)); + expressionResult = ExpressionResult.newSingle(doubleResult); + } + break; + case DIVIDE: + if (this.getDataType() == DataTypes.DT_INTEGER) { + if ( ((BigInteger)convertedArguments.get(1)).equals(new BigInteger("0")) ) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+ + arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString())); + } + integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).divide((BigInteger)convertedArguments.get(1)) ); + expressionResult = ExpressionResult.newSingle(integerResult); + } else { + if ((Double)convertedArguments.get(1) == 0) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+ + arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString())); + } + doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) / (Double)convertedArguments.get(1)); + expressionResult = ExpressionResult.newSingle(doubleResult); + } + break; + case MOD: + if ( ((BigInteger)convertedArguments.get(1)).equals(new BigInteger("0")) ) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+ + arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString())); + } + integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).remainder((BigInteger)convertedArguments.get(1)) ); + expressionResult = ExpressionResult.newSingle(integerResult); + break; + case ABS: + if (this.getDataType() == DataTypes.DT_INTEGER) { + integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).abs() ); + expressionResult = ExpressionResult.newSingle(integerResult); + } else { + doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, Math.abs((Double)convertedArguments.get(0))); + expressionResult = ExpressionResult.newSingle(doubleResult); + } + break; + case ROUND: + doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (double)(Math.round((Double)convertedArguments.get(0))) ); + expressionResult = ExpressionResult.newSingle(doubleResult); + break; + case FLOOR: + doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, Math.floor((Double)convertedArguments.get(0))); + expressionResult = ExpressionResult.newSingle(doubleResult); + break; + } + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + String args = arguments.get(0).getValue().toString(); + if (arguments.size() > 1) { + args += ", " + arguments.get(1).getValue().toString(); + } + expressionResult = ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message + + " args: " + args + " " + e.getMessage() )); + } + + return expressionResult; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java new file mode 100755 index 0000000..cbdb406 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java
@@ -0,0 +1,107 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.List; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionBag implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML 'type'-bag predicates as functions taking 0, 1 or multiple arguments of the same data type and returning a <code>Bag</code>. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-bag + * boolean-bag + * integer-bag + * double-bag + * time-bag + * date-bag + * dateTime-bag + * anyURI-bag + * hexBinary-bag + * base64Binary-bag + * dayTimeDuration-bag (version 1 and3) + * yearMonthDuration-bag (version 1 and 3) + * x500Name-bag + * rfc822Name-bag + * ipAddress-bag + * dnsName-bag + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments, + * which is also the "type" of the returned bag + */ +public class FunctionDefinitionBag<I> extends FunctionDefinitionBase<I, I> { + + + /** + * Constructor - need dataType input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionBag(Identifier idIn, DataType<I> dataTypeArgsIn) { + super(idIn, dataTypeArgsIn, dataTypeArgsIn, true); + } + + /** + * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s. + * + * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation + * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation + * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call + */ + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + // create a list to put the values into + Bag elementBag = new Bag(); + + // see if we have arguments + if (arguments != null && arguments.size() > 0) { + + // for each arg, evaluate it, check type, and put on the list + for (FunctionArgument argument : arguments) { + // get the argument, evaluate it and check status + ConvertedArgument<I> convertedArgument = new ConvertedArgument<I>(argument, this.getDataTypeArgs(), false); + + // check the status + if ( ! convertedArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus())); + } + + // Special case: Most methods want the value contained in the AttributeValue object inside the FunctionArgument. + // This one wants the AttributeValue itself. + // We use the ConvertedArgument constructor to validate that the argument is ok, then use the AttributeValue + // from the FunctionArgument. + elementBag.add(argument.getValue()); + } + } + + // return it + return ExpressionResult.newBag(elementBag); + } + + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java new file mode 100755 index 0000000..e61e59f --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
@@ -0,0 +1,132 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionBagIsIn implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML 'type'-is-in predicates as functions taking two arguments, the first of <code>type</code> and the second of type <code>Bag</code>, + * and returning a <code>Boolean</code> for whether the first argument is contained in the second. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-is-in + * boolean-is-in + * integer-is-in + * double-is-in + * time-is-in + * date-is-in + * dateTime-is-in + * anyURI-is-in + * hexBinary-is-in + * base64Binary-is-in + * dayTimeDuration-is-in (version 1 and3) + * yearMonthDuration-is-in (version 1 and 3) + * x500Name-is-in + * rfc822Name-is-in + * ipAddress-is-in + * dnsName-is-in + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the elements in the Input argument Bag + * + * The Output for these functions is always a Boolean. + */ +public class FunctionDefinitionBagIsIn<I> extends FunctionDefinitionBase<Boolean, I> { + + + /** + * Constructor - need dataType input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionBagIsIn(Identifier idIn, DataType<I> dataTypeArgsIn) { + super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, false); + + } + + /** + * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s. + * + * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation + * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation + * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call + */ + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + if (arguments == null || arguments.size() != 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 2 arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + // get the thing to look for in the bag + FunctionArgument elementArgument = arguments.get(0); + + ConvertedArgument<I> convertedTargetArgument = new ConvertedArgument<I>(elementArgument, this.getDataTypeArgs(), false); + if ( ! convertedTargetArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedTargetArgument.getStatus())); + } + + // Special case: Most methods want the value contained in the AttributeValue object inside the FunctionArgument. + // This one wants the AttributeValue itself. + // We use the ConvertedArgument constructor to validate that the argument is ok, then use the AttributeValue + // from the FunctionArgument. + AttributeValue<?> attributeValueElement = elementArgument.getValue(); + + // now get the bag + FunctionArgument bagArgument = arguments.get(1); + ConvertedArgument<Bag> convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true); + + if ( ! convertedBagArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus())); + } + + Bag bag = convertedBagArgument.getBag(); + + Iterator<AttributeValue<?>> iterBagContents = bag.getAttributeValues(); + while (iterBagContents.hasNext()) { + AttributeValue<?> attributeValueBagContents = iterBagContents.next(); + + /* + * Should we be checking the type of the bag contents and returning an error if the bag contents are not of the + * right type? The spec does not say this, so we just use the AttributeValue.equals() method for now. + */ + if (attributeValueElement.equals(attributeValueBagContents)) { + return ER_TRUE; + } + } + + return ER_FALSE; + } + + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java new file mode 100755 index 0000000..03e1210 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
@@ -0,0 +1,117 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionBagOneAndOnly implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML 'type'-one-and-only predicates as functions taking one <code>Bag</code> argument and returning the single element in that bag of the 'type'. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-one-and-only + * boolean-one-and-only + * integer-one-and-only + * double-one-and-only + * time-one-and-only + * date-one-and-only + * dateTime-one-and-only + * anyURI-one-and-only + * hexBinary-one-and-only + * base64Binary-one-and-only + * dayTimeDuration-one-and-only (version 1 and3) + * yearMonthDuration-one-and-only (version 1 and 3) + * x500Name-one-and-only + * rfc822Name-one-and-only + * ipAddress-one-and-only + * dnsName-one-and-only + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the elements in the bag handed to this as the Input argument, + * which is also the type of the return value + * + */ +public class FunctionDefinitionBagOneAndOnly<I> extends FunctionDefinitionBase<I,I> { + + + /** + * Constructor - need dataType input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionBagOneAndOnly(Identifier idIn, DataType<I> dataTypeArgsIn) { + super(idIn, dataTypeArgsIn, dataTypeArgsIn, false); + } + + /** + * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s. + * + * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation + * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation + * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call + */ + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + if (arguments == null || arguments.size() != 1) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + " Expected 1 argument, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + FunctionArgument argument = arguments.get(0); + ConvertedArgument<Bag> convertedArgument = new ConvertedArgument<Bag>(argument, null, true); + + if ( ! convertedArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus())); + } + + Bag bag = convertedArgument.getBag(); + + if (bag.size() != 1) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + + " Expected 1 but Bag has " + bag.size() + " elements")); + } + + // get the single value from the bag + AttributeValue<?> attributeValueOneAndOnly = bag.getAttributeValues().next(); + assert(attributeValueOneAndOnly != null); + + // make sure it has the right type + // + if (!this.getDataTypeId().equals(attributeValueOneAndOnly.getDataTypeId())) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + + " Element in bag of wrong type. Expected " + + this.getShortDataTypeId(this.getDataTypeId()) + " got " + this.getShortDataTypeId(attributeValueOneAndOnly.getDataTypeId()))); + } + return ExpressionResult.newSingle(attributeValueOneAndOnly); + } + + + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java new file mode 100755 index 0000000..af75491 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
@@ -0,0 +1,110 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.math.BigInteger; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionBagSize implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML 'type'-bag-size predicates as functions taking one <code>Bag</code> argument and returning an <code>Integer</code> + * representing the number of elements in the bag. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-bag-size + * boolean-bag-size + * integer-bag-size + * double-bag-size + * time-bag-size + * date-bag-size + * dateTime-bag-size + * anyURI-bag-size + * hexBinary-bag-size + * base64Binary-bag-size + * dayTimeDuration-bag-size (version 1 and3) + * yearMonthDuration-bag-size (version 1 and 3) + * x500Name-bag-size + * rfc822Name-bag-size + * ipAddress-bag-size + * dnsName-bag-size + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments + */ +public class FunctionDefinitionBagSize<I> extends FunctionDefinitionBase<BigInteger, I> { + + + /** + * Constructor - need dataType input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionBagSize(Identifier idIn, DataType<I> dataTypeArgsIn) { + super(idIn, DataTypes.DT_INTEGER, dataTypeArgsIn, false); + } + + /** + * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s. + * + * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation + * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation + * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call + */ + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + if (arguments == null || arguments.size() != 1) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + FunctionArgument argument = arguments.get(0); + ConvertedArgument<Bag> convertedArgument = new ConvertedArgument<Bag>(argument, null, true); + + if ( ! convertedArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus())); + } + + Bag bag = convertedArgument.getBag(); + + if (bag == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Bag is null" )); + + } + + + // type is correct, so create a wrapper and return it + AttributeValue<BigInteger> resultAttributeValue = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, BigInteger.valueOf(bag.size())); + return ExpressionResult.newSingle(resultAttributeValue); + } + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java new file mode 100755 index 0000000..390e9b2 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
@@ -0,0 +1,165 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.datatypes.DataTypeBoolean; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition; + + +/** + * /** + * FunctionDefinitionBase provides a common base for {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition}s. + * The child classes derived from this are of two types: + * <UL> + * <LI> Functions returning a single simple value of a type defined in {@link com.att.research.xacml.std.datatypes.DataTypes}. + * These functions will all derive from {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSimple}. + * <LI> Functions returning a single bag with elements of a single type. + * <UL> + * <P> + * This base class contains the following components: + * <UL> + * <LI> The Identity for this function. + * <LI> The DataType of the data returned from this function. + * For Bags this means the DataType of the elements in the bag, or null if that is ambiguous. + * <LI> Commonly-used values. + * </UL> + * + * @author glenngriffin + * + * @param <O> the java class for the Output data type returned by the <code>FunctionDefinition</code> + * @param <I> the java class for the Input data type expected in the arguments to the <code>FunctionDefinition</code>. + * Some functions have non-homogeneous arguments but may still have a main 'type'. + */ +public abstract class FunctionDefinitionBase<O,I> implements FunctionDefinition { + + // The XACML identifier string for this particular function + private Identifier id; + + // each function derived from this returns a single non-bag data value of the following type, or a Bag containing elements of this type + private DataType<O> dataTypeReturn; + + // All functions have input arguments and expect them to be of a given type. + // In some instances the argument gets multiple values of different types, but when the function has a 'type' associated with it's name + // specific ones of the input must be of this type. + // When an argument Input to the function is a Bag, the elements in that bag will be of this type. + // This corresponds most closely to the 'type' in the function name (as in 'type'-bag or 'type'-equals). + private DataType<I> dataTypeArgs; + + // true = the return value from this function is a bag; false = return value is a single-value DataType object + private boolean returnsBag; + + /* + * For functions that return a Boolean result we create a single instance of the True/False return values that they can share + */ + protected static final ExpressionResult ER_TRUE = ExpressionResult.newSingle(DataTypeBoolean.AV_TRUE); + protected static final ExpressionResult ER_FALSE = ExpressionResult.newSingle(DataTypeBoolean.AV_FALSE); + + /** + * Creates a new <code>FunctionDefinitionBase</code> with the {@link com.att.research.xacml.api.Identifier} <code>idIn</code> as + * the function id. + * + * @param idIn the <code>Identifier</code> for this <code>FunctionDefinitionBase</code> + */ + protected FunctionDefinitionBase(Identifier idIn, DataType<O> returnDataTypeIn, DataType<I> argumentDataTypeIn, boolean returnsBagIn) { + this.id = idIn; + this.dataTypeReturn = returnDataTypeIn; + this.dataTypeArgs = argumentDataTypeIn; + this.returnsBag = returnsBagIn; + } + + /** + * Returns a shortened version of the Id for this function, primarilly for use with error messages to prevent them from becoming too long. + * This is a simple convenience method to reduce code bloat. + * + * @return + */ + public String getShortFunctionId() { + return this.getId().getUri().toString().substring(this.getId().getUri().toString().indexOf("function:")); + } + + /** + * Returns a shortened version of the given DataType Id, primarily for use with error messages to prevent them from becoming too long. + * This is a simple convenience method to reduce code bloat. + * + * @param identifier expected to have '#' in it, and if no '#' should have ":data-type:" + * @return + */ + public String getShortDataTypeId(Identifier identifier) { + String idString = identifier.stringValue(); + int index = idString.indexOf("#"); + if (index < 0) { + index = idString.indexOf(":data-type:"); + if (index < 0) { + return idString; + } else { + return idString.substring(index + 11); + } + } else { + return idString.substring(index+1); + } + } + + /** + * Return a new Status that includes the name of this function in front of the original status' message. + * This is a convenience method to reduce code bloat. + * + * @param originalStatu + * @return + */ + public Status getFunctionStatus(Status originalStatus) { + return new StdStatus(originalStatus.getStatusCode(), getShortFunctionId() + " " + originalStatus.getStatusMessage()); + } + + + // + // Getters for the internal variables + // + + @Override + public Identifier getId() { + return this.id; + } + + @Override + public Identifier getDataTypeId() { + if (this.dataTypeReturn == null) { + return null; + } else { + return this.dataTypeReturn.getId(); + } + } + + public DataType<O> getDataType() { + return this.dataTypeReturn; + } + + /** + * Return the Identifier for the Input Argument(s) DataType. + * + * @return + */ + public DataType<I> getDataTypeArgs() { + return this.dataTypeArgs; + } + + @Override + public boolean returnsBag() { + return returnsBag; + } + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java new file mode 100755 index 0000000..a6af460 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
@@ -0,0 +1,136 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.ArrayList; +import java.util.List; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionComparison implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML comparison predicates as functions taking two arguments of the same type + * and returning a <code>Boolean</code>. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * integer-greater-than + * integer-greater-than-or-equal + * integer-less-than + * integer-less-than-or-equal + * double-greater-than + * double-greater-than-or-equal + * double-less-than + * double-less-than-or-equal + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments + */ +public class FunctionDefinitionComparison<I extends Comparable<I>> extends FunctionDefinitionHomogeneousSimple<Boolean, I> { + + /** + * List of comparison operations. + * + * @author glenngriffin + * + */ + public enum OPERATION {GREATER_THAN, GREATER_THAN_EQUAL, LESS_THAN, LESS_THAN_EQUAL }; + + // the operation for this instance of the class + private OPERATION operation; + + + /** + * Constructor - need dataType input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionComparison(Identifier idIn, DataType<I> dataTypeArgsIn, OPERATION opIn) { + super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 2); + operation = opIn; + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + List<I> convertedArguments = new ArrayList<I>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + int compareResult; + try { + compareResult = ((I)convertedArguments.get(0)).compareTo((I)convertedArguments.get(1)); + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + + switch (operation) { + case GREATER_THAN: + if (compareResult > 0) { + return ER_TRUE; + } else { + return ER_FALSE; + } + + case GREATER_THAN_EQUAL: + if (compareResult > -1) { + return ER_TRUE; + } else { + return ER_FALSE; + } + + case LESS_THAN: + if (compareResult < 0) { + return ER_TRUE; + } else { + return ER_FALSE; + } + + case LESS_THAN_EQUAL: + if (compareResult < 1) { + return ER_TRUE; + } else { + return ER_FALSE; + } + } + + // switch on enum should handle everything - should never get here + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " ENUM did not cover case of " + operation)); + + } + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java new file mode 100755 index 0000000..5530065 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
@@ -0,0 +1,125 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + + +import java.util.List; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.IDateTime; +import com.att.research.xacml.std.datatypes.ISO8601Duration; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionDateTimeArithmetic implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML Date and Time Arithmetic predicates. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * dateTime-add-dayTimeDuration + * dateTime-add-yearMonthDuration + * dateTime-subtract-dayTimeDuration + * dateTime-subtract-yearMonthDuration + * date-add-yearMonthDuration + * date-subtract-yearMonthDuration + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments; + * SPECIAL CASE: this applies ONLY to the 2nd argument. + * @param <O> the java class for the data type of the function Output; + * SPECIAL CASE: this ALSO applies to the type of the 1st Input argument. + */ +public class FunctionDefinitionDateTimeArithmetic<O extends IDateTime<O>, I extends ISO8601Duration> extends FunctionDefinitionBase<O, I> { + + /** + * List of Date and Time Arithmetic operations. + * + * @author glenngriffin + * + */ + public enum OPERATION {ADD, SUBTRACT}; + + // operation to be used in this instance of the class + private final OPERATION operation; + + + + /** + * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionDateTimeArithmetic(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION op) { + super(idIn, dataTypeIn, dataTypeArgsIn, false); + this.operation = op; + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + if (arguments == null || arguments.size() != 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Expected 2 arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + // first arg has same type as function output + FunctionArgument functionArgument = arguments.get(0); + ConvertedArgument<O> convertedArgument0 = new ConvertedArgument<O>(functionArgument, this.getDataType(), false); + if ( ! convertedArgument0.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus())); + } + O idateOrig = convertedArgument0.getValue(); + + // second argument is of input type + functionArgument = arguments.get(1); + ConvertedArgument<I> convertedArgument1 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false); + if ( ! convertedArgument1.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument1.getStatus())); + } + // get the Duration object from the argument which includes all fields, even if the incoming argument does not include them all + ISO8601Duration duration = convertedArgument1.getValue(); + + // add/subtract the duration to the input argument + // + O idateResult = null; + switch(this.operation) { + case ADD: + idateResult = idateOrig.add(duration); + break; + case SUBTRACT: + idateResult = idateOrig.sub(duration); + break; + } + ExpressionResult expressionResult = null; + try { + expressionResult = ExpressionResult.newSingle(this.getDataType().createAttributeValue(idateResult)); + } catch (DataTypeException e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + return expressionResult; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java new file mode 100755 index 0000000..af5c1e6 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
@@ -0,0 +1,88 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.ArrayList; +import java.util.List; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionEquality extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to + * implement the XACML Equality predicates as functions taking two arguments of the same data type and returning a <code>Boolean</code>. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-equal + * boolean-equal + * integer-equal + * double-equal + * date-equal + * time-equal + * dateTime-equal + * dayTimeDuration-equal + * yearMonthDuration-equal + * anyURI-equal + * + * @author car + * @version $Revision: 1.2 $ + * + * @param <I> the java class for the data type of the function Input arguments + */ +public class FunctionDefinitionEquality<I> extends FunctionDefinitionHomogeneousSimple<Boolean, I> { + + /** + * Determines if the two <code>T</code> values are equal using the java <code>equals</code> method. Derived classes + * may override this if the <code>equals</code> method is not sufficient. + * + * @param v1 the first object to compare + * @param v2 the second object to compare + * @return true if the two objects are the same, else false + */ + protected boolean isEqual(I v1, I v2) { + return v1.equals(v2); + } + + public FunctionDefinitionEquality(Identifier idIn, DataType<I> dataTypeArgsIn) { + super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 2); + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + List<I> convertedArguments = new ArrayList<I>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + /* + * Now just perform the equality operation. + */ + if (this.isEqual(convertedArguments.get(0), convertedArguments.get(1))) { + return ER_TRUE; + } else { + return ER_FALSE; + } + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java new file mode 100755 index 0000000..515cbd5 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
@@ -0,0 +1,523 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition; +import com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory; + +/** + * FunctionDefinitionSet implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML Set predicates as functions taking two arguments of <code>Bag</code> the same primitive type + * and returning either a <code>Boolean</code> or a <code>Bag</code> of the same primitive type. + * <P> + * The ipAddress, dnsName and xPathExpression do not have set functions defined for them in section 10.2.8 of the Release 3 XACML spec. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-bag + * boolean-bag + * integer-bag + * double-bag + * time-bag + * date-bag + * dateTime-bag + * anyURI-bag + * hexBinary-bag + * base64Binary-bag + * dayTimeDuration-bag (version 1 and3) + * yearMonthDuration-bag (version 1 and 3) + * x500Name-bag + * rfc822Name-bag + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments + * @param <O> the java class for the data type of the function Output + */ +public class FunctionDefinitionHigherOrderBag<O,I> extends FunctionDefinitionBase<O, I> { + + /** + * List of comparison operations. + * + * @author glenngriffin + * + */ + public enum OPERATION {ANY_OF, ALL_OF, ANY_OF_ANY, ALL_OF_ANY, ANY_OF_ALL, ALL_OF_ALL, MAP }; + + // the operation for this instance of the class + private OPERATION operation; + + + /** + * Constructor - need dataType input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionHigherOrderBag(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn) { + super(idIn, dataTypeIn, dataTypeArgsIn, ((opIn == OPERATION.MAP) ? true : false) ); + operation = opIn; + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + // simple argument check + if (arguments == null || arguments.size() < 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Expected at least 2 arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + // three functions have some things known about the arguments + if (operation == OPERATION.ALL_OF_ANY || operation == OPERATION.ANY_OF_ALL || operation == OPERATION.ALL_OF_ALL) { + if (arguments.size() != 3) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Expected 3 arguments, got " + arguments.size()) ); + } + // the 2nd & 3rd arguments must both be bags + if ( arguments.get(1) == null || ! arguments.get(1).isBag() ) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " 2nd argument must be bag, got '" + ((arguments.get(1) == null) ? "null" : this.getShortDataTypeId(arguments.get(1).getValue().getDataTypeId())) + "'" )); + } + if (arguments.get(2) == null || ! arguments.get(2).isBag() ) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " 3rd argument must be bag, got '" + ((arguments.get(2) == null) ? "null" : this.getShortDataTypeId(arguments.get(2).getValue().getDataTypeId())) + "'" )); + } + } + + // first argument is supposed to be a Function ID passed to us as an AnyURI + FunctionArgument functionIdArgument = arguments.get(0); + if (functionIdArgument == null || functionIdArgument.getValue() == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate Function (first argument) was null")); + } + if ( ! functionIdArgument.getValue().getDataTypeId().equals(DataTypes.DT_ANYURI.getId())) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " First argument expected URI, got " + functionIdArgument.getValue().getDataTypeId() ) ); + } + Identifier functionId = new IdentifierImpl((URI) functionIdArgument.getValue().getValue()); + + // look up the actual function definition based on that ID + StdFunctionDefinitionFactory fdf = new StdFunctionDefinitionFactory(); + + FunctionDefinition predicate = fdf.getFunctionDefinition(functionId); + + if (predicate == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " First argument was not URI of a function, got '" + functionId + "'") ); + } + // in all cases except MAP, the predicate must return True/False + if (operation != OPERATION.MAP) { + if ( ! predicate.getDataTypeId().equals(DataTypes.DT_BOOLEAN.getId())) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate Function must return boolean, but '" + predicate.getId() + "' returns '" + this.getShortDataTypeId(predicate.getDataTypeId()) )); + } + } + + + + // The remaining arguments may be either bags or primitive types. + // We do not know what the primitive types will be, and do not concern ourselves about that here + // (the predicate function we just got and will call later will complain if they do not match its expectations). + // The predicate function will want things as FunctionAttributes, so we do not need to unwrap anything. + boolean bagSeen = false; + for (int i = 1; i < arguments.size(); i++) { + FunctionArgument argument = arguments.get(i); + if (argument == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Got null argument at index " + i) ); + } + // force evaluation and check status + if ( ! argument.getStatus().isOk()) { + return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); + } + + // for bags, remember that we saw one; for non-bag primitives, check that the primitive value is not null + if (argument.isBag()) { + bagSeen = true; + } else { + if (argument.getValue() == null || argument.getValue().getValue() == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Got null attribute at index " + i) ); + } + } + } + + // all functions require at least one bag + if ( ! bagSeen && operation != OPERATION.ANY_OF_ANY) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Did not get any Bag argument; must have at least 1") ); + } + + + // arguments are ready for use + + // list of arguments for passing to the predicate + List<FunctionArgument> predicateArguments = new ArrayList<FunctionArgument>(); + + // for functions that take a single bag, which index is that bag at + int indexOfBagInOriginalArgs = -1; + + // bag iterator + Iterator<AttributeValue<?>> bagIterator1; + Iterator<AttributeValue<?>> bagIterator2; + + + + + switch (operation) { + + case ANY_OF: + // Copy the primitive arguments to the list for passing to the predicate, + // putting a place-holder in for the value from the (single) bag + for (int i = 1; i < arguments.size(); i++) { + predicateArguments.add(arguments.get(i)); + if (arguments.get(i).isBag()) { + if (indexOfBagInOriginalArgs == -1) { + indexOfBagInOriginalArgs = i ; + } else { + // bag already found - we should have only one + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); + } + } + } + + // get each primitive value in turn + bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); + while (bagIterator1.hasNext()) { + // all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list + predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); + ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); + if ( ! res.isOk()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate error: " + res.getStatus().getStatusMessage()) ); + } + if ( (Boolean)(res.getValue().getValue()) == true) { + return ER_TRUE; + } + } + + return ER_FALSE; + + + + case ALL_OF: + // Copy the primitive arguments to the list for passing to the predicate, + // putting a place-holder in for the value from the (single) bag + for (int i = 1; i < arguments.size(); i++) { + predicateArguments.add(arguments.get(i)); + if (arguments.get(i).isBag()) { + if (indexOfBagInOriginalArgs == -1) { + indexOfBagInOriginalArgs = i ; + } else { + // bag already found - we should have only one + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); + } + } + } + + // get each primitive value in turn + bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); + while (bagIterator1.hasNext()) { + // all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list + predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); + ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); + if ( ! res.isOk()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate error: " + res.getStatus().getStatusMessage()) ); + } + if ( (Boolean)(res.getValue().getValue()) == false) { + return ER_FALSE; + } + } + return ER_TRUE; + + + case ANY_OF_ANY: + // empty bags can give odd error messages, so check here and return something that makes more sense + for (int i = 1; i < arguments.size(); i++) { + if (arguments.get(i).isBag() && arguments.get(i).getBag().size() == 0) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Bag is empty at index " + i )); + } + } + // This is different from all the other Higher-order bag functions because it can take an unbounded number of arguments any/all of which may be bags. + // (The others take either an unbounded number of args of which exactly 1 is a bag, or they take exactly 2 bags) + // To handle the possibility of multiple bags without knowing a priori how many there might be, + // we first create all possible lists of arguments to be passed to the predicate. + // This is done using a depth-first search of the total argument space. + List<List<FunctionArgument>> listOfPredicateLists = new ArrayList<List<FunctionArgument>>(); + + /* + * Start the recursive append process + */ + appendCrossProduct(new ArrayList<FunctionArgument>(), arguments.subList(1, arguments.size()), 0, listOfPredicateLists); + + // we now have all possible argument lists for the predicate to work on, so do the ANY operation now + for (List<FunctionArgument> predicateArgumentList : listOfPredicateLists) { + // all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list + ExpressionResult res = predicate.evaluate(evaluationContext, predicateArgumentList); + if ( ! res.isOk()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate error: " + res.getStatus().getStatusMessage()) ); + } + if ( (Boolean)(res.getValue().getValue()) == true) { + return ER_TRUE; + } + } + + // if we get here then none of the combinations gave a TRUE result + return ER_FALSE; + + + + case ALL_OF_ANY: +//TODO - it might be more efficient to extract all the attributes from the first bag and convert them to FunctionArguments just once, then use that list each time + + // get the element from the 2nd bag that we want to check all elements from the 1st bag against + bagIterator2 = arguments.get(2).getBag().getAttributeValues(); + while (bagIterator2.hasNext()) { + FunctionArgument predicateArgument2 = new FunctionArgumentAttributeValue(bagIterator2.next()); + boolean allMatch = true; + + // now look at every value of the first bag operating with the selected value from the 2nd + bagIterator1 = arguments.get(1).getBag().getAttributeValues(); + while (bagIterator1.hasNext()) { + + predicateArguments.clear(); + predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator1.next())); + predicateArguments.add(predicateArgument2); + + ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); + if ( ! res.isOk()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate error: " + res.getStatus().getStatusMessage()) ); + } + if ( (Boolean)(res.getValue().getValue()) == false) { + allMatch = false; + break; + } + } + if (allMatch) { + // wee found one value in bag2 that works (is TRUE) for all values in bag1 + return ER_TRUE; + } + // this value from bag2 did not work, so get the next one + } + + // no value in bag2 worked for all values of bag1 + return ER_FALSE; + + + + case ANY_OF_ALL: +//TODO - it might be more efficient to extract all the attributes from the 2nd bag and convert them to FunctionArguments just once, then use that list each time + + // get the element from the 1st bag that we want to check all elements from the 1st bag against + bagIterator1 = arguments.get(1).getBag().getAttributeValues(); + while (bagIterator1.hasNext()) { + FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); + boolean allMatch = true; + + // now look at every value of the 2nd bag operating with the selected value from the first + bagIterator2 = arguments.get(2).getBag().getAttributeValues(); + while (bagIterator2.hasNext()) { + predicateArguments.clear(); + predicateArguments.add(predicateArgument1); + predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); + + ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); + if ( ! res.isOk()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate error: " + res.getStatus().getStatusMessage()) ); + } + if ( (Boolean)(res.getValue().getValue()) == false) { + allMatch = false; + break; + } + } + if (allMatch) { + // wee found one value in bag1 that works (is TRUE) for all values in bag2 + return ER_TRUE; + } + // this value from bag1 did not work, so get the next one + } + + // no value in bag1 worked for all values of bag2 + return ER_FALSE; + + + + case ALL_OF_ALL: +//TODO - it might be more efficient to extract all the attributes from the 2nd bag and convert them to FunctionArguments just once, then use that list each time + + // get the element from the 1st bag that we want to check all elements from the 1st bag against + bagIterator1 = arguments.get(1).getBag().getAttributeValues(); + while (bagIterator1.hasNext()) { + FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); + + // now look at every value of the 2nd bag operating with the selected value from the first + bagIterator2 = arguments.get(2).getBag().getAttributeValues(); + while (bagIterator2.hasNext()) { + predicateArguments.clear(); + predicateArguments.add(predicateArgument1); + predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); + + ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); + if ( ! res.isOk()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate error: " + res.getStatus().getStatusMessage()) ); + } + + if ( (Boolean)(res.getValue().getValue()) == false) { + return ER_FALSE; + } + } + // this value did not fail, so try the next + } + + // everything in bag1 worked (was true) for everything in bag 2 + return ER_TRUE; + + + + case MAP: + // Copy the primitive arguments to the list for passing to the predicate, + // putting a place-holder in for the value from the (single) bag + for (int i = 1; i < arguments.size(); i++) { + predicateArguments.add(arguments.get(i)); + if (arguments.get(i).isBag()) { + if (indexOfBagInOriginalArgs == -1) { + indexOfBagInOriginalArgs = i ; + } else { + // bag already found - we should have only one + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); + } + } + } + + Bag outputBag = new Bag(); + + // get each primitive value in turn + bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); + while (bagIterator1.hasNext()) { + // all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list + predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); + ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); + if ( ! res.isOk()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Predicate error: " + res.getStatus().getStatusMessage()) ); + } + if (res.isBag()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Cannot put bag inside bag; predicate was '" + predicate.getId() + "'")); + } + outputBag.add(res.getValue()); + } + + + return ExpressionResult.newBag(outputBag); + + } + + // all cases should have been covered by above - should never get here + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Higher-Order Bag function " + operation)); + + } + + + + + + + + + + + + + /** + * Performs the depth-first walk to generate argument lists. Needed by any-of-any because of the variable number of bags it might get. + * + * This code was salvaged from the R2 version of the product and adjusted to fit the new way of doing business. + * + * @param argListInProgress the current argument list being generated in this pass + * @param valueList the list of expression result values + * @param nPosition the position within the expression result values to use to append to the base argument list + * @param listArgLists the <code>List</code> where final argument lists are appended + */ + private static void appendCrossProduct(List<FunctionArgument> argListInProgress, List<FunctionArgument> valueList, int nPosition, List<List<FunctionArgument>> listArgLists) { + /* + * Have we hit a leaf? + */ + if (nPosition >= valueList.size()) { + List<FunctionArgument> copy = new ArrayList<FunctionArgument>(); + copy.addAll(argListInProgress); + listArgLists.add(copy); + return; + } + + /* + * Check to see if the value at the current position is a primitive or a bag + */ + FunctionArgument FunctionArgument = valueList.get(nPosition); + if (FunctionArgument.isBag() && FunctionArgument.getBag().getAttributeValues() != null && FunctionArgument.getBag().size() > 0) { + Iterator<AttributeValue<?>> iterBagValues = FunctionArgument.getBag().getAttributeValues(); + while (iterBagValues.hasNext()) { + AttributeValue<?> attributeValue = iterBagValues.next(); + FunctionArgument functionArgument = new FunctionArgumentAttributeValue(attributeValue); + argListInProgress.add(functionArgument); + appendCrossProduct(argListInProgress, valueList, nPosition+1, listArgLists); + argListInProgress.remove(argListInProgress.size()-1); + } + } else { + /* + * This is a simple value, so we can just append to the argListInProgress and continue the recursion + */ + argListInProgress.add(FunctionArgument); + appendCrossProduct(argListInProgress, valueList, nPosition+1, listArgLists); + argListInProgress.remove(argListInProgress.size()-1); + } + } + + + + + + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java new file mode 100755 index 0000000..a41ccbe --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
@@ -0,0 +1,142 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.List; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionHomogeneousSimple extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSimple} + * with utility methods for ensuring the types of the arguments passed in the <code>evaluate</code> method matches the parameterized + * type, and the number of arguments is correct. + * When evaluated the resulting arguments must be simple data types, not bags. + * + * The various functions have the following needs with respect to their arguments: + * <UL> + * <LI> + * The argument list size is pre-defined and all arguments can be evaluated at once before the function is called. + * <LI> + * The argument list size is pre-defined but the arguments must be evaluated one at a time by the function. + * <LI> + * The argument list size is not pre-defined. + * </UL> + * To support those needs this class includes methods for checking the list size and evaluating a single argument as well as + * combining those operations in a single method to make it simpler for the calling function. + * + * @author car + * @version $Revision: 1.3 $ + * + * @param <O> the java class for the value of the Output return result from the <code>FunctionDefinition</code> + * @param <I> the java class for the value of the Input {@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s in the <code>evaluate</code> method + */ +public abstract class FunctionDefinitionHomogeneousSimple<O,I> extends FunctionDefinitionBase<O,I> { + + + // null means that number of arguments is variable + private Integer numArgs; + + /** + * Constructor + * + * @param idIn + * @param dataTypeReturnIn + * @param dataTypeArgsIn + * @param nArgs + */ + public FunctionDefinitionHomogeneousSimple(Identifier idIn, DataType<O> dataTypeReturnIn, DataType<I> dataTypeArgsIn, Integer nArgs) { + super(idIn, dataTypeReturnIn, dataTypeArgsIn, false); + this.numArgs = nArgs; + } + + + /** + * Gets the number of arguments expected to this <code>FunctionDefinition</code>. + * For functions without a pre-defined number of arguments this is not used. + * + * @return the number of arguments expected to this <code>FunctionDefinition</code>. + */ + public Integer getNumArgs() { + return this.numArgs; + } + + + /** + * Validates the given <code>List</code> of <code>FunctionArgument</code>s has the correct count and <code>DataType</code> and evaluates expressions. + * This combines both the argument list length check and the evaluation of all arguments on that list. + * + * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate + * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid + */ + public Status validateArguments(List<FunctionArgument> listFunctionArguments, List<I> convertedValues) { + /* + * See if we have to validate the number of arguments + */ + Status listLengthStatus = validateArgumentListLength(listFunctionArguments); + if ( ! listLengthStatus.isOk()) { + return listLengthStatus; + } + + + /* + * Now validate the types of the arguments + */ + for (int i = 0; i < listFunctionArguments.size(); i++) { + FunctionArgument functionArgument = listFunctionArguments.get(i); + ConvertedArgument<I> argument = new ConvertedArgument<I>(functionArgument, getDataTypeArgs(), false); + if ( ! argument.isOk()) { + // when a Status is returned that indicates an error, tell caller which arg had problem + Status decoratedStatus = new StdStatus(argument.getStatus().getStatusCode(), argument.getStatus().getStatusMessage() + " at arg index " + i ); + return decoratedStatus; + } + if (convertedValues != null) { + convertedValues.add(argument.getValue()); + } + } + + /* + * Everything passed the data type test, so we are good to go + */ + return StdStatus.STATUS_OK; + } + + + /** + * Validates the given <code>List</code> of <code>FunctionArgument</code>s has the correct count. + * + * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate + * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid + */ + public Status validateArgumentListLength(List<FunctionArgument> listFunctionArguments) { + /* + * See if we have to validate the number of arguments + */ + if ((listFunctionArguments == null && this.numArgs > 0 ) || + (listFunctionArguments != null && this.numArgs != listFunctionArguments.size()) ) { + return new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected " + this.numArgs + " arguments, got " + + ((listFunctionArguments == null) ? 0 : listFunctionArguments.size()) ); + } + + /* + * Everything passed the data type test, so we are good to go + */ + return StdStatus.STATUS_OK; + } + + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java new file mode 100755 index 0000000..a99456b --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
@@ -0,0 +1,219 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionLogical extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to + * implement the XACML Logic predicates as functions taking zero, one, or multiple arguments of type <code>Boolean</code> and returning a <code>Boolean</code>. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * or + * and + * n-of + * not + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + */ +public class FunctionDefinitionLogical extends FunctionDefinitionHomogeneousSimple<Boolean,Boolean> { + + /** + * List of Logical Operations types + * + * @author glenngriffin + * + */ + public enum OPERATION {OR, AND, N_OF, NOT} + + // the operation that this instance is being asked to do + private final OPERATION operation; + + + public FunctionDefinitionLogical(Identifier idIn, OPERATION op) { + super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, null); + operation = op; + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + switch (operation) { + case OR: + if (arguments == null || arguments.size() == 0) { + return ER_FALSE; + } + try { + // evaluate the arguments one at a time and abort on the first true + for (int i = 0; i < arguments.size(); i++) { + ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false); + if ( ! argument.isOk()) { + // return a decorated message + return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); + } + if (argument.getValue() == true) { + return ER_TRUE; + } + } + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + return ER_FALSE; + + + case AND: + if (arguments == null || arguments.size() == 0) { + return ER_TRUE; + } + try { + // evaluate the arguments one at a time and abort on the first false + for (int i = 0; i < arguments.size(); i++) { + ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false); + if ( ! argument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); + } + if (argument.getValue() == false) { + return ER_FALSE; + } + } + + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + return ER_TRUE; + + + case N_OF: + Integer argumentCountNeeded; + int trueArgumentsSeen = 0; + if (arguments == null || arguments.size() == 0) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got 0")); + } + try { + // + // Special case: + // The first argument in the list (an Integer) is not homogeneous with the rest of the arguments (Booleans). + // While this is technically not a FunctionDefinitionHomogeneousSimple type of object, we derive from that class anyway + // so that we can take advantage of the validateArgument() method in that class. + // Unfortunately we cannot re-use that same code (because of generics - it gets messy) for the Integer argument. + // The following code essentially does the same job as validateArgument() on the first argument in the list. + // + + // first arg is the number of remaining arguments that must be TRUE + if (arguments.get(0) == null) { + return ER_TRUE; + } + if ( ! arguments.get(0).getStatus().isOk()) { + return ExpressionResult.newError(getFunctionStatus(arguments.get(0).getStatus())); + } + if (arguments.get(0).isBag()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected a simple value, saw a bag")); + } + AttributeValue<?> attributeValue = arguments.get(0).getValue(); + if (attributeValue == null) { + // assume this is the same as "first argument is 0" + return ER_TRUE; + } + + argumentCountNeeded = DataTypes.DT_INTEGER.convert(attributeValue.getValue()).intValue(); + if (argumentCountNeeded == 0) { + return ER_TRUE; + } + if (arguments.size() - 1 < argumentCountNeeded) { + // return a non-OK status to signal indeterminate + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Expected " + argumentCountNeeded + " arguments but only " + + (arguments.size() - 1) + " arguments in list after the count")); + } + for (int i = 1; i < arguments.size(); i++) { + ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false); + if ( ! argument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); + } + if ((argument.getValue()) == true) { + trueArgumentsSeen++; + if (trueArgumentsSeen >= argumentCountNeeded) { + return ER_TRUE; + } + } + // if we cannot reach the goal, stop now. + // remaining entries to be looked at = list size - i - 1, which is the most additional TRUEs that we could get. + if ( (arguments.size() - i - 1) + trueArgumentsSeen < argumentCountNeeded) { + // do not evaluate remaining entries + return ER_FALSE; + } + } + // did not reach our goal + return ER_FALSE; + + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + + + case NOT: + if (arguments == null || arguments.size() != 1) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got " + + ((arguments == null) ? "null" : arguments.size()) ) ); + } + try { + ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(0), this.getDataTypeArgs(), false); + if ( ! argument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); + } + if (argument.getValue() == true) { + return ER_FALSE; + } else { + return ER_TRUE; + } + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + } + + // all cases should have been covered by above - should never get here + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Logical function " + operation)); + + } + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java new file mode 100755 index 0000000..ce5ec07 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
@@ -0,0 +1,90 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionNumberTypeConversion extends {@link FunctionDefinitionHomogeneousSimple} to + * implement the XACML predicates foc converting <code>Double</code> to <code>Integer</code> and vice versa. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * double-to-integer + * integer-to-double + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <O> the java class for the data type of the function Output + * @param <I> the java class for the data type of the function Input argument + */ +public class FunctionDefinitionNumberTypeConversion<O extends Number, I extends Number> extends FunctionDefinitionHomogeneousSimple<O, I> { + + + public FunctionDefinitionNumberTypeConversion(Identifier idIn, DataType<O> outputType, DataType<I> argType) { + super(idIn, outputType, argType, 1); + + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + List<I> convertedArguments = new ArrayList<I>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + /* + * Numeric operations cannot be operated on generically in java, so we have to check the types and handle separately. + * Whichever type the argument is, convert it to the other + */ + ExpressionResult expressionResult; + try { + if (convertedArguments.get(0).getClass() == BigInteger.class) { + AttributeValue<Double> doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, + new Double( ((BigInteger)convertedArguments.get(0)).toString() ) ); + expressionResult = ExpressionResult.newSingle(doubleResult); + } else { + AttributeValue<BigInteger> integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, BigInteger.valueOf(((Double)convertedArguments.get(0)).intValue()) ); + expressionResult = ExpressionResult.newSingle(integerResult); + } + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + + return expressionResult; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java new file mode 100755 index 0000000..5015204 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
@@ -0,0 +1,141 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.List; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.RFC822Name; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionRFC822NameMatch extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to + * implement the XACML RFC822Name match predicate as functions taking one <code>String</code> and one <code>RFC822Name</code> arguments + * and returning a single <code>Boolean</code> value. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * rfc822Name-match + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + */ +public class FunctionDefinitionRFC822NameMatch extends FunctionDefinitionBase<Boolean, RFC822Name> { + + + /** + * Constructor + * + * @param idIn + * @param dataTypeArgsIn + * @param op + */ + public FunctionDefinitionRFC822NameMatch(Identifier idIn) { + super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, false); + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + if (arguments == null || arguments.size() != 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + " Expected 2 arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + // get the string to search for + ConvertedArgument<String> stringArgument = new ConvertedArgument<String>(arguments.get(0), DataTypes.DT_STRING, false); + if ( ! stringArgument.isOk()) { + Status decoratedStatus = new StdStatus(stringArgument.getStatus().getStatusCode(), stringArgument.getStatus().getStatusMessage() + " at arg index 0" ); + return ExpressionResult.newError(getFunctionStatus(decoratedStatus)); + } + String searchTermString = stringArgument.getValue(); + + // get the RFC822Name to match with + ConvertedArgument<RFC822Name> rfc822Argument = new ConvertedArgument<RFC822Name>(arguments.get(1), DataTypes.DT_RFC822NAME, false); + if ( ! rfc822Argument.isOk()) { + Status decoratedStatus = new StdStatus(rfc822Argument.getStatus().getStatusCode(), rfc822Argument.getStatus().getStatusMessage() + " at arg index 1" ); + return ExpressionResult.newError(getFunctionStatus(decoratedStatus)); + } + + RFC822Name rfc822Name = rfc822Argument.getValue(); + + + /* + * Now perform the match. + */ + + /* + * According to the spec the string must be one of the following 3 things: + * - a name with an '@' in it = a full name that must exactly match the whole RFC name (domain part is ignore case) + * - a domain name (without an '@' and not starting with a '.') = must match whole RFC domain name (ignore case) + * - a partial domain name (without an '@') starting with a '.' = the last part of the RFC domain name (ignore case) + */ + + String[] searchTerms = searchTermString.split("@"); + + if (searchTerms.length > 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + + " String contained more than 1 '@' in '" + searchTermString + "'" )); + } + + if (searchTerms.length == 2 || searchTermString.endsWith("@")) { + // this is an exact match + if (searchTerms[0] == null || searchTerms[0].length() == 0) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + + " String missing local part in '" + searchTermString + "'" )); + } + if (searchTerms.length < 2 || searchTerms[1] == null || searchTerms[1].length() == 0) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + + " String missing domain part in '" + searchTermString + "'" )); + } + + // args are ok, so check both against RFC name + if (searchTerms[0].equals(rfc822Name.getLocalName()) && + searchTerms[1].toLowerCase().equals(rfc822Name.getCanonicalDomainName())) { + return ER_TRUE; + } else { + return ER_FALSE; + } + } + + // we have only a domain name, which may be whole or partial + + // make it match the canonical version + searchTerms[0] = searchTerms[0].toLowerCase(); + + if (searchTerms[0].charAt(0) == '.') { + // name is partial - must match the end + if (rfc822Name.getCanonicalDomainName().endsWith(searchTerms[0])) { + return ER_TRUE; + } else { + return ER_FALSE; + } + } else { + // name is whole domain - must match exactly + if (rfc822Name.getCanonicalDomainName().equals(searchTerms[0])) { + return ER_TRUE; + } else { + return ER_FALSE; + } + } + + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java new file mode 100755 index 0000000..ad442ae --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java
@@ -0,0 +1,117 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + + +import java.util.List; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionRegexMatch implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML 'type'-regex-match predicates as functions taking two arguments, the first of <code>String</code>, + * representing a regular expression, and the second of the type for that specific predicate, + * and returning a <code>Boolean</code> for whether the regular expression matches the string representation of the second argument. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-regexp-match + * anyURI-regexp-match + * x500Name-regexp-match + * rfc822Name-regexp-match (in sub-class {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition.FunctionDefinitionRegexpMatchRFC822} ) + * ipAddress-regexp-match + * dnsName-regexp-match + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments + */ +public class FunctionDefinitionRegexpMatch<I> extends FunctionDefinitionBase<Boolean, I> { + + + /** + * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionRegexpMatch(Identifier idIn, DataType<I> dataTypeArgsIn) { + super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, false); + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + if (arguments == null || arguments.size() != 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 2 arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + // get the regular expression + FunctionArgument regexpArgument = arguments.get(0); + + ConvertedArgument<String> convertedArgument = new ConvertedArgument<String>(regexpArgument, DataTypes.DT_STRING, false); + if ( ! convertedArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus())); + } + + // String regexpValue = (String)regexpArgument.getValue().getValue(); + String regexpValue = convertedArgument.getValue(); + + + // now get the element to match + FunctionArgument elementArgument = arguments.get(1); + + ConvertedArgument<I> convertedElement = new ConvertedArgument<I>(elementArgument, this.getDataTypeArgs(), false); + if ( ! convertedElement.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedElement.getStatus())); + } + + I elementValueObject = convertedElement.getValue(); + + String elementValueString; + try { + elementValueString = this.getDataTypeArgs().toStringValue(elementValueObject); + } catch (DataTypeException e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + + // ConvertedArgument checks for null value, so do not need to do again here + + if (elementValueString.matches(regexpValue)) { + return ER_TRUE; + } else { + return ER_FALSE; + } + + } + + + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java new file mode 100755 index 0000000..1595a47 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java
@@ -0,0 +1,230 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.ArrayList; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionSet implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML Set predicates as functions taking two arguments of <code>Bag</code> the same primitive type + * and returning either a <code>Boolean</code> or a <code>Bag</code> of the same primitive type. + * <P> + * The ipAddress, dnsName and xPathExpression do not have set functions defined for them in section 10.2.8 of the Release 3 XACML spec. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-bag + * boolean-bag + * integer-bag + * double-bag + * time-bag + * date-bag + * dateTime-bag + * anyURI-bag + * hexBinary-bag + * base64Binary-bag + * dayTimeDuration-bag (version 1 and3) + * yearMonthDuration-bag (version 1 and 3) + * x500Name-bag + * rfc822Name-bag + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments + * @param <O> the java class for the data type of the function Output + */ +public class FunctionDefinitionSet<O,I> extends FunctionDefinitionBase<O, I> { + + /** + * List of comparison operations. + * + * @author glenngriffin + * + */ + public enum OPERATION {INTERSECTION, AT_LEAST_ONE_MEMBER_OF, UNION, SUBSET, SET_EQUALS }; + + // the operation for this instance of the class + private OPERATION operation; + + + /** + * Constructor - need dataType input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionSet(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn) { + super(idIn, dataTypeIn, dataTypeArgsIn, ((opIn == OPERATION.INTERSECTION || opIn == OPERATION.UNION) ? true : false) ); + operation = opIn; + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + if (arguments == null || arguments.size() != 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 2 arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + // get first bag + FunctionArgument bagArgument = arguments.get(0); + ConvertedArgument<Bag> convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true); + + if ( ! convertedBagArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus())); + } + + Bag bag1 = convertedBagArgument.getBag(); + List<AttributeValue<?>> list1 = (List<AttributeValue<?>>) bag1.getAttributeValueList(); + + // get second bag + bagArgument = arguments.get(1); + convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true); + + if ( ! convertedBagArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus())); + } + + Bag bag2 = convertedBagArgument.getBag(); + List<AttributeValue<?>> list2 = (List<AttributeValue<?>>) bag2.getAttributeValueList(); + + // arguments are ready BUT they have NOT had duplicates removed + + ExpressionResult expressionResult = null; + + // some functions return a bag rather than boolean + Bag outBag; + List<AttributeValue<?>> outList; + + + switch (operation) { + case INTERSECTION: + outList = new ArrayList<AttributeValue<?>>(); + + for (AttributeValue<?> element : list1) { + if (outList.contains(element)) { + continue; + } + if (list2.contains(element)) { + outList.add(element); + } + } + + // now have the intersection; put it in a bag + + outBag = new Bag(); + + for (AttributeValue<?> element : outList) { + outBag.add(element); + } + + expressionResult = ExpressionResult.newBag(outBag); + return expressionResult; + + + case AT_LEAST_ONE_MEMBER_OF: + // look for elements from the first list in the second. + // duplicates do not matter because if the element is not there it does not matter that we look for it again, + // and if it is there we stop the first time we see it. + // If the first bag is empty, this should fail because no element from the first set can be found in the second set + // (because there IS no element in first set). + for (AttributeValue<?> element : list1) { + if (list2.contains(element)) { + return ER_TRUE; + } + } + // did not find any element from list 1 in list 2 + return ER_FALSE; + + case UNION: + outList = new ArrayList<AttributeValue<?>>(); + + for (AttributeValue<?> element : list1) { + if (outList.contains(element)) { + continue; + } + outList.add((AttributeValue<?>) element); + } + for (AttributeValue<?> element : list2) { + if (outList.contains(element)) { + continue; + } + outList.add((AttributeValue<?>) element); + } + + // now have the intersection; put it in a bag + + outBag = new Bag(); + + for (AttributeValue<?> element : outList) { + outBag.add(element); + } + + expressionResult = ExpressionResult.newBag(outBag); + return expressionResult; + + + case SUBSET: + // all elements from list 1 must exist in list 2. + // duplicates do not matter because if an element is not found the first time we stop immediately, + // and if it is found the first time it will also be found for the duplicate. + // If the first set is empty we return TRUE because all elements (i.e. none) in the first set are in the second. + for (AttributeValue<?> element : list1) { + if ( ! list2.contains(element)) { + return ER_FALSE; + } + } + // all elements in list1 were found + return ER_TRUE; + + + case SET_EQUALS: + // we cannot do a direct one-to-one compare because the lists may contain duplicates. Also they may not be ordered the same. + // So we ask: + // are all elements in list 1 in list 2 (ignoring duplicates) + // are all elements in list 2 in list 1 (ignoring duplicates) + for (AttributeValue<?> element : list1) { + if ( ! list2.contains(element)) { + return ER_FALSE; + } + } + for (AttributeValue<?> element : list2) { + if ( ! list1.contains(element)) { + return ER_FALSE; + } + } + // all elements in each are part of the other + return ER_TRUE; + } + + // all cases should have been covered by above - should never get here + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Set function " + operation)); + + } + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java new file mode 100755 index 0000000..bde0bbe --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java
@@ -0,0 +1,117 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.ArrayList; +import java.util.List; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionNumberTypeConversion extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to + * implement the XACML predicates for converting <code>String</code> to <code>DataType<?></code> and vice versa. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * boolean-from-string + * string-from-boolean + * integer-from-string + * string-from-integer + * double-from-string + * string-from-double + * time-from-string + * string-from-time + * date-from-string + * string-from-date + * dateTime-from-string + * string-from-dateTime + * anyURI-from-string + * string-from-anyURI + * dayTimeDuration-from-string + * string-from-dayTimeDuration + * yearMonthDuration-from-string + * string-from-yearMonthDuration + * x500Name-from-string + * string-from-x500Name + * rfc822Name-from-string + * string-from-rfc822Name + * ipAddress-from-string + * string-from-ipAddress + * dnsName-from-string + * string-from-dnsName + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <O> the java class for the data type of the function Output + * @param <I> the java class for the data type of the function Input argument + */ +public class FunctionDefinitionStringConversion<O,I> extends FunctionDefinitionHomogeneousSimple<O, I> { + + public FunctionDefinitionStringConversion(Identifier idIn, DataType<O> outputType, DataType<I> argType) { + super(idIn, outputType, argType, 1); + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + List<I> convertedArguments = new ArrayList<I>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + /* + * Do different conversion depending on which way we are going (to/from String) + */ + if (this.getDataTypeId().equals(DataTypes.DT_STRING.getId())) { + // converting TO String + try { + String output = this.getDataTypeArgs().toStringValue(convertedArguments.get(0)); + return ExpressionResult.newSingle(new StdAttributeValue<String>(this.getDataTypeId(), output)); + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + // untested - not clear how this could happen + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + } else { + // converting FROM String to object of DataType + try { + O output = this.getDataType().convert(convertedArguments.get(0)); + return ExpressionResult.newSingle(new StdAttributeValue<O>(this.getDataTypeId(), output)); + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + " " + message )); + } + } + + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java new file mode 100755 index 0000000..b8aae7d --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java
@@ -0,0 +1,55 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.datatypes.DataTypes; + +/** + * FunctionDefinitionStringEqualIgnoreCase extends {@link FunctionDefinitionEquality} for + * <code>String</code> arguments by testing for equality without regard to case. + * + * The specification actually says that the strings are first converted to lower case using the string-normalize-to-lower-case function. + * This code ASSUMES that + * <UL> + * <LI> the normalize function just calls the Java toLowerCase() function, and + * <LI> the Java VM is consistent in that equalsIgnoreCase provides the same result as calling toLowerCase on each string and doing a compare. + * </UL> + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-equal-ignore-case + * + * + * @author car + * @version $Revision: 1.2 $ + */ +public class FunctionDefinitionStringEqualIgnoreCase extends FunctionDefinitionEquality<String> { + + /** + * ASSUMES that equalsIgnoreCase provides the same result as calling string-normalize-to-lower-case on both strings and then comparing. + */ + @Override + protected boolean isEqual(String s1, String s2) { + return s1.equalsIgnoreCase(s2); + } + + /** + * Creates a new <code>FunctionDefinitionStringEqualIgnoreCase</code> with the given <code>Identifier</code>. + * + * @param idIn the <code>Identifier</code> for the new <code>FunctionDefinitionStringEqualIgnoreCase</code> + */ + public FunctionDefinitionStringEqualIgnoreCase(Identifier idIn) { + super(idIn, DataTypes.DT_STRING); + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java new file mode 100755 index 0000000..bc5515d --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java
@@ -0,0 +1,256 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + + +import java.math.BigInteger; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionStringFunctions implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML String Functions predicates except for the conversions between <code>String</code> and <code>DataType</code> + * which are contained in <code>FunctionDefinitionStringConversion</code>. + * The functions in this file do not have a lot in common except that the return data type is known and the input argument types are + * either known or of the generic type. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-concatenate + * string-starts-with + * anyURI-starts-with + * string-ends-with + * anyURI-ends-with + * string-contains + * anyURI-contains + * string-substring + * anyURI-substring + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments + * @param <O> the java class for the data type of the function Output - + * needed because different functions within this class have different output types + */ +public class FunctionDefinitionStringFunctions<O, I> extends FunctionDefinitionBase<O, I> { + + /** + * List of String operations. + * + * @author glenngriffin + * + */ + public enum OPERATION {CONCATENATE, STARTS_WITH, ENDS_WITH, CONTAINS, SUBSTRING }; + + // operation to be used in this instance of the StringFunctions class + private final OPERATION operation; + + + /** + * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionStringFunctions(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION op) { + super(idIn, dataTypeIn, dataTypeArgsIn, false); + this.operation = op; + } + + + @SuppressWarnings("incomplete-switch") + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + if (arguments == null || + (operation == OPERATION.CONCATENATE && arguments.size() < 2) || + (operation == OPERATION.SUBSTRING && arguments.size() != 3) || + (operation != OPERATION.SUBSTRING && operation != OPERATION.CONCATENATE && arguments.size() != 2) ) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected " + + ((operation == OPERATION.SUBSTRING) ? 3 : (operation == OPERATION.CONCATENATE ? "2 or more " : 2)) + " arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + + + ExpressionResult expressionResult = null; + + String firstArgumentAsString = null; + String secondArgumentAsString = null; + + Integer secondArgumentAsInteger = null; + Integer thirdArgumentAsInteger = null; + + // most of the functions take 2 args, but SUBSTRING takes 3 AND concatenate takes 2 or more + if (operation == OPERATION.CONCATENATE) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < arguments.size(); i++) { + FunctionArgument functionArgument = arguments.get(i); + ConvertedArgument<I> convertedArgument = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false); + if ( ! convertedArgument.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus())); + } + try { + String argumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument.getValue()); + builder.append(argumentAsString); + } catch (DataTypeException e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message )); + } + } + AttributeValue<String> stringResult = new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, + builder.toString() ); + expressionResult = ExpressionResult.newSingle(stringResult); + return expressionResult; + + } else if (operation == OPERATION.SUBSTRING) { + // first arg is of generic type + FunctionArgument functionArgument = arguments.get(0); + ConvertedArgument<I> convertedArgument0 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false); + if ( ! convertedArgument0.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus())); + } + try { + firstArgumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument0.getValue()); + } catch (DataTypeException e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message )); + } + + functionArgument = arguments.get(1); + ConvertedArgument<BigInteger> convertedArgumentInt = new ConvertedArgument<BigInteger>(functionArgument, DataTypes.DT_INTEGER, false); + if ( ! convertedArgumentInt.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgumentInt.getStatus())); + } + secondArgumentAsInteger = convertedArgumentInt.getValue().intValue(); + if (secondArgumentAsInteger < 0 || secondArgumentAsInteger > firstArgumentAsString.length()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + + "Start point '" + secondArgumentAsInteger + "' out of range 0-" + firstArgumentAsString.length() + + " for string='" + firstArgumentAsString + "'")); + } + + + functionArgument = arguments.get(2); + convertedArgumentInt = new ConvertedArgument<BigInteger>(functionArgument, DataTypes.DT_INTEGER, false); + if ( ! convertedArgumentInt.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgumentInt.getStatus())); + } + thirdArgumentAsInteger = convertedArgumentInt.getValue().intValue(); + // special case: -1 means "to end of string" + if (thirdArgumentAsInteger < -1 || thirdArgumentAsInteger > firstArgumentAsString.length()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + + "End point '" + thirdArgumentAsInteger + "' out of range 0-" + firstArgumentAsString.length() + + " for string='" + firstArgumentAsString + "'")); + } + if (thirdArgumentAsInteger != -1 && thirdArgumentAsInteger < secondArgumentAsInteger) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + + "End point '" + thirdArgumentAsInteger + "' less than start point '" + secondArgumentAsString + "'" + + " for string='" + firstArgumentAsString + "'")); + } + + } else { + // expect 2 args, one String and one of Generic type + FunctionArgument functionArgument = arguments.get(0); + ConvertedArgument<String> convertedArgument0 = new ConvertedArgument<String>(functionArgument, DataTypes.DT_STRING, false); + if ( ! convertedArgument0.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus())); + } + firstArgumentAsString = convertedArgument0.getValue(); + + + functionArgument = arguments.get(1); + ConvertedArgument<I> convertedArgument1 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false); + if ( ! convertedArgument1.isOk()) { + return ExpressionResult.newError(getFunctionStatus(convertedArgument1.getStatus())); + } + try { + secondArgumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument1.getValue()); + } catch (DataTypeException e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message + + " " + message )); + } + + + } + + // arguments are ready - do the operation + + switch (operation) { + case STARTS_WITH: + if (secondArgumentAsString.startsWith(firstArgumentAsString)) { + return ER_TRUE; + } else { + return ER_FALSE; + } + + + case ENDS_WITH: + if (secondArgumentAsString.endsWith(firstArgumentAsString)) { + return ER_TRUE; + } else { + return ER_FALSE; + } + + case CONTAINS: + if (secondArgumentAsString.contains(firstArgumentAsString)) { + return ER_TRUE; + } else { + return ER_FALSE; + } + + case SUBSTRING: + String substring = null; + if (thirdArgumentAsInteger == -1) { + // from start point to end of string + substring = firstArgumentAsString.substring(secondArgumentAsInteger); + } else { + substring = firstArgumentAsString.substring(secondArgumentAsInteger, thirdArgumentAsInteger); + } + AttributeValue<String> stringResult = new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, substring); + expressionResult = ExpressionResult.newSingle(stringResult); + break; + } + + + return expressionResult; + + } + + + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java new file mode 100755 index 0000000..11d6359 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java
@@ -0,0 +1,108 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.ArrayList; +import java.util.List; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypeString; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionStringNormalize extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to + * implement the XACML String normalization predicates as functions taking one <code>String</code> arg and returning a single value of the same type. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-normalize-space + * string-normalize-to-lower-case + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + */ +public class FunctionDefinitionStringNormalize extends FunctionDefinitionHomogeneousSimple<String, String> { + + /** + * List of string normalization operations. + * + * @author glenngriffin + * + */ + public enum OPERATION {SPACE, LOWER_CASE }; + + // operation to be used in this instance of the Arightmetic class + private final OPERATION operation; + + + // result variables used by all functions + AttributeValue<String> result; + + + /** + * Constructor + * + * @param idIn + * @param dataTypeArgsIn + * @param op + */ + public FunctionDefinitionStringNormalize(Identifier idIn, OPERATION op) { + // for Arithmetic functions, the output type is the same as the input type (no mixing of Ints and Doubles!) + super(idIn, DataTypes.DT_STRING, DataTypeString.newInstance(), 1); + + // save the operation and data type to be used in this instance + operation = op; + + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + List<String> convertedArguments = new ArrayList<String>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + /* + * Now perform the requested operation. + */ + ExpressionResult expressionResult = null; + + switch (operation) { + case SPACE: + result = new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, convertedArguments.get(0).trim() ); + break; + case LOWER_CASE: + result = new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, convertedArguments.get(0).toLowerCase() ); + break; + } + + expressionResult = ExpressionResult.newSingle(result); + + return expressionResult; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java new file mode 100755 index 0000000..bf7ba8b --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java
@@ -0,0 +1,96 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.ArrayList; +import java.util.List; + +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionTimeInRange implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to + * implement the XACML time-in-range predicates as a function taking three arguments of type <code>Time</code> + * and returning a <code>Boolean</code>. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * time-in-range + * + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <I> the java class for the data type of the function Input arguments. + */ +public class FunctionDefinitionTimeInRange<I> extends FunctionDefinitionHomogeneousSimple<Boolean, I> { + + + + + /** + * Constructor - need dataType input because of java Generic type-erasure during compilation. + * + * @param idIn + * @param dataTypeArgsIn + */ + public FunctionDefinitionTimeInRange(Identifier idIn, DataType<I> dataTypeArgsIn) { + super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 3); + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + List<I> convertedArguments = new ArrayList<I>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + int compareResultLow; + int compareResultHigh; + try { + + compareResultLow = ((ISO8601Time) convertedArguments.get(1)).compareTo((ISO8601Time)convertedArguments.get(0)); + compareResultHigh = ((ISO8601Time)convertedArguments.get(2)).compareTo((ISO8601Time)convertedArguments.get(0)); + } catch (Exception e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message)); + } + + // is arg 0 within the inclusive range of the other two? + if (compareResultLow <=0 && compareResultHigh >= 0) { + return ER_TRUE; + } else { + return ER_FALSE; + } + } + + + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java new file mode 100755 index 0000000..cf9a375 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java
@@ -0,0 +1,114 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.net.URI; +import java.util.List; + +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionURIStringConcatenate extends {@link FunctionDefinitionHomogeneousSimple} to + * implement the XACML uri-string-concatenate predicate as a function taking one <code>URI</code> and one or more <code>String</code> arguments + * and returning a single <code>URI</code> value. + * + * THIS FUNCTION IS DEPRECATED IN 3.0 BUT NOT REMOVED. + * To provide backward compatibility for previously built XACML policies we include it in our R3 version. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * uri-string-concatenate + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + */ +@Deprecated +public class FunctionDefinitionURIStringConcatenate extends FunctionDefinitionBase<URI, URI> { + + + /** + * Constructor + * + * @param idIn + * @param dataTypeArgsIn + * @param op + */ + public FunctionDefinitionURIStringConcatenate(Identifier idIn) { + super(idIn, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, false); + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + if (arguments == null || arguments.size() < 2) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + " Expected 2 or more arguments, got " + + ((arguments == null) ? "null" : arguments.size()) )); + } + + // get the string to search for + ConvertedArgument<URI> uriArgument = new ConvertedArgument<URI>(arguments.get(0), DataTypes.DT_ANYURI, false); + if ( ! uriArgument.isOk()) { + Status decoratedStatus = new StdStatus(uriArgument.getStatus().getStatusCode(), uriArgument.getStatus().getStatusMessage() + " at arg index 0" ); + return ExpressionResult.newError(getFunctionStatus(decoratedStatus)); + } + String uriString = uriArgument.getValue().toString(); + + // remaining arguments are strings + String[] stringValues = new String[arguments.size() - 1]; + + for (int i = 1; i < arguments.size(); i++) { + + ConvertedArgument<String> stringArgument = new ConvertedArgument<String>(arguments.get(i), DataTypes.DT_STRING, false); + if ( ! stringArgument.isOk()) { + Status decoratedStatus = new StdStatus(stringArgument.getStatus().getStatusCode(), stringArgument.getStatus().getStatusMessage() + " at arg index " + i ); + return ExpressionResult.newError(getFunctionStatus(decoratedStatus)); + } + + stringValues[i-1] = stringArgument.getValue(); + + } + + + // add each of the strings onto the URI + for (int i = 0; i < stringValues.length; i++) { + uriString += stringValues[i]; + } + + URI resultURI = null; + try { + resultURI = DataTypes.DT_ANYURI.convert(uriString); + } catch (DataTypeException e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); + } + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, getShortFunctionId() + + " Final string '" + uriString + "' not URI, " + message)); + } + + return ExpressionResult.newSingle(new StdAttributeValue<URI>(XACML.ID_DATATYPE_ANYURI, resultURI)); + + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java new file mode 100755 index 0000000..7f5069c --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java
@@ -0,0 +1,98 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + +/** + * FunctionDefinitionX500NameMatch extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to + * implement the XACML X500Name match predicate as functions taking two <code>X500Name</code> arguments and returning a single <code>Boolean</code> value. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * x500Name-match + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + */ +public class FunctionDefinitionX500NameMatch extends FunctionDefinitionHomogeneousSimple<Boolean, X500Principal> { + + + /** + * Constructor + * + * @param idIn + * @param dataTypeArgsIn + * @param op + */ + public FunctionDefinitionX500NameMatch(Identifier idIn) { + super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, 2); + } + + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + List<X500Principal> convertedArguments = new ArrayList<X500Principal>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + /* + * Now perform the match. + */ + + /* + * The spec writer's comments at: + * https://lists.oasis-open.org/archives/xacml/200906/msg00019.html + * say that the first sequence must exactly match the END of the second sequence. + */ + + String[] searchFor = convertedArguments.get(0).getName().split(","); + String[] searchIn = convertedArguments.get(1).getName().split(","); + + // if first is bigger than 2nd there is no way we can match + if (searchFor.length > searchIn.length) { + return ER_FALSE; + } + + // start from back-end of both lists - everything should match up to the length of the input + for (int i = 0; i < searchFor.length; i++) { + String searchForTerm = searchFor[searchFor.length - i - 1]; + String searchInTerm = searchIn[searchIn.length - i - 1]; + if (searchForTerm == null || searchInTerm == null || + ! searchForTerm.trim().equals(searchInTerm.trim())) { + return ER_FALSE; + } + } + + + return ER_TRUE; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java new file mode 100755 index 0000000..22ed22c --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java
@@ -0,0 +1,249 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.xml.xpath.XPathExpression; + +import org.w3c.dom.NodeList; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.RequestAttributes; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.XACML; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.XPathExpressionWrapper; +import com.att.research.xacmlatt.pdp.eval.EvaluationContext; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; + + +/** + * FunctionDefinitionXPath extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to + * implement the XACML XPath predicates as functions taking one or two <code>XPathExpression</code> arguments and returning + * either an <code>Integer</code> or a <code>Boolean</code>. + * + * XACML version 1.0 and 2.0 used <code>String</code> data type as input. + * We do NOT support those functions because of ambiguity in the meaning of those Strings. + * The root of the XPath changed from the Request level in 2.0 to the Content level in 3.0. + * Also the 2.0 Requests contain only one Content, located in the resources category, while 3.0 allows Requests to contain Content in multiple categories. + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * xpath-node-count + * xpath-node-equals + * xpath-node-match + * + * @author glenngriffin + * @version $Revision: 1.1 $ + * + * @param <O> the java class for the data type of the function Output + + * + */ +public class FunctionDefinitionXPath<O> extends FunctionDefinitionHomogeneousSimple<O, XPathExpressionWrapper> { + + /** + * List of string normalization operations. + * + * @author glenngriffin + * + */ + public enum OPERATION {COUNT, EQUAL, MATCH }; + + // operation to be used in this instance of the Arightmetic class + private final OPERATION operation; + + + // result variables used by all functions + AttributeValue<String> result; + + + /** + * Constructor + * + * @param idIn + * @param dataTypeArgsIn + * @param op + */ + public FunctionDefinitionXPath(Identifier idIn, DataType<O> dataTypeIn, OPERATION op) { + super(idIn, dataTypeIn, DataTypes.DT_XPATHEXPRESSION, ( (op == OPERATION.COUNT) ? 1 : 2 ) ); + // save the operation and data type to be used in this instance + operation = op; + + } + + @Override + public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { + + List<NodeList> nodeListList = new ArrayList<NodeList>(); + + List<XPathExpressionWrapper> convertedArguments = new ArrayList<XPathExpressionWrapper>(); + Status status = this.validateArguments(arguments, convertedArguments); + + /* + * If the function arguments are not correct, just return an error status immediately + */ + if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) { + return ExpressionResult.newError(getFunctionStatus(status)); + } + + // check the evaluationContext and Request for null + if (evaluationContext == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Got null EvaluationContext")); + } + if (evaluationContext.getRequest() == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " Got null Request in EvaluationContext")); + } + + + // each argument is an XPath that needs to be evaluated against the Content part of some Category (specified in the argument) + for (int i = 0; i < arguments.size(); i++) { + FunctionArgument functionArgument = arguments.get(i); + if (functionArgument.isBag()) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got bag at index " + i)); + } + AttributeValue<?> attributeValueFunctionArgument = functionArgument.getValue(); + if (attributeValueFunctionArgument == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null value at index " + i)); + } + Identifier xpathCategory = attributeValueFunctionArgument.getXPathCategory(); + if (xpathCategory == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + + " Got null Category at index " + i)); + } + + Iterator<RequestAttributes> it = evaluationContext.getRequest().getRequestAttributes(xpathCategory); + if (it == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + + " Got null Iterator at index " + i)); + } + + NodeList nodeList = null; + + while (it.hasNext()) { + if (nodeList != null) { + // the request has more than one Content entry for the same Category - error + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + + " More than one Content section for id '" + xpathCategory + "'" )); + } + RequestAttributes requestAttributes = it.next(); + + // if there is no Content section then we return either 0 or FALSE + if (requestAttributes.getContentRoot() == null) { + if (operation == OPERATION.COUNT){ + return ExpressionResult.newSingle(new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, new BigInteger("0") )); + } else { + return ER_FALSE; + } + } + + try { + XPathExpression xPathExpression = convertedArguments.get(i).getXpathExpressionWrapped(); + nodeList = requestAttributes.getContentNodeListByXpathExpression(xPathExpression); + } catch (Exception e) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + + " XPath produces null result at '" + convertedArguments.get(i).getPath() + "' at index " + i )); + } + + + } + + if (nodeList == null) { + return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + + " XPathExpression returned null at index " + i)); + } + + // add this nodeList to the list of lists + nodeListList.add(nodeList); + } + + + /* + * Now perform the requested operation. + */ + ExpressionResult expressionResult = null; + + switch (operation) { + case COUNT: + Integer listLength = new Integer(nodeListList.get(0).getLength()); + expressionResult = ExpressionResult.newSingle(new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, + new BigInteger(listLength.toString()) )); + return expressionResult; + + + case EQUAL: + // true if any node in first list equals any node in second set. + // The spec says: "Two nodes are considered equal if they have the same identity." + // we use the isSameNode method in Node to determine that. + for (int index0 = 0; index0 < nodeListList.get(0).getLength(); index0++) { + for (int index1 = 0; index1 < nodeListList.get(1).getLength(); index1++) { + if (nodeListList.get(0).item(index0).isSameNode(nodeListList.get(1).item(index1))) { + return ER_TRUE; + } + } + } + // none from the first list found in the second + return ER_FALSE; + + + case MATCH: + // this is looking to see if any of the nodes in the second set are children of (or equal to) the nodes in the first set + // Call recursive check for that. + expressionResult = nodeListMatch(nodeListList.get(0), nodeListList.get(1)); + return expressionResult; + } + + expressionResult = ExpressionResult.newSingle(result); + + return expressionResult; + } + + /** + * Recursive method checking to see if anything in list 2 equals anything in list 1 OR list 1's child nodes + * @param list1 + * @param list2 + * @return + */ + private ExpressionResult nodeListMatch(NodeList list1, NodeList list2) { + // look for match with current contents of list 1 + for (int index1 = 0; index1 < list1.getLength(); index1++) { + for (int index2 = 0; index2 < list2.getLength(); index2++) { + if (list1.item(index1).isSameNode(list2.item(index2))) { + return ER_TRUE; + } + } + } + // look for match with children of list 1 + for (int index1 = 0; index1 < list1.getLength(); index1++) { + if (nodeListMatch(list1.item(index1).getChildNodes(), list2) == ER_TRUE) { + return ER_TRUE; + } + // this one had no children that matched, so check the next element in list1 + } + + // no match anywhere + return ER_FALSE; + } + +}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java new file mode 100755 index 0000000..2122dd9 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java
@@ -0,0 +1,20 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.std.functions; + +/** + * com.att.research.xacmlatt.pdp.policy.expressions contains class definitions that represent specific XACML function + * implementations for target and condition evaluation and variable definitions. + * + * @author car + * @version $Revision: 1.1 $ + */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java new file mode 100755 index 0000000..fe69353 --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java
@@ -0,0 +1,20 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ + +package com.att.research.xacmlatt.pdp.std; + +/** + * com.att.research.xacmlatt.pdp.std contains classes that provide reference implementations of various extensible components + * in the PDP implementation. + * + * @author car + * @version $Revision: 1.1 $ + */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java new file mode 100755 index 0000000..2b932ba --- /dev/null +++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java
@@ -0,0 +1,29 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.util; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.util.XACMLProperties; + +public class ATTPDPProperties extends XACMLProperties { + public static final String PROP_EVALUATIONCONTEXTFACTORY = "xacml.att.evaluationContextFactory"; + public static final String PROP_COMBININGALGORITHMFACTORY = "xacml.att.combiningAlgorithmFactory"; + public static final String PROP_FUNCTIONDEFINITIONFACTORY = "xacml.att.functionDefinitionFactory"; + public static final String PROP_POLICYFINDERFACTORY = "xacml.att.policyFinderFactory"; + public static final String PROP_POLICYFINDERFACTORY_COMBINEROOTPOLICIES = "xacml.att.policyFinderFactory.combineRootPolicies"; + + public static final Identifier ID_POLICY_COMBINEDPERMITOVERRIDES = new IdentifierImpl("urn:com:att:xacml:3.0:policy-combining-algorithm:combined-permit-overrides"); + + protected ATTPDPProperties() { + } + +}
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class new file mode 100644 index 0000000..61fbdd6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class new file mode 100644 index 0000000..56e339d --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class new file mode 100644 index 0000000..647988e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class new file mode 100644 index 0000000..435ab9c --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class new file mode 100644 index 0000000..25802a3 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class new file mode 100644 index 0000000..ab03f3e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class new file mode 100644 index 0000000..8e508d2 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class new file mode 100644 index 0000000..2f424aa --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class new file mode 100644 index 0000000..c73f36d --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class new file mode 100644 index 0000000..8306ba6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class new file mode 100644 index 0000000..9ec087c --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class new file mode 100644 index 0000000..d24eb17 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class new file mode 100644 index 0000000..ccb1e74 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class new file mode 100644 index 0000000..cdf3dc3 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class new file mode 100644 index 0000000..58d2ced --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class new file mode 100644 index 0000000..101274e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class new file mode 100644 index 0000000..4942daf --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class new file mode 100644 index 0000000..ef8fe7e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class new file mode 100644 index 0000000..3fb1237 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class new file mode 100644 index 0000000..2bc997b --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class new file mode 100644 index 0000000..ee80fd2 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class new file mode 100644 index 0000000..5157663 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class new file mode 100644 index 0000000..ad60823 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class new file mode 100644 index 0000000..225cf1d --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class new file mode 100644 index 0000000..2a74ea6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class new file mode 100644 index 0000000..0e0aea0 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class new file mode 100644 index 0000000..051dbef --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class new file mode 100644 index 0000000..30c0841 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class new file mode 100644 index 0000000..9c507c0 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class new file mode 100644 index 0000000..dddaa10 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class new file mode 100644 index 0000000..1c431ba --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class new file mode 100644 index 0000000..c337941 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class new file mode 100644 index 0000000..d5cb5ed --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class new file mode 100644 index 0000000..12ef034 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class new file mode 100644 index 0000000..1abf718 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class new file mode 100644 index 0000000..8ba8dd4 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class new file mode 100644 index 0000000..6367b3f --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class new file mode 100644 index 0000000..5c2d6f3 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class new file mode 100644 index 0000000..3bd5b5e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class new file mode 100644 index 0000000..1a7355c --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class new file mode 100644 index 0000000..285943b --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class new file mode 100644 index 0000000..d45b7cb --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class new file mode 100644 index 0000000..1ff09f5 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class new file mode 100644 index 0000000..2a245a5 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class new file mode 100644 index 0000000..121d0a8 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class new file mode 100644 index 0000000..9bc54d9 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class new file mode 100644 index 0000000..5fdb442 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class new file mode 100644 index 0000000..90a1f82 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class new file mode 100644 index 0000000..2e17129 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class new file mode 100644 index 0000000..98f42a1 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class new file mode 100644 index 0000000..3883a6e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class new file mode 100644 index 0000000..f631054 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class new file mode 100644 index 0000000..7cda7d4 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class new file mode 100644 index 0000000..af76185 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class new file mode 100644 index 0000000..643f5eb --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class new file mode 100644 index 0000000..d834fa5 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class new file mode 100644 index 0000000..171ecbe --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class new file mode 100644 index 0000000..1dc60b6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class new file mode 100644 index 0000000..911cbcb --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class new file mode 100644 index 0000000..9ab657b --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class new file mode 100644 index 0000000..5b2ca51 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class new file mode 100644 index 0000000..96c3cab --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class new file mode 100644 index 0000000..b955b0e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class new file mode 100644 index 0000000..2516589 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class new file mode 100644 index 0000000..503201c --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class new file mode 100644 index 0000000..8be4cfc --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class new file mode 100644 index 0000000..3ac5422 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class new file mode 100644 index 0000000..14583a3 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class new file mode 100644 index 0000000..a0b2a05 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class new file mode 100644 index 0000000..7062e1f --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class new file mode 100644 index 0000000..c2709e6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class new file mode 100644 index 0000000..e823a43 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class new file mode 100644 index 0000000..c3ce1c7 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class new file mode 100644 index 0000000..b006026 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class new file mode 100644 index 0000000..c4ef9c6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class new file mode 100644 index 0000000..d02bb03 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class new file mode 100644 index 0000000..585ad00 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class new file mode 100644 index 0000000..9abb139 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class new file mode 100644 index 0000000..8213a5b --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class new file mode 100644 index 0000000..5f2a5b2 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class new file mode 100644 index 0000000..251b708 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class new file mode 100644 index 0000000..5052858 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class new file mode 100644 index 0000000..c6d8849 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class new file mode 100644 index 0000000..170541f --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class new file mode 100644 index 0000000..5975519 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class new file mode 100644 index 0000000..4307789 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class new file mode 100644 index 0000000..f2faac6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class new file mode 100644 index 0000000..c05e205 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class new file mode 100644 index 0000000..c60901c --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class new file mode 100644 index 0000000..94411a2 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class new file mode 100644 index 0000000..99f5f44 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class new file mode 100644 index 0000000..9fcf24a --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class new file mode 100644 index 0000000..36bddc1 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class new file mode 100644 index 0000000..e4ea696 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class new file mode 100644 index 0000000..c0864ba --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class new file mode 100644 index 0000000..dd76634 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class new file mode 100644 index 0000000..d62b7c1 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class new file mode 100644 index 0000000..cc23407 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class new file mode 100644 index 0000000..2ef4d9a --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class new file mode 100644 index 0000000..a6a4b4b --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class new file mode 100644 index 0000000..0a065dd --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class new file mode 100644 index 0000000..b704f03 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class new file mode 100644 index 0000000..2dcba35 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class new file mode 100644 index 0000000..1671f08 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class new file mode 100644 index 0000000..ffed3c4 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class new file mode 100644 index 0000000..d409eba --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class new file mode 100644 index 0000000..ea56f8e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class new file mode 100644 index 0000000..6f57c16 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class new file mode 100644 index 0000000..8bef17e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class new file mode 100644 index 0000000..019485f --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class new file mode 100644 index 0000000..20bd937 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class new file mode 100644 index 0000000..42057bf --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class new file mode 100644 index 0000000..f5a6ae2 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class new file mode 100644 index 0000000..71f33e6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class new file mode 100644 index 0000000..b5a3d4c --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class new file mode 100644 index 0000000..d75367a --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class new file mode 100644 index 0000000..72554f8 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class new file mode 100644 index 0000000..95e620a --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class new file mode 100644 index 0000000..44ad7fd --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class new file mode 100644 index 0000000..d29d9a7 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class new file mode 100644 index 0000000..d965889 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class new file mode 100644 index 0000000..f7bf40e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class new file mode 100644 index 0000000..7c13802 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class new file mode 100644 index 0000000..62eeef6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class new file mode 100644 index 0000000..5135125 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class new file mode 100644 index 0000000..9081b65 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class new file mode 100644 index 0000000..a1656af --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class new file mode 100644 index 0000000..61d0da8 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class new file mode 100644 index 0000000..d1c518a --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class new file mode 100644 index 0000000..b8f83e6 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class new file mode 100644 index 0000000..ae8115c --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class new file mode 100644 index 0000000..d28ce78 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class new file mode 100644 index 0000000..0a104a2 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class new file mode 100644 index 0000000..a0ac560 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class new file mode 100644 index 0000000..7fe2a1b --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class new file mode 100644 index 0000000..6cc59f0 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class new file mode 100644 index 0000000..7e69de0 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class new file mode 100644 index 0000000..da9dead --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class new file mode 100644 index 0000000..34f3a5e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class new file mode 100644 index 0000000..844df5e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class new file mode 100644 index 0000000..ff60811 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class new file mode 100644 index 0000000..652a98f --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class new file mode 100644 index 0000000..5e9bf60 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class new file mode 100644 index 0000000..1045783 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class new file mode 100644 index 0000000..1056721 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class new file mode 100644 index 0000000..85d79ca --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class new file mode 100644 index 0000000..ccd974a --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class new file mode 100644 index 0000000..4e3726f --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class new file mode 100644 index 0000000..315fb99 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class new file mode 100644 index 0000000..ae2716d --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class new file mode 100644 index 0000000..a2a0169 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class new file mode 100644 index 0000000..1bcaa07 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class new file mode 100644 index 0000000..ef8f697 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class new file mode 100644 index 0000000..7d04b7b --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class new file mode 100644 index 0000000..92e5e67 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class new file mode 100644 index 0000000..c204a33 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class new file mode 100644 index 0000000..612f3c3 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class new file mode 100644 index 0000000..7ddfc87 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class new file mode 100644 index 0000000..2e56349 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class new file mode 100644 index 0000000..ddc1cb0 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class new file mode 100644 index 0000000..2b522e8 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class new file mode 100644 index 0000000..93eae8f --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class new file mode 100644 index 0000000..9cf81f1 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class new file mode 100644 index 0000000..b3d96fa --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class new file mode 100644 index 0000000..305cd59 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class new file mode 100644 index 0000000..714bf36 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class new file mode 100644 index 0000000..23e2571 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class new file mode 100644 index 0000000..592b19e --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class new file mode 100644 index 0000000..4a8b7b1 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class new file mode 100644 index 0000000..5f6a4e9 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class new file mode 100644 index 0000000..b80bd20 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class new file mode 100644 index 0000000..e0eb6cb --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class new file mode 100644 index 0000000..b539667 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class new file mode 100644 index 0000000..b8b971f --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class new file mode 100644 index 0000000..0f93467 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class new file mode 100644 index 0000000..3ef30e5 --- /dev/null +++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class Binary files differ
diff --git a/openaz-xacml-pdp/target/maven-archiver/pom.properties b/openaz-xacml-pdp/target/maven-archiver/pom.properties new file mode 100644 index 0000000..7e994fb --- /dev/null +++ b/openaz-xacml-pdp/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@ +#Generated by Maven +#Tue Apr 07 07:42:36 EDT 2015 +version=0.0.1-SNAPSHOT +groupId=org.openliberty.openaz +artifactId=openaz-xacml-pdp
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..d6cacb9 --- /dev/null +++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,176 @@ +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class +com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class +com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class +com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class +com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class +com/att/research/xacmlatt/pdp/policy/AdviceExpression.class +com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class +com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class +com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class +com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class +com/att/research/xacmlatt/pdp/policy/CombiningElement.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class +com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class +com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class +com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class +com/att/research/xacmlatt/pdp/policy/Match.class +com/att/research/xacmlatt/pdp/policy/RuleEffect.class +com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class +com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class +com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class +com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class +com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class +com/att/research/xacmlatt/pdp/policy/expressions/Apply.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class +com/att/research/xacmlatt/pdp/ATTPDPEngine.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class +com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class +com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class +com/att/research/xacmlatt/pdp/policy/AllOf.class +com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class +com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class +com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class +com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class +com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class +com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class +com/att/research/xacmlatt/pdp/policy/FunctionArgument.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class +com/att/research/xacmlatt/pdp/eval/EvaluationResult.class +com/att/research/xacmlatt/pdp/std/StdProperties.class +com/att/research/xacmlatt/pdp/policy/Target.class +com/att/research/xacmlatt/pdp/policy/Bag.class +com/att/research/xacmlatt/pdp/policy/AnyOf.class +com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class +com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class +com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class +com/att/research/xacmlatt/pdp/eval/Evaluatable.class +com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class +com/att/research/xacmlatt/pdp/policy/Expression.class +com/att/research/xacmlatt/pdp/policy/ExpressionResult.class +com/att/research/xacmlatt/pdp/eval/EvaluationException.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class +com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class +com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class +com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class +com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class +com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class +com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class +com/att/research/xacmlatt/pdp/policy/PolicySetChild.class +com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class +com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class +com/att/research/xacmlatt/pdp/eval/MatchResult.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class +com/att/research/xacmlatt/pdp/policy/Match$1.class +com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class +com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class +com/att/research/xacmlatt/pdp/policy/PolicySet$1.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class +com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class +com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class +com/att/research/xacmlatt/pdp/policy/PolicySet.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class +com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class +com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class +com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class +com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class +com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class +com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class +com/att/research/xacmlatt/pdp/policy/PolicyDef.class +com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class +com/att/research/xacmlatt/pdp/policy/VariableDefinition.class +com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class +com/att/research/xacmlatt/pdp/policy/Policy$1.class +com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class +com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class +com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class +com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class +com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class +com/att/research/xacmlatt/pdp/eval/Matchable.class +com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class +com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class +com/att/research/xacmlatt/pdp/eval/EvaluationContext.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class +com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class +com/att/research/xacmlatt/pdp/policy/PolicyFinder.class +com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class +com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class +com/att/research/xacmlatt/pdp/std/StdFunctions.class +com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class +com/att/research/xacmlatt/pdp/policy/PolicyComponent.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class +com/att/research/xacmlatt/pdp/policy/Condition.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class +com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class +com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class +com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class +com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class +com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class +com/att/research/xacmlatt/pdp/policy/AnyOf$1.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class +com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class +com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class +com/att/research/xacmlatt/pdp/policy/expressions/Function.class +com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class +com/att/research/xacmlatt/pdp/policy/CombinerParameter.class +com/att/research/xacmlatt/pdp/policy/VariableMap.class +com/att/research/xacmlatt/pdp/policy/Rule$1.class +com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class +com/att/research/xacmlatt/pdp/policy/Rule.class +com/att/research/xacmlatt/pdp/policy/Policy.class +com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class +com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class +com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class +com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class +com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class +com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class +com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class +com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class +com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class +com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class +com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class +com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class +com/att/research/xacmlatt/pdp/policy/ObligationExpression.class +com/att/research/xacmlatt/pdp/policy/AllOf$1.class +com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class +com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class +com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class +com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class +com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..b9e94a4 --- /dev/null +++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,142 @@ +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar b/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..ff65667 --- /dev/null +++ b/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar Binary files differ
diff --git a/openaz-xacml-pdp/xacml.properties b/openaz-xacml-pdp/xacml.properties new file mode 100755 index 0000000..8394be9 --- /dev/null +++ b/openaz-xacml-pdp/xacml.properties
@@ -0,0 +1,26 @@ +# Default XACML Properties File +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory + +# If there is a standard set of PIPEngines: +# xacml.pip.engines=engine1,engine2,...,engineN +# engine1.classname=com.att.research.xacmlpip.OraclePIP +# engine1.prop1=foo +# engine1.prop2=bar +# ... +# engine2.classname=com.att.research.xacmlpip.ActiveDirectoryPIP +# ... + +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +# If there is a standard policy for the engine: +# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-xacml-rest/pom.xml b/openaz-xacml-rest/pom.xml new file mode 100755 index 0000000..cf8b334 --- /dev/null +++ b/openaz-xacml-rest/pom.xml
@@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>openaz</artifactId> + <groupId>org.openliberty.openaz</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>openaz-xacml-rest</artifactId> + + <dependencies> + <dependency> + <groupId>org.openliberty.openaz</groupId> + <artifactId>openaz-xacml</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + </dependencies> + +</project> \ No newline at end of file
diff --git a/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java new file mode 100755 index 0000000..83a8c7b --- /dev/null +++ b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java
@@ -0,0 +1,201 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.servlet.ServletConfig; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.util.XACMLProperties; + +/** + * This static class is used by both the PDP and PAP servlet's. It contains some common + * static functions and objects used by both the servlet's. + * + * @author pameladragosh + * + */ +public class XACMLRest { + private static final Log logger = LogFactory.getLog(XACMLRest.class); + private static Properties restProperties = new Properties(); + + /** + * This must be called during servlet initialization. It sets up the xacml.?.properties + * file as a system property. If the System property is already set, then it does not + * do anything. This allows the developer to specify their own xacml.properties file to be + * used. They can 1) modify the default properties that comes with the project, or 2) change + * the WebInitParam annotation, or 3) specify an alternative path in the web.xml, or 4) set + * the Java System property to point to their xacml.properties file. + * + * The recommended way of overriding the default xacml.properties file is using a Java System + * property: + * + * -Dxacml.properties=/opt/app/xacml/etc/xacml.admin.properties + * + * This way one does not change any actual code or files in the project and can leave the + * defaults alone. + * + * @param config - The servlet config file passed from the javax servlet init() function + */ + public static void xacmlInit(ServletConfig config) { + // + // Get the XACML Properties File parameter first + // + String propFile = config.getInitParameter("XACML_PROPERTIES_NAME"); + if (propFile != null) { + // + // Look for system override + // + String xacmlPropertiesName = System.getProperty(XACMLProperties.XACML_PROPERTIES_NAME); + if (xacmlPropertiesName == null) { + // + // Set it to our servlet default + // + if (logger.isDebugEnabled()) { + logger.debug("Using Servlet Config Property for XACML_PROPERTIES_NAME:" + propFile); + } + System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, propFile); + } else { + if (logger.isDebugEnabled()) { + logger.debug("Using System Property for XACML_PROPERTIES_NAME:" + xacmlPropertiesName); + } + } + } + // + // Setup the remaining properties + // + Enumeration<String> params = config.getInitParameterNames(); + while (params.hasMoreElements()) { + String param = params.nextElement(); + if (! param.equals("XACML_PROPERTIES_NAME")) { + String value = config.getInitParameter(param); + logger.info(param + "=" + config.getInitParameter(param)); + restProperties.setProperty(param, value); + } + } + } + + /** + * Reset's the XACMLProperties internal properties object so we start + * in a fresh environment. Then adds back in our Servlet init properties that were + * passed in the javax Servlet init() call. + * + * This function is primarily used when a new configuration is passed in and the + * PDP servlet needs to load a new PDP engine instance. + * + * @param pipProperties - PIP configuration properties + * @param policyProperties - Policy configuration properties + */ + public static void loadXacmlProperties(Properties policyProperties, Properties pipProperties) { + try { + // + // Start fresh + // + XACMLProperties.reloadProperties(); + // + // Now load our init properties + // + XACMLProperties.getProperties().putAll(XACMLRest.restProperties); + // + // Load our policy properties + // + if (policyProperties != null) { + XACMLProperties.getProperties().putAll(policyProperties); + } + // + // Load our pip config properties + // + if (pipProperties != null) { + XACMLProperties.getProperties().putAll(pipProperties); + } + } catch (IOException e) { + logger.error("Failed to put init properties into Xacml properties", e); + } + // + // Dump them + // + if (logger.isDebugEnabled()) { + try { + logger.debug(XACMLProperties.getProperties().toString()); + } catch (IOException e) { + logger.error("Cannot dump properties", e); + } + } + } + + /** + * Helper routine to dump the HTTP servlet request being serviced. Primarily for debugging. + * + * @param request - Servlet request (from a POST/GET/PUT/etc.) + */ + public static void dumpRequest(HttpServletRequest request) { + if (logger.isDebugEnabled()) { + // special-case for receiving heartbeat - don't need to repeatedly output all of the information in multiple lines + if (request.getMethod().equals("GET") && "hb".equals(request.getParameter("type")) ) { + logger.debug("GET type=hb : heartbeat received"); + return; + } + logger.debug(request.getMethod() + ":" + request.getRemoteAddr() + " " + request.getRemoteHost() + " " + request.getRemotePort()); + logger.debug(request.getLocalAddr() + " " + request.getLocalName() + " " + request.getLocalPort()); + Enumeration<String> en = request.getHeaderNames(); + logger.debug("Headers:"); + while (en.hasMoreElements()) { + String element = en.nextElement(); + Enumeration<String> values = request.getHeaders(element); + while (values.hasMoreElements()) { + String value = values.nextElement(); + logger.debug(element + ":" + value); + } + } + logger.debug("Attributes:"); + en = request.getAttributeNames(); + while (en.hasMoreElements()) { + String element = en.nextElement(); + logger.debug(element + ":" + request.getAttribute(element)); + } + logger.debug("ContextPath: " + request.getContextPath()); + if (request.getMethod().equals("PUT") || request.getMethod().equals("POST")) { + // POST and PUT are allowed to have parameters in the content, but in our usage the parameters are always in the Query string. + // More importantly, there are cases where the POST and PUT content is NOT parameters (e.g. it might contain a Policy file). + // Unfortunately the request.getParameterMap method reads the content to see if there are any parameters, + // and once the content is read it cannot be read again. + // Thus for PUT and POST we must avoid reading the content here so that the main code can read it. + logger.debug("Query String:" + request.getQueryString()); + try { + if (request.getInputStream() == null) { + logger.debug("Content: No content inputStream"); + } else { + logger.debug("Content available: " + request.getInputStream().available()); + } + } catch (Exception e) { + logger.debug("Content: inputStream exception: " + e.getMessage() + "; (May not be relevant)"); + } + } else { + logger.debug("Parameters:"); + Map<String, String[]> params = request.getParameterMap(); + Set<String> keys = params.keySet(); + for (String key : keys) { + String[] values = params.get(key); + logger.debug(key + "(" + values.length + "): " + (values.length > 0 ? values[0] : "")); + } + } + logger.debug("Request URL:" + request.getRequestURL()); + } + } +}
diff --git a/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java new file mode 100755 index 0000000..d70f33e --- /dev/null +++ b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java
@@ -0,0 +1,137 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + +import com.att.research.xacml.util.XACMLProperties; + +/** + * These are XACML Properties that are relevant to the RESTful API interface for + * the PDP, PAP and AC interfaces. + * + * + * @author pameladragosh + * + */ +public class XACMLRestProperties extends XACMLProperties { + /** + * A unique identifier for the PDP servlet instance. Usually set to the URL + * it is running as in the J2EE container. + * + * Eg. http://localhost:8080/pdp/ + */ + public static final String PROP_PDP_ID = "xacml.rest.pdp.id"; + /** + * A PDP servlet's configuration directory. Holds the pip and policy configuration + * data as well as the local policy cache. + * + * Eg: /opt/app/xacml/config + */ + public static final String PROP_PDP_CONFIG = "xacml.rest.pdp.config"; + /** + * Set this property to true or false if the PDP servlet should register itself upon + * startup with the PAP servlet. + */ + public static final String PROP_PDP_REGISTER = "xacml.rest.pdp.register"; + /** + * Number of seconds the PDP will sleep while retrying registration with the PAP. + * This value must be greater or equal to 5. + */ + public static final String PROP_PDP_REGISTER_SLEEP = "xacml.rest.pdp.register.sleep"; + /** + * Number of retry attempts at registration with the PAP. A value of -1 indicates infinite retries. + */ + public static final String PROP_PDP_REGISTER_RETRIES = "xacml.rest.pdp.register.retries"; + /** + * Max content length accepted for an incoming POST XML/JSON request. Default is 32767 bytes. + */ + public static final String PROP_PDP_MAX_CONTENT = "xacml.rest.pdp.maxcontent"; + /** + * Custom HTTP header used by PDP to send the value of the PROP_PDP_ID + */ + public static final String PROP_PDP_HTTP_HEADER_ID = "X-XACML-PDP-ID"; + /** + * Custom HHTP header used by PDP to send its heartbeat value. + */ + public static final String PROP_PDP_HTTP_HEADER_HB = "X-XACML-PDP-HB"; + /** + * The URL of the PAP servlet. Used by PDP servlet's to communicate. Because administrators + * can set whatever context they want to run the PAP servlet, it isn't easy to determine a return + * URL for the PAP servlet. This is especially true upon initialization. + */ + public static final String PROP_PAP_URL = "xacml.rest.pap.url"; + /** + * Upon startup, have the PAP servlet send latest configuration information to all + * the PDP nodes it knows about. + */ + public static final String PROP_PAP_INITIATE_PDP_CONFIG = "xacml.rest.pap.initiate.pdp"; + /** + * The interval the PAP servlet uses to send heartbeat requests to the PDP nodes. + */ + public static final String PROP_PAP_HEARTBEAT_INTERVAL = "xacml.rest.pap.heartbeat.interval"; + /** + * Timeout value used by the PAP servlet when trying to check the heartbeat of a PDP node. + */ + public static final String PROP_PAP_HEARTBEAT_TIMEOUT = "xacml.rest.pap.heartbeat.timeout"; + /* + * Local path to where the GIT repository exists. + * + * Eg. /opt/app/xacml/repository + */ + public static final String PROP_ADMIN_REPOSITORY = "xacml.rest.admin.repository"; + /* + * Local path to where user workspaces exist. The user workspace contains temporary files, the + * user's clone of the GIT repository, anything specific to the user, etc. + */ + public static final String PROP_ADMIN_WORKSPACE = "xacml.rest.admin.workspace"; + /* + * This is the domain you can setup for your organization, it should be a URI. + * + * Eg. com:sample:foo + */ + public static final String PROP_ADMIN_DOMAIN = "xacml.rest.admin.domain"; + /** + * PROP_ADMIN_USER_NAME is simply a name for the logged in user. + * + * AC authentication is out the scope of the web application itself. It is up to the + * developer to setup authentication as they please in the J2EE container used to run + * the web application. Whatever authentication mechanism they use, they should then set + * the attribute into the HttpSession object. The Admin Console will be able to read that + * value (default to "guest") in. + * + * ((HttpServletRequest) request).getSession().setAttribute("xacml.rest.admin.user.name", "Homer"); + * + */ + public static final String PROP_ADMIN_USER_NAME = "xacml.rest.admin.user.name"; + /** + * + * PROP_ADMIN_USER_ID is an id for the logged in user. + * + * Eg. hs1234 + * + * @see #PROP_ADMIN_USER_NAME for more information. + */ + public static final String PROP_ADMIN_USER_ID = "xacml.rest.admin.user.id"; + /** + * + * PROP_ADMIN_USER_EMAIL is a user's email address. + * + * @see #PROP_ADMIN_USER_NAME for more information. + */ + public static final String PROP_ADMIN_USER_EMAIL = "xacml.rest.admin.user.email"; + /** + * Directory path containing sub-directories where the Subscriber servlet puts files sent through data feeds. + */ + public static final String PROP_SUBSCRIBER_INCOMING = "xacml.subscriber.incoming"; + /** + * The specific data feed name for the Subscriber servlet to register for. + */ + public static final String PROP_SUBSCRIBER_FEED = "xacml.subscriber.feed"; +}
diff --git a/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class new file mode 100644 index 0000000..ef86656 --- /dev/null +++ b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class Binary files differ
diff --git a/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class new file mode 100644 index 0000000..b6570eb --- /dev/null +++ b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class Binary files differ
diff --git a/openaz-xacml-rest/target/maven-archiver/pom.properties b/openaz-xacml-rest/target/maven-archiver/pom.properties new file mode 100644 index 0000000..75af03d --- /dev/null +++ b/openaz-xacml-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@ +#Generated by Maven +#Tue Apr 07 07:42:35 EDT 2015 +version=0.0.1-SNAPSHOT +groupId=org.openliberty.openaz +artifactId=openaz-xacml-rest
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..d842d7d --- /dev/null +++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,2 @@ +com/att/research/xacml/rest/XACMLRestProperties.class +com/att/research/xacml/rest/XACMLRest.class
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..f772e13 --- /dev/null +++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,2 @@ +/Users/ajith/IdeaProjects/openaz/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..49eba1f --- /dev/null +++ b/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar Binary files differ
diff --git a/openaz-xacml-test/pom.xml b/openaz-xacml-test/pom.xml new file mode 100755 index 0000000..c88e4c0 --- /dev/null +++ b/openaz-xacml-test/pom.xml
@@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>openaz</artifactId> + <groupId>org.openliberty.openaz</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>openaz-xacml-test</artifactId> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>openaz-xacml</artifactId> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>openaz-xacml-rest</artifactId> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>openaz-xacml-pdp</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + </dependency> + <dependency> + <groupId>postgresql</groupId> + <artifactId>postgresql</artifactId> + </dependency> + <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + </dependency> + </dependencies> + +</project> \ No newline at end of file
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java new file mode 100755 index 0000000..de3851b --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java
@@ -0,0 +1,187 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.dom; + +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.Response; +import com.att.research.xacml.std.dom.DOMResponse; + +/** + * Tests for handling the XML version of the XACML Response object. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * Normally the Response is generated by the PDP and returned through the RESTful interface as JSON. + * Testing of the XML interface is minimal and not complete. + * + * + * + * @author glenngriffin + * + */ +public class DOMResponseConformanceTest { + + // where to find the conformance test XML files + private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4"; + + // The request object output from each test conversion from JSON string + Response response; + + + + // Load the Conformance test responses into Response objects, generate the output XML for that Response and compare with the original files. + @Test + public void testDOMResponse() { + List<File> filesInDirectory = null; + + File conformanceDirectory = null; + + File currentFile = null; + + try { + conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH); + filesInDirectory = getRequestsInDirectory(conformanceDirectory); + } catch (Exception e) { + fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e); + } + + // run through each XML file + // - load the file from XML into an internal Response object + // - generate the XML representation from that Response object + // - reload the file into a String + // - compare the 2 XML strings + Response xmlResponse = null; + try { + for (File f : filesInDirectory) { + currentFile = f; + +//// This is a simple way to select just one file for debugging - comment out when not being used +//if ( ! f.getName().equals("IID302Response.xml")) { continue; } + +// during debugging it is helpful to know what file it is starting to work on +// System.out.println("starting file="+currentFile.getName()); + + + BufferedReader br = new BufferedReader(new FileReader(f)); + StringBuffer sb = new StringBuffer(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line + "\n"); + } + br.close(); + + String xmlFromFile = sb.toString(); + + try { + // load XML into a Response object + xmlResponse = DOMResponse.load(xmlFromFile); + } catch (Exception e) { + // if XML does not load, just note it and continue with next file + System.out.println("XML file did not load: '" + f.getName() + " e=" + e); + continue; + } +//System.out.println(xmlFromFile); + + // create String version from the Response object + String xmlResponseString = DOMResponse.toString(xmlResponse, false); + + // Comparing the string directly to the String from the file is difficult. + // We can minimize the problems with newlines and whitespace, but we have other issues with how various object values are represented. + // For instance, and input double of "23.50" is output as "23.5" which is the same value but not identical strings. + // Therefore we take the XML output and use it to create a new Response object, then compare the two objects. + +//System.out.println(xmlResponseString); + Response reGeneratedResponse = DOMResponse.load(xmlResponseString); + + if ( ! xmlResponse.equals(reGeneratedResponse)) { + String normalizedFromFile = xmlFromFile.replaceAll("\\r|\\n", ""); + normalizedFromFile = normalizedFromFile.replaceAll("\\s+", " "); + normalizedFromFile = normalizedFromFile.replaceAll(">\\s*<", "><"); + System.out.println("File="+normalizedFromFile); + System.out.println("Gend="+ xmlResponseString); + + System.out.println(DOMResponse.toString(xmlResponse, true)); + + fail("Output string did not re-generate eqivilent object."); + } + +// // Normally whitespace is significant in XML. +// // However in this case we are generating an XML string for output and comparing it to a hand-made file. +// // The file may contain extra newlines or fewer spaces then our prettyPrinted output version. +// // Therefore we do the comparison on the un-prettyPrinted generated string. +// // To do this we have to remove the extra whitespace from the version read from the file. +// String normalizedFromFile = xmlFromFile.replaceAll("\\r|\\n", ""); +// normalizedFromFile = normalizedFromFile.replaceAll("\\s+", " "); +// normalizedFromFile = normalizedFromFile.replaceAll(">\\s*<", "><"); +// +// if ( ! xmlResponseString.equals(normalizedFromFile)) { +// System.out.println("file="+normalizedFromFile+"\ngend="+xmlResponseString); +// fail("file not same as generated string: " + f.getName()+ "\nFile="+xmlFromFile + "\nString="+xmlResponseString); +// } + + + } + + } catch (Exception e) { + fail ("Failed test with '" + currentFile.getName() + "', e=" + e); + } + + + } + + + + // + // HELPER to get list of all Request files in the given directory + // + + private List<File> getRequestsInDirectory(File directory) { + List<File> fileList = new ArrayList<File>(); + + File[] fileArray = directory.listFiles(); + for (File f : fileArray) { + if (f.isDirectory()) { + List<File> subDirList = getRequestsInDirectory(f); + fileList.addAll(subDirList); + } + if (f.getName().endsWith("Response.xml")) { + fileList.add(f); + } + } + return fileList; + + } + + +} + + +/* +Place to edit long strings output during tests + + + + + + + + +*/
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java new file mode 100755 index 0000000..9596650 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java
@@ -0,0 +1,2287 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.dom; + +import com.att.research.xacml.api.*; +import com.att.research.xacml.std.*; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.StringNamespaceContext; +import com.att.research.xacml.std.datatypes.XPathExpressionWrapper; +import com.att.research.xacml.std.dom.DOMResponse; +import com.att.research.xacml.std.dom.DOMStructureException; +import org.junit.Test; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * Test DOM XML Responses + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * This class was copied from the JSON tests. At this time only the first two methods have been revised to work with XML. + * The second method includes multiple instances of all possible fields and has been manually verified. + * The remaining methods have not been converted because: + * - "conversion" consists of replacing the JSON strings with XML + * - the replacement would consist of copying the XML from the JUnit output and doing a String replace + * - there would be little examination of the (long) XML strings, so their validity would be questionable + * so the benefit for the cost of doing that work is not clear. + * + * @author glenngriffin + * + */ +public class DOMResponseTest { + + String xmlResponse; + + StdMutableResponse response; + + StdMutableResult result; + + StdMutableStatus status; + + + // Note: Initially test responses without Obligations, Associated Advice, Attributes, or PolicyIdentifier + + + @Test + public void testEmptyAndDecisions() { + // null response + try { + xmlResponse = DOMResponse.toString(null, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // empty response (no Result object) + response = new StdMutableResponse(); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + // just decision, no status + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // just status (empty), no decision + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // just status (non-empty), no decision + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + result.setStatus(status); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + // test other decisions without Status + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.DENY); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Deny</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.NOTAPPLICABLE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>NotApplicable</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_DENY); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // test Multiple Decisions - success + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + StdMutableResult result2 = new StdMutableResult(); + result2.setDecision(Decision.DENY); + response.add(result2); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result><Result><Decision>Deny</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // test Multiple Decisions - one success and one error + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + result2 = new StdMutableResult(); + result2.setDecision(Decision.INDETERMINATE); + response.add(result2); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result><Result><Decision>Indeterminate</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // Test with every field filled in with multiple values where appropriate + @Test + public void testAllFieldsResponse() { + + // fully-loaded multiple response + + StdMutableResponse response = new StdMutableResponse(); + // create a Status object + StdMutableStatus status = new StdMutableStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + status.setStatusMessage("some status message"); + StdMutableStatusDetail statusDetailIn = new StdMutableStatusDetail(); + StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail(); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "doh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_INTEGER.getId(), "5432")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.setAttributeId(XACML3.ID_ACTION_PURPOSE); + mad.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION); + mad.setDataTypeId(XACML3.ID_DATATYPE_STRING); + mad.setIssuer("an Issuer"); + statusDetailIn.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetailIn); + // create a single result object + StdMutableResult result = new StdMutableResult(status); + // set the decision + result.setDecision(Decision.INDETERMINATE); + // put the Result into the Response + response.add(result); + + + // create a new Result with a different Decision + status = new StdMutableStatus(StdStatusCode.STATUS_CODE_OK); + result = new StdMutableResult(status); + result.setDecision(Decision.DENY); + + StdMutableObligation obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer2", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned"))); + result.addObligation(obligation); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_SUBJECT_CATEGORY_INTERMEDIARY_SUBJECT); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer3", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer4", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer"))); + result.addObligation(obligation); + + + StdMutableAdvice advice = new StdMutableAdvice(); + advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"))); + advice.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "advice-issuerNoCategory", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Crusty"))); + result.addAdvice(advice); + + + response.add(result); + + + // create a new Result with a different Decision + // add Child/minor status codes within the main status + StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode")); + StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode); + StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode); + StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + + status = new StdMutableStatus(statusCode); + + + result = new StdMutableResult(status); + result.setDecision(Decision.PERMIT); + + + + + // add attribute list in result + Identifier categoryIdentifier = new IdentifierImpl("firstCategory"); + Attribute[] attrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(attrList))); + categoryIdentifier = new IdentifierImpl("secondCategory"); + Attribute[] secondAttrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList))); + + + // add PolicyIdentifierList to result + StdIdReference policyIdentifier1 = null; + StdIdReference policyIdentifier2 = null; + StdIdReference policySetIdentifier1 = null; + StdIdReference policySetIdentifier2 = null; + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + + response.add(result); + + // convert Response to XML + try { + xmlResponse = DOMResponse.toString(response, false); +//System.out.println(xmlResponse); +//System.out.println(DOMResponse.toString(response, true)); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusMessage>some status message</StatusMessage><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:action:purpose\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\" Issuer=\"an Issuer\"><AttributeValue>doh</AttributeValue><AttributeValue>5432</AttributeValue><AttributeValue>meh</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result><Result><Decision>Deny</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Ned</AttributeAssignment></Obligation><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Homer</AttributeAssignment></Obligation></Obligations><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Crusty</AttributeAssignment></Advice></AssociatedAdvice></Result><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"><StatusCode Value=\"childChildStatusCode\"><StatusCode Value=\"childChildChildStatusCode\"/></StatusCode></StatusCode></StatusCode></Status><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrNoIssuer\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes><Attributes Category=\"secondCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent12\" Issuer=\"AIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu2</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent32\" Issuer=\"CIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Der2</AttributeValue></Attribute></Attributes><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // combinations of Status values with Decision values + @Test + public void testDecisionStatusMatch() { + // the tests in this method use different values and do not change structures, so we can re-use the objects + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + response.add(result); + + // StatusCode = OK + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + result.setDecision(Decision.PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Deny</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>NotApplicable</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + + + + + // StatusCode = SyntaxError + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + result.setDecision(Decision.PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // StatusCode = ProcessingError + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + result.setDecision(Decision.PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // StatusCode = MissingAttribute + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + result.setDecision(Decision.PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // tests related to Status and its components + @Test + public void testStatus() { + // Status with no StatusCode - error + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Status with StatusMessage when OK + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail when OK + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + StdMutableStatusDetail statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Status with StatusMessage when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + // Status with StatusMessage when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + // Status with StatusMessage when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // Status with StatusDetail with empty detail when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail(); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Status with StatusDetail with valid detail with no value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail with valid detail with value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>meh</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail with array valid detail with value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>meh</AttributeValue><AttributeValue>nu?</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Status with StatusDetail with valid detail with Integer value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>1111</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail with array valid detail with Integer value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)); + mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222)); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + +// StringNamespaceContext snc = new StringNamespaceContext(); +// try { +// snc.add("defaultURI"); +// snc.add("md", "referenceForMD"); +// } catch (Exception e) { +// fail("unable to create NamespaceContext e="+e); +// } +// XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); +// +//TODO - assume that we will never try to pass back an XPathExpression in a MissingAttributeDetail - it doesn't make sense and is unclear how to put into XML +// // Status with StatusDetail with valid detail with XPathExpression value when MissingAttribute +// response = new StdMutableResponse(); +// result = new StdMutableResult(); +// status = new StdMutableStatus(); +// status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); +// statusDetail = new StdMutableStatusDetail(); +// mad = new StdMutableMissingAttributeDetail(); +// mad.setAttributeId(new IdentifierImpl("mad")); +// mad.setCategory(XACML3.ID_ACTION); +// mad.setDataTypeId(DataTypes.DT_STRING.getId()); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId"))); +// statusDetail.addMissingAttributeDetail(mad); +// status.setStatusDetail(statusDetail); +// result.setStatus(status); +// result.setDecision(Decision.INDETERMINATE); +// response.add(result); +// try { +// xmlResponse = DOMResponse.toString(response, false); +// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail><AttributeValue>1111</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", xmlResponse); +// } catch (Exception e) { +// fail("operation failed, e="+e); +// } +// +// // Status with StatusDetail with array valid detail with XPathExpression value when MissingAttribute +// response = new StdMutableResponse(); +// result = new StdMutableResult(); +// status = new StdMutableStatus(); +// status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); +// statusDetail = new StdMutableStatusDetail(); +// mad = new StdMutableMissingAttributeDetail(); +// mad.setAttributeId(new IdentifierImpl("mad")); +// mad.setCategory(XACML3.ID_ACTION); +// mad.setDataTypeId(DataTypes.DT_STRING.getId()); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId1"))); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId2"))); +// statusDetail.addMissingAttributeDetail(mad); +// status.setStatusDetail(statusDetail); +// result.setStatus(status); +// result.setDecision(Decision.INDETERMINATE); +// response.add(result); +// try { +// xmlResponse = DOMResponse.toString(response, false); +// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail><AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", xmlResponse); +// } catch (Exception e) { +// fail("operation failed, e="+e); +// } + +//TODO - try with other data types, esp XPathExpression + + // Status with StatusDetail with array valid detail with value when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Status with StatusDetail with array valid detail with value when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + + // Status with nested child StatusCodes (child status containing child status containing...) + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode")); + StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + status = new StdMutableStatus(statusCode); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"/></StatusCode><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode")); + StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode); + child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode); + statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + status = new StdMutableStatus(statusCode); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"><StatusCode Value=\"childChildStatusCode\"><StatusCode Value=\"childChildChildStatusCode\"/></StatusCode></StatusCode></StatusCode><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + } + + + + @Test + public void testObligations() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital"); + + StdMutableObligation obligation; + + // test Obligation single decision no attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // obligation missing Id + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + + // AttributeAssignment - with AttributeId, Value, Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - with AttributeId, Value, no Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Missing AttributeId + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + null, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - Missing Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + null)); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - missing required DataType (Different than JSON where DataType is optional with default String) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(null, "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - missing issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Integer type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - XPathExpression type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + + // + // Technically arrays cannot occur in Obligations and Advice elements. The XML spec boils down to the following definition: + // <Obligation (attributes of the obligation) > + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // : + // </Obligation + // which means that there may be multiple AttributeAssignments but each one has only one value. + // This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements. + // For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer. + // + + + // AttributeAssignment - Multiple values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Lisa</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - Multiple Integer values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 3333))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">2222</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">3333</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Multiple XPathExpression values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory")))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:hospital</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + } + + + + + @Test + public void testAdvice() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital"); + + StdMutableAdvice Advice; + + // test Advice single decision no attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Advice missing Id + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + + // AttributeAssignment - with AttributeId, Value, Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - with AttributeId, Value, no Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Missing AttributeId + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + null, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - Missing Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + null)); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - missing Required DataType (Different than JSON where DataType is optional with default String) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(null, "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - missing issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Integer type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - XPathExpression type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + + // + // Technically arrays cannot occur in Obligations and Advice elements. The XML spec boils down to the following definition: + // <Obligation (attributes of the obligation) > + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // : + // </Obligation + // which means that there may be multiple AttributeAssignments but each one has only one value. + // This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements. + // For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer. + // + + // AttributeAssignment - Multiple values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa"))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Lisa</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - Multiple Integer values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 3333))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">2222</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">3333</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Multiple XPathExpression values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory")))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:hospital</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + + + + + + + // Attributes tests + @Test + public void testAttributes() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + + + Identifier categoryIdentifier; + List<Attribute> attrList = new ArrayList<Attribute>(); + StdMutableAttribute mutableAttribute; + + // Attr list with no entries + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // one Attribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // multiple attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent2\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // IncludeInResult=false/true + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", false)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Missing AttributeId (mandatory) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, null, new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Missing mandatory Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), null), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Missing optional Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // missing required DataType (different from JSON where DataType is optional and assumed to be String) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(null, "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // same id, same type different issuer + // (This is not an array of values because Issuer is different) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "CIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Simpson</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same id, same type same issuer + // (This is an array of values) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Simpson</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same Id, different types, same issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same Id, different types, different issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // different Id, different types, same issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "AIssue"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent2\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">AIssue</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // one Attribute of type XPathExpression (the only complex data type) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategory")), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" XPathCategory=\"xpathCategory\">//md:record</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // multiple sets of values + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + categoryIdentifier = new IdentifierImpl("secondCategory"); + Attribute[] secondAttrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList))); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrNoIssuer\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes><Attributes Category=\"secondCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent12\" Issuer=\"AIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu2</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent32\" Issuer=\"CIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Der2</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - same type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned")); + + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Homer</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Ned</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - compatible different types + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567)); + mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432)); + mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567)); + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - incompatible different types (Different from JSON because these are not part of an array in XML, just separate values) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M")); + mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432)); + mutableAttribute.addValue(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true)); + mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567)); + mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567)); + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + } + + + + + + // PolicyIdentifier tests + @Test + public void testPolicyIdentifier() { + + StdIdReference policyIdentifier1 = null; + StdIdReference policyIdentifier2 = null; + StdIdReference policySetIdentifier1 = null; + StdIdReference policySetIdentifier2 = null; + + // multiple PolicyIdentifiers of both types + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // PolicyIdentifier exists but has no IdReferences + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + policyIdentifier1 = null; + result.addPolicyIdentifier(policyIdentifier1); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // PolicySetIdentifier exists but has not IdReferences + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + policySetIdentifier1 = null; + result.addPolicyIdentifier(policySetIdentifier1); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // PolicyIdentifier with PolicyIdReference and no PolicySetIdReference + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicyIdentifier(policyIdentifier1); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // PolicyIdentifier with no PolicyIdReference and with PolicySetIdReference + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicySetIdentifier(policySetIdentifier1); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // IdReferences without version + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), null); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference>idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference>idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + +//TODO - the XML spec implies that the Result Attributes may include the Content (It is part of the UML) + + + // test indentation??? + + +} + + +/* +Place to edit long strings ouput from tests + + +Expected +<?xml version="1.0" encoding="UTF-8"?><Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"><Result><Decision>Permit</Decision></Result></Response> +<?xml version="1.0" encoding="UTF-8"?><Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"><Result><Decision>Permit</Decision></Result></Response> +Actual + + + + */ + + + + + + + + + + + + +
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java new file mode 100755 index 0000000..c7844a8 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java
@@ -0,0 +1,497 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdMutableRequest; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdEvaluationContext; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import org.junit.Ignore; +import org.junit.Test; + +import javax.xml.namespace.NamespaceContext; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.junit.Assert.*; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOT IMPLEMENTED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * This function is not yet implemented so these tests intentionally fail. + * + * @author glenngriffin + * + */ +public class FunctionDefinitionAccessPermittedTest { + + // + // Strings for the Request contents + // + + String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + + "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" + + " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"" + + " ReturnPolicyIdList=\"false\"" + + " CombinedDecision=\"false\"" + + " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"" + + " xmlns:md=\"http://www.medico.com/schemas/record\"" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + + " <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>" + + " </Attribute>" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>" + + " </Attribute>" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>" + + " </Attribute>" + + "</Attributes>"; + + String reqStrResourceStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">"; + + String reqStrMdRecordSimpson = + "<md:record>" + + "<md:hospital_info>" + + "<md:name>ABC Hospital</md:name>" + + "<md:department>Surgery</md:department>" + + "</md:hospital_info>" + + "<md:patient_info>" + + "<md:name>Bart Simpson</md:name>" + + "<md:age>60</md:age>" + + "<md:sex>male</md:sex>" + + "<md:health_insurance>123456</md:health_insurance>" + + "</md:patient_info>" + + "<md:diagnosis_info>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Gastric Cancer</md:item>" + + "<md:item type=\"secondary\">Hyper tension</md:item>" + + "</md:diagnosis>" + + "<md:pathological_diagnosis>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" + + "</md:diagnosis>" + + "<md:date>2000-10-05</md:date>" + + "<md:malignancy type=\"yes\"/>" + + "</md:pathological_diagnosis>" + + "</md:diagnosis_info>" + + " </md:record>"; + String reqStrContentMdRecordSimpson = "<Content>" + reqStrMdRecordSimpson + "</Content>"; + String reqStrMalformedContent = + " <Content>" + + "<md:record>" + + "<md:hospital_info>" + + "<md:name>ABC Hospital</md:name>" + + "<md:malignancy type=\"yes\"/>" + + "</Content>"; + String reqStrMdRecordSpringer = + "<md:record>" + + "<md:hospital_info>" + + "<md:name>XYZ Hospital</md:name>" + + "<md:department>Surgery</md:department>" + + "</md:hospital_info>" + + "<md:patient_info>" + + "<md:name>Jerry Springer</md:name>" + + "<md:age>65</md:age>" + + "<md:sex>male</md:sex>" + + "<md:health_insurance>765432</md:health_insurance>" + + "</md:patient_info>" + + "<md:diagnosis_info>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Hyatal Hernia</md:item>" + + "<md:item type=\"secondary\">Diabetes</md:item>" + + "<md:item type=\"tertiary\">Neuronal Collapse</md:item>" + + "</md:diagnosis>" + + "<md:pathological_diagnosis>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">We have no idea</md:item>" + + "</md:diagnosis>" + + "<md:date>2012-07-22</md:date>" + + "<md:malignancy type=\"no\"/>" + + "</md:pathological_diagnosis>" + + "</md:diagnosis_info>" + + " </md:record>"; + String reqStrContentMdRecordSpringer = + "<Content>" + reqStrMdRecordSpringer + "</Content>"; + + String reqStrResourceEnd = " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>" + + " </Attribute>" + + "</Attributes> "; + String reqStrActionStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">"; + + String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">" + + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>" + + "</Attribute>" + + "</Attributes> "; + String reqStrEnvironmentStartEnd = " <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />"; + String reqStrMainEnd = " </Request>"; + + + // combined strings for convenience + String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart; + String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd; + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + + // Name Spaces used in the XML as part of these examples - needed for compiling XPaths + NamespaceContext nameSpaceContext = new NamespaceContext() { + @Override + public Iterator<?> getPrefixes(String arg0) { return null;} + + @Override + public String getPrefix(String arg0) {return null;} + + @Override + public String getNamespaceURI(String arg0) { + if("md".equals(arg0)) { + return "http://www.medico.com/schemas/record"; + } else if ("xacml-context".equals(arg0)) { + return "urn:oasis:names:tc:xacml:3.0:context:schema:os"; + } else if ("xsi".equals(arg0)) { + return "http://www.w3.org/2001/XMLSchema-instance"; + } + return null; + } + }; + + + + // + // URIs for attribute categroies + // + + FunctionArgumentAttributeValue attrUriNull = null; + FunctionArgumentAttributeValue attrUriEmpty = null; + FunctionArgumentAttributeValue attrUriResources = null; + FunctionArgumentAttributeValue attrUriAction = null; + FunctionArgumentAttributeValue attrUriNotInRequest = null; + FunctionArgumentAttributeValue attrUriNotCategory = null; + + + + // + // XML Contents + // + + FunctionArgumentAttributeValue attrXnull = null; + FunctionArgumentAttributeValue attrXEmpty = null; + FunctionArgumentAttributeValue attrXSimpson = null; + FunctionArgumentAttributeValue attrXSpringer = null; + FunctionArgumentAttributeValue attrXContentSimpson = null; + FunctionArgumentAttributeValue attrXContentSpringer = null; + FunctionArgumentAttributeValue attrXBadXML = null; + + + + + + + // + // REQUEST objects available for use in tests + // + Request requestEmpty = new StdMutableRequest(); + Request requestMdRecord = null; + Request requestDoubleResources = null; + Request requestDoubleContent = null; + Request requestResourceActionContent = null; + Request requestContentInAction = null; + + + + + /** + * Set up all variables in one place because it is complicated (lots of steps needed for each attribute) + */ + public FunctionDefinitionAccessPermittedTest() { + try { + + + // create Function Attributes for URIs + attrUriNull = null; + attrUriEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrUriResources = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:resource")); + attrUriAction = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:action")); + attrUriNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("NoSuchURI")); + attrUriNotCategory = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:1.0:resource:resource-id")); + + // create Function Attributes for XML Strings + attrXnull = new FunctionArgumentAttributeValue(null); + attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrXSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSimpson)); + attrXSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSpringer)); + attrXContentSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSimpson)); + attrXContentSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSpringer)); + attrXBadXML = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMalformedContent)); + + + + // Request objects + // to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it. + + // single Content in the Resources section (normal valid request) + String reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceAllEnd; + File tFile = File.createTempFile("functionJunit", "request"); + BufferedWriter bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestMdRecord = DOMRequest.load(tFile); + tFile.delete(); + + // Resources included twice + reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecordSimpson +reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestDoubleResources = DOMRequest.load(tFile); + tFile.delete(); + + // Content included twice - error + reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrContentMdRecordSimpson +reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestDoubleContent = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + // content included in both Resource and Action - ok + reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestResourceActionContent = DOMRequest.load(tFile); + tFile.delete(); + + // Content included only in Action - missing content produces non-error result according to spec + reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestContentInAction = DOMRequest.load(tFile); + tFile.delete(); + + + + // Test that Bad XML is caught + @SuppressWarnings("unused") + Request requestContentMisplaced = null; + @SuppressWarnings("unused") + Request requestMalformedContent = null; + + + // Bad XML - Content not under a Category + reqString = reqStrMainStart + reqStrContentMdRecordSimpson + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestContentMisplaced = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + // Bad XML - Content is not valid XML + reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestMalformedContent = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + } catch (Exception e) { + fail("Constructor initializing variables, e="+ e + " cause="+e.getCause()); + } + + } + + + + + + + + @Ignore + @Test + public void testAccess_permitted() { + + ExpressionResult res = null; + Boolean resValue = null; + + FunctionDefinitionAccessPermitted fd = (FunctionDefinitionAccessPermitted) StdFunctions.FD_ACCESS_PERMITTED; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ACCESS_PERMITTED, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + + // successful invoke returns true + arguments.clear(); + arguments.add(attrUriResources); + arguments.add(attrXEmpty); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + + // successful invoke returns false + + + // URI not in Request (ok - evaluate anyway) + + // test for infinite loop + + // second arg ok both with and without <Content> tag + arguments.clear(); + arguments.add(attrUriResources); + arguments.add(attrXContentSpringer); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrUriResources); + arguments.add(attrXSpringer); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // second arg not valid XML + arguments.clear(); + arguments.add(attrUriResources); + arguments.add(attrXBadXML); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Parsing of XML string failed. Cause='The element type \"md:hospital_info\" must be terminated by the matching end-tag \"</md:hospital_info>\".'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Evaluation Context + arguments.clear(); + arguments.add(attrUriNotCategory); + arguments.add(attrXContentSimpson); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Request + arguments.clear(); + arguments.add(attrUriAction); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Got null Request in EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first arg not uri + arguments.clear(); + arguments.add(attrUriNotCategory); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg not attribute-category urn + arguments.clear(); + arguments.add(attrXContentSimpson); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected data type 'anyURI' saw 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second arg not string + arguments.clear(); + arguments.add(attrUriAction); + arguments.add(attrUriAction); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // too few args + arguments.clear(); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // too many args + arguments.clear(); + arguments.add(attrUriEmpty); + arguments.add(attrXContentSimpson); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java new file mode 100755 index 0000000..3887198 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java
@@ -0,0 +1,707 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionArithmeticTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + @Test + public void testInteger_add() { + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attrBadType = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_ADD; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_ADD, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + arguments.clear(); + arguments.add(attr1); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-add Expected data type 'integer' saw 'double' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testDouble_add() { + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_ADD; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_ADD, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(4.0), resValue); + + } + + + @Test + public void testInteger_subtract() { + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(6)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_SUBTRACT; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_SUBTRACT, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("5"), resValue); + + } + + + @Test + public void testDouble_subtract() { + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(8.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.3)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_SUBTRACT; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_SUBTRACT, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(6.2), resValue); + + } + + + @Test + public void testInteger_multiply() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_MULTIPLY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_MULTIPLY, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("10"), resValue); + + + // test 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("0"), resValue); + } + + + @Test + public void testDouble_multiply() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_MULTIPLY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_MULTIPLY, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(3.75), resValue); + + // test multiply by 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0), resValue); + } + + + @Test + public void testInteger_divide() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_DIVIDE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_DIVIDE, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + + // test 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-divide Divide by 0 error: 5, 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testDouble_divide() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5)); + + } catch (Exception e) { + fail("creating attributes e="+e); + } + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_DIVIDE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_DIVIDE, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0.6), resValue); + + // test multiply by 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-divide Divide by 0 error: 1.5, 0.0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + @Test + public void testInteger_mod() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(28)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_MOD; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_MOD, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("3"), resValue); + + + // test 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-mod Divide by 0 error: 28, 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testInteger_abs() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attrM1 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + attrM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-7)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_ABS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_ABS, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("5"), resValue); + + arguments.clear(); + arguments.add(attrM1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("7"), resValue); + + arguments.clear(); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("0"), resValue); + } + + + @Test + public void testDouble_abs() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5)); + + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_ABS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_ABS, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1.5), resValue); + + arguments.clear(); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(2.5), resValue); + + arguments.clear(); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0), resValue); + + } + + + @Test + public void testDouble_round() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attr3 = null; + FunctionArgumentAttributeValue attr4 = null; + FunctionArgumentAttributeValue attr5 = null; + FunctionArgumentAttributeValue attr6 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.49)); + attr3 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.51)); + attr4 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5)); + attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.49)); + attr6 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.51)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_ROUND; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ROUND, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal + arguments.add(attr0); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0), resValue); + + arguments.clear(); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(2), resValue); + + arguments.clear(); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1), resValue); + + arguments.clear(); + arguments.add(attr3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(2), resValue); + + arguments.clear(); + arguments.add(attr4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-2), resValue); + + arguments.clear(); + arguments.add(attr5); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-2), resValue); + + arguments.clear(); + arguments.add(attr6); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-3), resValue); + } + + + @Test + public void testDouble_floor() { + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attr3 = null; + FunctionArgumentAttributeValue attr4 = null; + FunctionArgumentAttributeValue attr5 = null; + FunctionArgumentAttributeValue attr6 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.49)); + attr3 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.51)); + attr4 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5)); + attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.49)); + attr6 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.51)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_FLOOR; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_FLOOR, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal + arguments.add(attr0); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0), resValue); + + arguments.clear(); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1), resValue); + + arguments.clear(); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1), resValue); + + arguments.clear(); + arguments.add(attr3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1), resValue); + + arguments.clear(); + arguments.add(attr4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-3), resValue); + + arguments.clear(); + arguments.add(attr5); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-3), resValue); + + arguments.clear(); + arguments.add(attr6); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-3), resValue); + } + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java new file mode 100755 index 0000000..d097122 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java
@@ -0,0 +1,201 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionBagIsInTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @Test + public void testString() { + String v1 = new String("abc"); + String v2 = new String("def"); + String notInBag = new String("lmnop"); + String sameValueV1 = new String("abc"); + Integer vOtherType = new Integer(11); + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrV2 = null; + FunctionArgumentAttributeValue attrNotInBag = null; + FunctionArgumentAttributeValue attrSameValueV1 = null; + FunctionArgumentAttributeValue attrOtherType = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2)); + attrNotInBag = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(notInBag)); + attrSameValueV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(sameValueV1)); + attrOtherType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(vOtherType)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + Bag bag0 = new Bag(); + Bag bag1 = new Bag(); + bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + Bag bag2 = new Bag(); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2));; + + + + FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0); + FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1); + FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2); + + + + FunctionDefinitionBagIsIn<?> fd = (FunctionDefinitionBagIsIn<?>) StdFunctions.FD_STRING_IS_IN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_IS_IN, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // element is in bag + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBag2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // element not in bag + arguments.clear(); + arguments.add(attrNotInBag); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // different element with the same value is in bag + arguments.clear(); + arguments.add(attrSameValueV1); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty bag + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBag0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // missing arg + arguments.clear(); + arguments.add(attrSameValueV1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 1st arg is bag + arguments.clear(); + arguments.add(attrBag1); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Expected a simple value, saw a bag", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2nd arg not bag + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg null + arguments.clear(); + arguments.add(null); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2nd arg null + arguments.clear(); + arguments.add(attrV1); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg type does not match bag elements + arguments.clear(); + arguments.add(attrOtherType); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag has mixed element types +// behavior not specified for this case in spec. It ASSUMES that all elements in bag are same type. + + } + + + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java new file mode 100755 index 0000000..13c5161 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java
@@ -0,0 +1,204 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.math.BigInteger; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionBagOneAndOnlyTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @Test + public void testString() { + String v1 = new String("abc"); + String v2 = new String("def"); + BigInteger vOtherType = BigInteger.valueOf(11); + + Bag bag0 = new Bag(); + Bag bag1 = new Bag(); + bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + Bag bag2 = new Bag(); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2)); + Bag bagOtherType = new Bag(); + bagOtherType.add(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), vOtherType)); + + FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0); + FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1); + FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2); + FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType); + + + FunctionDefinitionBagOneAndOnly<?> fd = (FunctionDefinitionBagOneAndOnly<?>) StdFunctions.FD_STRING_ONE_AND_ONLY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + + + // bag with only one + arguments.clear(); + arguments.add(attrBag1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + String resValue = (String)res.getValue().getValue(); + assertEquals(v1, resValue); + + // null bag + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-one-and-only Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with exactly one but of other type in it + arguments.clear(); + arguments.add(attrBagOtherType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-one-and-only Element in bag of wrong type. Expected string got integer", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with none + arguments.clear(); + arguments.add(attrBag0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-one-and-only Expected 1 but Bag has 0 elements", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with multiple + arguments.clear(); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-one-and-only Expected 1 but Bag has 2 elements", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + @Test + public void testBoolean() { + Boolean v1 = new Boolean(true); + Boolean v2 = new Boolean(false); + BigInteger vOtherType = BigInteger.valueOf(11); + + Bag bag0 = new Bag(); + Bag bag1 = new Bag(); + bag1.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v1)); + Bag bag2 = new Bag(); + bag2.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v1)); + bag2.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v2)); + Bag bagOtherType = new Bag(); + bagOtherType.add(new StdAttributeValue<BigInteger>(DataTypes.DT_STRING.getId(), vOtherType)); + + + FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0); + FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1); + FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2); + FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType); + + + FunctionDefinitionBagOneAndOnly<?> fd = (FunctionDefinitionBagOneAndOnly<?>) StdFunctions.FD_BOOLEAN_ONE_AND_ONLY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + + + // bag with only one + arguments.clear(); + arguments.add(attrBag1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // null bag + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-one-and-only Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with exactly one but of other type in it + arguments.clear(); + arguments.add(attrBagOtherType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-one-and-only Element in bag of wrong type. Expected boolean got string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with none + arguments.clear(); + arguments.add(attrBag0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-one-and-only Expected 1 but Bag has 0 elements", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with multiple + arguments.clear(); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-one-and-only Expected 1 but Bag has 2 elements", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java new file mode 100755 index 0000000..afc5e09 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java
@@ -0,0 +1,138 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionBagSizeTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @Test + public void testString() { + String v1 = new String("abc"); + String v2 = new String("def"); + Integer vOtherType = new Integer(11); + + + + Bag bag0 = new Bag(); + Bag bag1 = new Bag(); + bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + Bag bag2 = new Bag(); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2)); + Bag bagOtherType = new Bag(); + bagOtherType.add(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), vOtherType)); + + + FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0); + FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1); + FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2); + FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType); + + + FunctionDefinitionBagSize<?> fd = (FunctionDefinitionBagSize<?>) StdFunctions.FD_STRING_BAG_SIZE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_BAG_SIZE, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + + + // bag with only one + arguments.clear(); + arguments.add(attrBag1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(BigInteger.class, res.getValue().getValue().getClass()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(1), resValue); + + // null bag + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-bag-size Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with exactly one but of other type in it + arguments.clear(); + arguments.add(attrBagOtherType); + res = fd.evaluate(null, arguments); + // NOTE: Size does not care about content type! + assertTrue(res.isOk()); + assertEquals(BigInteger.class, res.getValue().getValue().getClass()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(1), resValue); + + // bag with none + arguments.clear(); + arguments.add(attrBag0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(BigInteger.class, res.getValue().getValue().getClass()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(0), resValue); + + // bag with multiple + arguments.clear(); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(BigInteger.class, res.getValue().getValue().getClass()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(2), resValue); + } + + + + + + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java new file mode 100755 index 0000000..4901916 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java
@@ -0,0 +1,527 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionBagTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + FunctionArgumentAttributeValue attrInteger = null; + FunctionArgumentAttributeValue attrString = null; + + public FunctionDefinitionBagTest() { + try { + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1111111111)); + attrString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("a string value")); + } catch (Exception e) { + fail("creating attributes e="+e); + } + } + + @Test + public void testString() { + + String s1 = "abc"; + String s2 = "def"; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(s1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(s2)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_STRING_BAG; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_BAG, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // bag with only one + arguments.clear(); + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // zero args => empty bag + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + assertEquals(0, bag.size()); + + + // null argument + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-bag Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // argument of other type + arguments.clear(); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-bag Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args (check response is correct) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(2, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + + // duplicate args (verify return) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // lots of args + arguments.clear(); + for (int i = 0; i < 1000; i++) { + arguments.add(attr1); + } + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1000, bag.size()); + + } + + + @Test + public void testBoolean() { + + Boolean s1 = true; + Boolean s2 = false; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(s1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(s2)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_BOOLEAN_BAG; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BOOLEAN_BAG, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // bag with only one + arguments.clear(); + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // zero args => empty bag + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + assertEquals(0, bag.size()); + + + // null argument + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-bag Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // argument of other type + arguments.clear(); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-bag Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args (check response is correct) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(2, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + + // duplicate args (verify return) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // lots of args + arguments.clear(); + for (int i = 0; i < 1000; i++) { + arguments.add(attr1); + } + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1000, bag.size()); + + } + + + + @Test + public void testInteger() { + + BigInteger s1 = new BigInteger("123"); + BigInteger s2 = new BigInteger("456"); + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(s1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(s2)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_INTEGER_BAG; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_BAG, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // bag with only one + arguments.clear(); + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // zero args => empty bag + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + assertEquals(0, bag.size()); + + + // null argument + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-bag Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // argument of other type + arguments.clear(); + arguments.add(attrString); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-bag Expected data type 'integer' saw 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args (check response is correct) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(2, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + + // duplicate args (verify return) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // lots of args + arguments.clear(); + for (int i = 0; i < 1000; i++) { + arguments.add(attr1); + } + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1000, bag.size()); + + } + + + + + @Test + public void testDouble() { + + Double s1 = 123.45; + Double s2 = 678.901; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(s1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(s2)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_DOUBLE_BAG; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_BAG, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // bag with only one + arguments.clear(); + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // zero args => empty bag + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + assertEquals(0, bag.size()); + + + // null argument + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-bag Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // argument of other type + arguments.clear(); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-bag Expected data type 'double' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args (check response is correct) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(2, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + + // duplicate args (verify return) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // lots of args + arguments.clear(); + for (int i = 0; i < 1000; i++) { + arguments.add(attr1); + } + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1000, bag.size()); + + } + + + + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java new file mode 100755 index 0000000..0a967f5 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java
@@ -0,0 +1,121 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test functions in the abstract FunctionDefinitionSimpleTest class. + * Functions are tested by creating instances of other classes that should have appropriate properties to verify all variations of the responses expected. + * + * Note: we do not test getDataTypeId() because all it does is get the String out of the Identity object and we assume that the Data Type Identity objects + * are tested enough in everything else that any errors in them will be found and fixed quickly. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionBaseTest { + /** + * getId() is pretty trivial, so verifying one should be enough to check that the mechanism is working ok + */ + @Test + public void testGetId() { + FunctionDefinition fd = StdFunctions.FD_STRING_EQUAL; + Identifier id = fd.getId(); + assertTrue(XACML3.ID_FUNCTION_STRING_EQUAL.stringValue().equals(id.stringValue()) ); + } + + /** + * check an instance of every result type that we can deal with + */ + @Test + public void testGetDataType() { + +//?? Need functions that return each of these data types except for Boolean which is returned by any of the EQUAL functions + FunctionDefinition fdstring = StdFunctions.FD_STRING_NORMALIZE_SPACE; + assertEquals(XACML3.ID_DATATYPE_STRING, fdstring.getDataTypeId()); + + FunctionDefinition fdboolean = StdFunctions.FD_STRING_EQUAL; + assertEquals(XACML3.ID_DATATYPE_BOOLEAN, fdboolean.getDataTypeId()); + + FunctionDefinition fdinteger = StdFunctions.FD_INTEGER_ADD; + assertEquals(XACML3.ID_DATATYPE_INTEGER, fdinteger.getDataTypeId()); + + FunctionDefinition fddouble = StdFunctions.FD_DOUBLE_ADD; + assertEquals(XACML3.ID_DATATYPE_DOUBLE, fddouble.getDataTypeId()); + + FunctionDefinition fddate = StdFunctions.FD_DATE_BAG; + assertEquals(XACML3.ID_DATATYPE_DATE, fddate.getDataTypeId()); + + FunctionDefinition fdtime = StdFunctions.FD_TIME_BAG; + assertEquals(XACML3.ID_DATATYPE_TIME, fdtime.getDataTypeId()); + + FunctionDefinition fddateTime = StdFunctions.FD_DATETIME_BAG; + assertEquals(XACML3.ID_DATATYPE_DATETIME, fddateTime.getDataTypeId()); + + FunctionDefinition fddayTimeDuration = StdFunctions.FD_DAYTIMEDURATION_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_DAYTIMEDURATION, fddayTimeDuration.getDataTypeId()); + + FunctionDefinition fdyearMonthDuration = StdFunctions.FD_YEARMONTHDURATION_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_YEARMONTHDURATION, fdyearMonthDuration.getDataTypeId()); + + FunctionDefinition fdanyURI = StdFunctions.FD_ANYURI_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_ANYURI, fdanyURI.getDataTypeId()); + + FunctionDefinition fdhexBinary = StdFunctions.FD_HEXBINARY_UNION; + assertEquals(XACML3.ID_DATATYPE_HEXBINARY, fdhexBinary.getDataTypeId()); + + FunctionDefinition fdbase64Binary = StdFunctions.FD_BASE64BINARY_UNION; + assertEquals(XACML3.ID_DATATYPE_BASE64BINARY, fdbase64Binary.getDataTypeId()); + + FunctionDefinition fdrfc822Name = StdFunctions.FD_RFC822NAME_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_RFC822NAME, fdrfc822Name.getDataTypeId()); + + FunctionDefinition fdx500Name = StdFunctions.FD_X500NAME_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_X500NAME, fdx500Name.getDataTypeId()); + +//TODO - There are currently no functions that return XPathExpression objects +// FunctionDefinition fdxpathExpression = StdFunctions.FD_XPATHEXPRESSION_FROM_STRING; +// assertEquals(XACML3.ID_DATATYPE_XPATHEXPRESSION, fdxpathExpression.getDataTypeId()); + + FunctionDefinition fdipAddress = StdFunctions.FD_IPADDRESS_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_IPADDRESS, fdipAddress.getDataTypeId()); + + FunctionDefinition fddnsName = StdFunctions.FD_DNSNAME_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_DNSNAME, fddnsName.getDataTypeId()); + } + + /** + * check the type of return, single vs multiple values + */ + @Test + public void testReturnsBag() { + FunctionDefinition fdNotBag = StdFunctions.FD_BOOLEAN_EQUAL; + assertFalse(fdNotBag.returnsBag()); + + FunctionDefinitionBag<?> fdBag = (FunctionDefinitionBag<?>) StdFunctions.FD_STRING_BAG; + assertTrue(fdBag.returnsBag()); + } + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java new file mode 100755 index 0000000..a93bf14 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java
@@ -0,0 +1,1356 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.ISO8601Date; +import com.att.research.xacml.std.datatypes.ISO8601DateTime; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test FunctionDefinitionComparison + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionComparisonTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + FunctionArgumentAttributeValue stringAttr1 = null; + FunctionArgumentAttributeValue stringAttr1a = null; + FunctionArgumentAttributeValue stringAttr2 = null; + FunctionArgumentAttributeValue stringAttrNeg1 = null; + + + FunctionArgumentAttributeValue intAttr1 = null; + FunctionArgumentAttributeValue intAttr1a = null; + FunctionArgumentAttributeValue intAttr2 = null; + FunctionArgumentAttributeValue intAttr0 = null; + FunctionArgumentAttributeValue intAttrNeg1 = null; + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr1a = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attrNeg1 = null; + + FunctionArgumentAttributeValue attrDateToday = null; + FunctionArgumentAttributeValue attrDateSameDay = null; + FunctionArgumentAttributeValue attrDateTommorrow = null; + FunctionArgumentAttributeValue attrDateYesterday = null; + FunctionArgumentAttributeValue attrDateWithTimeZone = null; + FunctionArgumentAttributeValue attrDateNoTimeZone = null; + + + FunctionArgumentAttributeValue attrTimeToday = null; + FunctionArgumentAttributeValue attrTimeSameDay = null; + FunctionArgumentAttributeValue attrTimeTommorrow = null; + FunctionArgumentAttributeValue attrTimeYesterday = null; + FunctionArgumentAttributeValue attrTimeWithTimeZone = null; + FunctionArgumentAttributeValue attrTimeNoTimeZone = null; + + FunctionArgumentAttributeValue attrDateTimeToday = null; + FunctionArgumentAttributeValue attrDateTimeSameDay = null; + FunctionArgumentAttributeValue attrDateTimeTommorrow = null; + FunctionArgumentAttributeValue attrDateTimeYesterday = null; + FunctionArgumentAttributeValue attrDateTimeWithTimeZone = null; + FunctionArgumentAttributeValue attrDateTimeNoTimeZone = null; + + /** + * Set up some common variables on startup + */ + public FunctionDefinitionComparisonTest() { + try { + stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def")); + stringAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("AAA")); + + + intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + intAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + intAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + intAttr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + intAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1)); + + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0)); + attr1a = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.4)); + attrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-1.0)); + + // create dates + Calendar calendar = Calendar.getInstance(); + Date today = calendar.getTime(); + Date longAgo = new Date(1234); + // create a date that is different than "today" but within the same day (i.e. has a different hour) + if (calendar.get(Calendar.HOUR_OF_DAY) > 3) { + calendar.set(Calendar.HOUR_OF_DAY, 3); + } else { + calendar.set(Calendar.HOUR_OF_DAY, 5); + } + Date todayPlus = calendar.getTime(); + calendar.add(Calendar.DATE, 1); + Date tommorrow = calendar.getTime(); + attrDateToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today)); + attrDateSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(todayPlus)); + attrDateTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(tommorrow)); + attrDateYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(longAgo)); + ISO8601Date isoDate = new ISO8601Date(1920, 5, 8); + attrDateNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(isoDate)); + isoDate = new ISO8601Date("GMT+00:02", 1920, 5, 8); + attrDateWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(isoDate)); + + // create Times + ISO8601Time isoTime = new ISO8601Time(14, 43, 12, 145); + attrTimeToday = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + attrTimeSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + isoTime = new ISO8601Time(18, 53, 34, 423); + attrTimeTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + isoTime = new ISO8601Time(7, 34, 6,543); + attrTimeYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + isoTime = new ISO8601Time(12, 12, 12, 12); + attrTimeNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + isoTime = new ISO8601Time("GMT:+00:03", 12, 12, 12, 12); + attrTimeWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + + // create DateTimes + isoDate = new ISO8601Date(1920, 5, 8); + isoTime = new ISO8601Time( 18, 53, 34, 423); + ISO8601DateTime isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 18, 53, 34, 423); + attrDateTimeToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + attrDateTimeSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + isoTime = new ISO8601Time(20, 53, 34, 423); + isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 20, 53, 34, 423); + attrDateTimeTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + isoTime = new ISO8601Time(7, 34, 6,543); + isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 7, 34, 6, 543); + attrDateTimeYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + isoTime = new ISO8601Time(12, 12, 12, 12); + isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 12, 12, 12, 12); + attrDateTimeNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + isoTime = new ISO8601Time("GMT:+00:03", 12, 12, 12, 12); + isoDate = new ISO8601Date("GMT:+00:03", 1920, 5, 8); + isoDateTime = new ISO8601DateTime("GMT:+00:03", 1920, 5, 8, 12, 12, 12, 12); + attrDateTimeWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + + + + + } catch (Exception e) { + fail("Error creating values e="+ e); + } + } + + /** + * String + */ + @Test + public void testString_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(stringAttr1); + arguments.add(stringAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check first < second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(intAttr1); + arguments.add(stringAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + } + + @Test + public void testString_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(stringAttr1); + arguments.add(stringAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check first < second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testString_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(stringAttr1); + arguments.add(stringAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check first < second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testString_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(stringAttr1); + arguments.add(stringAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check first < second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + /** + * Integer + */ + @Test + public void testInteger_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check first < second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + } + + @Test + public void testInteger_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check first < second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testInteger_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check first < second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testInteger_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check first < second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + + /** + * Double + */ + @Test + public void testDouble_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + @Test + public void testDouble_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testDouble_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testDouble_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + /** + * Date + */ + + @Test + public void testDate_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateToday); + arguments.add(attrDateSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? One with TimeZone and one without + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // test with TimeZone vs without + arguments.clear(); + arguments.add(attrDateWithTimeZone); + arguments.add(attrDateNoTimeZone); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + + @Test + public void testDate_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateToday); + arguments.add(attrDateSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testDate_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateToday); + arguments.add(attrDateSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testDate_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateToday); + arguments.add(attrDateSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + + + + + /** + * Time + */ + + @Test + public void testTime_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrTimeToday); + arguments.add(attrTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? One with TimeZone and one without + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // test with TimeZone vs without + arguments.clear(); + arguments.add(attrTimeWithTimeZone); + arguments.add(attrTimeNoTimeZone); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + + @Test + public void testTime_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrTimeToday); + arguments.add(attrTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testTime_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrTimeToday); + arguments.add(attrTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testTime_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrTimeToday); + arguments.add(attrTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + + + /** + * Time-in-range + */ + @Test + public void testTime_in_range() { + + FunctionDefinitionTimeInRange<?> fd = (FunctionDefinitionTimeInRange<?>) StdFunctions.FD_TIME_IN_RANGE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_IN_RANGE, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(3), fd.getNumArgs()); + + // arg 0 in range of others + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + arguments.add(attrTimeTommorrow); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // below range + arguments.clear(); + arguments.add(attrTimeYesterday); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // above range + arguments.clear(); + arguments.add(attrTimeTommorrow); + arguments.add(attrTimeYesterday); + arguments.add(attrTimeToday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // range bad + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bad types + arguments.clear(); + arguments.add(attrDateTimeWithTimeZone); + arguments.add(attrDateTimeNoTimeZone); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-in-range Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrDateTimeWithTimeZone); + arguments.add(attrDateTimeNoTimeZone); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-in-range Expected data type 'time' saw 'dateTime' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + /** + * DateTime + */ + + @Test + public void testDateTime_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? One with TimeZone and one without + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // test with TimeZone vs without + arguments.clear(); + arguments.add(attrDateTimeWithTimeZone); + arguments.add(attrDateTimeNoTimeZone); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + + @Test + public void testDateTime_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testDateTime_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testDateTime_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + +} \ No newline at end of file
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java new file mode 100755 index 0000000..d502375 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java
@@ -0,0 +1,1582 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.ISO8601Date; +import com.att.research.xacml.std.datatypes.ISO8601DateTime; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacml.std.datatypes.ISO8601TimeZone; +import com.att.research.xacml.std.datatypes.XPathDayTimeDuration; +import com.att.research.xacml.std.datatypes.XPathYearMonthDuration; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionDateTimeArithmeticTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + ExpressionResult res; + + + @Test + public void testDateTime_add_dayTimeDuration() { + // Date objects to be adjusted + ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 777)); + ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, + new ISO8601Date(2000, 12, 31), + new ISO8601Time(23, 59, 30, 1)); + ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, + new ISO8601Date(-2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0)); + ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0)); + ISO8601DateTime dateTimeIIC102Result = null; + + // Durations + XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0); + XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3); + XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3); + XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 3.223); + XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + FunctionArgumentAttributeValue attrDateTimeIIC102 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + FunctionArgumentAttributeValue attrDurationIIC102 = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5)); + attrDateTimeIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(DataTypes.DT_DATETIME.convert("2002-03-22T08:23:47-05:00"))); + + dateTimeIIC102Result = DataTypes.DT_DATETIME.convert("2002-03-27T10:23:47-05:00"); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover)); + attrDurationIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("P5DT2H0M0S")); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_DAYTIMEDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + ISO8601DateTime testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 17), + new ISO8601Time(19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 7), + new ISO8601Time(5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + // millisecs work correctly + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 17), + new ISO8601Time(19, 23, 18, 0) ); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2001, 1, 1), + new ISO8601Time(0, 0, 0, 0) ); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(-2000, 1, 17), + new ISO8601Time(19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 17), + new ISO8601Time(timeZone0, 19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 17), + new ISO8601Time(timeZone5, 19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // conformance test IIC102 + arguments.clear(); + arguments.add(attrDateTimeIIC102); + arguments.add(attrDurationIIC102); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeIIC102Result, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + @Test + public void testDateTime_subtract_dayTimeDuration() { + // Date objects to be adjusted + ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 777)); + ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, + new ISO8601Date(2001, 1, 1), + new ISO8601Time(0, 0, 0, 0) ); + ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, + new ISO8601Date(-2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0)); + ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0)); + + // Durations + XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0); + XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3); + XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3); + XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 14.778); + XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_DAYTIMEDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + ISO8601DateTime testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 7), + new ISO8601Time(5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 17), + new ISO8601Time(19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // millisecs work correctly + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 7), + new ISO8601Time(5, 2, 59, 999) ); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 12, 31), + new ISO8601Time(23, 59, 30, 1)); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(-2000, 1, 7), + new ISO8601Time(5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 7), + new ISO8601Time(timeZone0, 5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 7), + new ISO8601Time(timeZone5, 5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + + + + @Test + public void testDateTime_add_yearMonthDuration() { + // Date objects to be adjusted + ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 777)); + ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, + new ISO8601Date(2000, 12, 31), + new ISO8601Time(23, 59, 30, 1)); + ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, + new ISO8601Date(-2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0)); + ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0)); + + // Durations + XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0); + XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7); + XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + ISO8601DateTime testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2005, 8, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(1994, 6, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // millisecs work correctly (not relevant to YearMonth, but should not break + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2005, 8, 12), + new ISO8601Time(12, 13, 14, 777) ); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2001, 1, 31), + new ISO8601Time(23, 59, 30, 1) ); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(-1995, 8, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone0, + new ISO8601Date(timeZone0, 2005, 8, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone5, + new ISO8601Date(timeZone5, 2005, 8, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + @Test + public void testDateTime_subtract_yearMonthDuration() { + // Date objects to be adjusted + ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 777)); + ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 1), + new ISO8601Time(23, 59, 30, 1)); + ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, + new ISO8601Date(-2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0)); + ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0)); + + // Durations + XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0); + XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7); + XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + ISO8601DateTime testResponse = new ISO8601DateTime( + null, + new ISO8601Date(1994, 6, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2005, 8, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // millisecs work correctly (not relevant to YearMonth, but should not break + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(1994, 6, 12), + new ISO8601Time(12, 13, 14, 777) ); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(1999, 12, 1), + new ISO8601Time(23, 59, 30, 1) ); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(-2006, 6, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone0, + new ISO8601Date(timeZone0, 1994, 6, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone5, + new ISO8601Date(timeZone5, 1994, 6, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + + + + + + @Test + public void testDate_add_yearMonthDuration() { + // Date objects to be adjusted + ISO8601Date dateTimeStdExample1 = new ISO8601Date(2000, 1, 12); + ISO8601Date dateTimeMsecs =new ISO8601Date(2000, 1, 12); + ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 12, 31); + ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12); + ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12); + + // Durations + XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0); + XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7); + XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_ADD_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + ISO8601Date resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + ISO8601Date testResponse = new ISO8601Date(2005, 8, 12); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(1994, 6, 12); + assertEquals(testResponse, resValue); + + // millisecs work correctly (not relevant to YearMonth, but should not break + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(2005, 8, 12); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(2001, 1, 31); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(-1995, 8, 12); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(timeZone0, 2005, 8, 12); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(timeZone5, 2005, 8, 12); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + @Test + public void testDate_subtract_yearMonthDuration() { + // Date objects to be adjusted + ISO8601Date dateTimeStdExample1 =new ISO8601Date(2000, 1, 12); + ISO8601Date dateTimeMsecs = new ISO8601Date(2000, 1, 12); + ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 1, 1); + ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12); + ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12); + + // Durations + XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0); + XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7); + XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_SUBTRACT_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + ISO8601Date resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + ISO8601Date testResponse = new ISO8601Date(1994, 6, 12); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(2005, 8, 12); + assertEquals(testResponse, resValue); + + // millisecs work correctly (not relevant to YearMonth, but should not break + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(1994, 6, 12); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(1999, 12, 1); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(-2006, 6, 12); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(timeZone0, 1994, 6, 12); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(timeZone5, 1994, 6, 12); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java new file mode 100755 index 0000000..d092f60 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java
@@ -0,0 +1,1182 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML1; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.Base64Binary; +import com.att.research.xacml.std.datatypes.DataTypeRFC822Name; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.HexBinary; +import com.att.research.xacml.std.datatypes.RFC822Name; +import com.att.research.xacml.std.datatypes.XPathDayTimeDuration; +import com.att.research.xacml.std.datatypes.XPathYearMonthDuration; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test FunctionDefinitionEquality, all of its super-classes, and all XACML functions supported by that class. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-equal + * boolean-equal + * integer-equal + * double-equal + * date-equal + * time-equal + * dateTime-equal + * dayTimeDuration-equal + * yearMonthDuration-equal + * + * Each of these is put into a separate test method just to keep things organized. + * + * @author glenngriffin + * + */ +public class FunctionDefinitionEqualityTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + FunctionArgumentAttributeValue stringAttr1 = null; + FunctionArgumentAttributeValue stringAttr2 = null; + FunctionArgumentAttributeValue stringAttr3 = null; + FunctionArgumentAttributeValue stringAttr4 = null; + + FunctionArgumentAttributeValue booleanAttrT1 = null; + FunctionArgumentAttributeValue booleanAttrT2 = null; + FunctionArgumentAttributeValue booleanAttrF1 = null; + FunctionArgumentAttributeValue booleanAttrF2 = null; + + FunctionArgumentAttributeValue intAttr1 = null; + FunctionArgumentAttributeValue intAttr1a = null; + FunctionArgumentAttributeValue intAttr2 = null; + FunctionArgumentAttributeValue intAttr0 = null; + FunctionArgumentAttributeValue intAttrNeg1 = null; + + public FunctionDefinitionEqualityTest() { + try { + stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC")); + stringAttr4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def")); + + booleanAttrT1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + booleanAttrT2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + booleanAttrF1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + booleanAttrF2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + intAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + intAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + intAttr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + intAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + } + + + + + /** + * String (matching case) + */ + @Test + public void testString_Equal() { + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_STRING_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check "abc" with "abc" - separate string objects with same value + arguments.add(stringAttr1); + arguments.add(stringAttr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check "abc" with "ABC" (not same) + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + /** + * Boolean + */ + @Test + public void testBoolean_Equal() { + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_BOOLEAN_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BOOLEAN_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with same value + arguments.add(booleanAttrT1); + arguments.add(booleanAttrT2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check different values + arguments.clear(); + arguments.add(booleanAttrT1); + arguments.add(booleanAttrF1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * Integer + */ + @Test + public void testInteger_Equal() { + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_INTEGER_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with same value + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + /** + * Double + */ + @Test + public void testDouble_Equal() { + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr1a = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attrNeg1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0)); + attr1a = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.4)); + attrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-1.0)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DOUBLE_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + + + /** + * Date + */ + @Test + public void testDate_Equal() { + Calendar calendar = Calendar.getInstance(); + Date today = calendar.getTime(); + Date longAgo = new Date(1234); + // create a date that is different than "today" but within the same day (i.e. has a different hour) + if (calendar.get(Calendar.HOUR_OF_DAY) > 3) { + calendar.set(Calendar.HOUR_OF_DAY, 3); + } else { + calendar.set(Calendar.HOUR_OF_DAY, 5); + } + Date todayPlus = calendar.getTime(); + + + FunctionArgumentAttributeValue attrToday = null; + FunctionArgumentAttributeValue attrToday2 = null; + FunctionArgumentAttributeValue attrLaterToday = null; + FunctionArgumentAttributeValue attrYesterday = null; + try { + attrToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today)); + attrToday2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today)); + attrLaterToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(todayPlus)); + attrYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(longAgo)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DATE_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrToday); + arguments.add(attrToday2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrToday); + arguments.add(attrYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // Date objects with different times but within the same day should match + arguments.clear(); + arguments.add(attrToday); + arguments.add(attrLaterToday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + + /** + * Time + */ + @Test + public void testTime_Equal() { + + Date now = new Date(); + Date now2 = new Date(now.getTime()); + Date notNow = new Date(now.getTime() - 100000); + + FunctionArgumentAttributeValue attrNow = null; + FunctionArgumentAttributeValue attrNow2 = null; + FunctionArgumentAttributeValue attrNotNow = null; + try { + attrNow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(now)); + attrNow2 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(now2)); + attrNotNow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(notNow)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_TIME_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrNow); + arguments.add(attrNow2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrNow); + arguments.add(attrNotNow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + + /** + * DateTime + */ + @Test + public void testDateTime_Equal() { + Calendar calendar = Calendar.getInstance(); + Date today = calendar.getTime(); + Date longAgo = new Date(1234); + // create a dateTime that is different than "today" changing only the Timezone + if (calendar.get(Calendar.ZONE_OFFSET) > 3) { + calendar.set(Calendar.ZONE_OFFSET, 3); + } else { + calendar.set(Calendar.ZONE_OFFSET, 5); + } + Date todayPlus = calendar.getTime(); + + + FunctionArgumentAttributeValue attrToday = null; + FunctionArgumentAttributeValue attrToday2 = null; + FunctionArgumentAttributeValue attrLaterToday = null; + FunctionArgumentAttributeValue attrYesterday = null; + try { + attrToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(today)); + attrToday2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(today)); + attrLaterToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(todayPlus)); + attrYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(longAgo)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DATETIME_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrToday); + arguments.add(attrToday2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrToday); + arguments.add(attrYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // DateTime with different Zones should not match + arguments.clear(); + arguments.add(attrToday); + arguments.add(attrLaterToday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * dayTimeDuration - Version1 + */ + @Test + public void testDayTimeDuration_Equal_V1() { + + XPathDayTimeDuration dur1 = new XPathDayTimeDuration(1, 3, 5, 12, 38); + XPathDayTimeDuration dur2 = new XPathDayTimeDuration(1, 3, 5, 12, 38); + XPathDayTimeDuration differentDur = new XPathDayTimeDuration(-1, 4, 7, 5, 33); + + FunctionArgumentAttributeValue attrDur1 = null; + FunctionArgumentAttributeValue attrDur2 = null; + FunctionArgumentAttributeValue attrDifferentDur = null; + try { + attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur1)); + attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur2)); + attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(differentDur)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DAYTIMEDURATION_EQUAL_VERSION1; + + // check identity and type of the thing created + assertEquals(XACML1.ID_FUNCTION_DAYTIMEDURATION_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrDur1); + arguments.add(attrDur2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrDur1); + arguments.add(attrDifferentDur); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * dayTimeDuration - Current version + */ + @Test + public void testDayTimeDuration_Equal() { + + XPathDayTimeDuration dur1 = new XPathDayTimeDuration(1, 3, 5, 12, 38); + XPathDayTimeDuration dur2 = new XPathDayTimeDuration(1, 3, 5, 12, 38); + XPathDayTimeDuration differentDur = new XPathDayTimeDuration(-1, 4, 7, 5, 33); + + FunctionArgumentAttributeValue attrDur1 = null; + FunctionArgumentAttributeValue attrDur2 = null; + FunctionArgumentAttributeValue attrDifferentDur = null; + try { + attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur1)); + attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur2)); + attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(differentDur)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DAYTIMEDURATION_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrDur1); + arguments.add(attrDur2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrDur1); + arguments.add(attrDifferentDur); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + /** + * dayTimeDuration - Version1 + */ + @Test + public void testYearMonthDuration_Equal_V1() { + + XPathYearMonthDuration dur1 = new XPathYearMonthDuration(1, 3, 5); + XPathYearMonthDuration dur2 = new XPathYearMonthDuration(1, 3, 5); + XPathYearMonthDuration differentDur = new XPathYearMonthDuration(-1, 4, 7); + + FunctionArgumentAttributeValue attrDur1 = null; + FunctionArgumentAttributeValue attrDur2 = null; + FunctionArgumentAttributeValue attrDifferentDur = null; + try { + attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur1)); + attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur2)); + attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(differentDur)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_YEARMONTHDURATION_EQUAL_VERSION1; + + // check identity and type of the thing created + assertEquals(XACML1.ID_FUNCTION_YEARMONTHDURATION_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrDur1); + arguments.add(attrDur2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrDur1); + arguments.add(attrDifferentDur); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + + /** + * dayTimeDuration - Current version + */ + @Test + public void testYearMonthDuration_Equal() { + + XPathYearMonthDuration dur1 = new XPathYearMonthDuration(1, 3, 5); + XPathYearMonthDuration dur2 = new XPathYearMonthDuration(1, 3, 5); + XPathYearMonthDuration differentDur = new XPathYearMonthDuration(-1, 4, 7); + + FunctionArgumentAttributeValue attrDur1 = null; + FunctionArgumentAttributeValue attrDur2 = null; + FunctionArgumentAttributeValue attrDifferentDur = null; + try { + attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur1)); + attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur2)); + attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(differentDur)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_YEARMONTHDURATION_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrDur1); + arguments.add(attrDur2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrDur1); + arguments.add(attrDifferentDur); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * URI + */ + @Test + public void testAnyURI_Equal() { + + URI uri1 = null; + URI uri2 = null; + URI uriNotThere = null; + try { + uri1 = new URI("http://someplace.com/gothere"); + uri2 = new URI("http://someplace.com/gothere"); + uriNotThere = new URI("http://someplace.com/notGoingThere"); + } catch (Exception e) { + fail(e.toString()); + } + + FunctionArgumentAttributeValue attrUri1 = null; + FunctionArgumentAttributeValue attrUri2 = null; + FunctionArgumentAttributeValue attrUriNotThere = null; + try { + attrUri1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri1)); + attrUri2 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri2)); + attrUriNotThere = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uriNotThere)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_ANYURI_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrUri1); + arguments.add(attrUri2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrUri1); + arguments.add(attrUriNotThere); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * X500Name + */ + @Test + public void testX500Name_Equal() { + + X500Principal name1 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"); + X500Principal name2 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"); + X500Principal name3 = new X500Principal("CN=NotDuke, OU=NotThere, O=Oracle, C=US"); + + + FunctionArgumentAttributeValue attrName1 = null; + FunctionArgumentAttributeValue attrName1a = null; + FunctionArgumentAttributeValue attrNotSameName = null; + try { + attrName1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name1)); + attrName1a = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name2)); + attrNotSameName = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name3)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_X500NAME_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_X500NAME_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrName1); + arguments.add(attrName1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrNotSameName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + /** + * RFC822Name + */ + @Test + public void testRfc822Name_Equal() { + + RFC822Name name1 = null; + RFC822Name name1a = null; + RFC822Name differentLocalName = null; + RFC822Name differentDomainName = null; + RFC822Name localCaseName = null; + RFC822Name domainCaseName = null; + @SuppressWarnings("unused") + RFC822Name noAtName = null; + + try { + name1 = RFC822Name.newInstance("localPart@DomainPart"); + name1a = RFC822Name.newInstance("localPart@DomainPart"); + differentLocalName = RFC822Name.newInstance("differentlocalPart@DomainPart"); + differentDomainName = RFC822Name.newInstance("localPart@differentDomainPart"); + localCaseName = RFC822Name.newInstance("LOCALPart@DomainPart"); + domainCaseName = RFC822Name.newInstance("localPart@DOMAINPart"); + + + } catch (Exception e) { + fail(e.toString()); + } + + // should not be able to create a name without an @. If you try, newInstance returns null + Exception exSeen = null; + try { + noAtName = RFC822Name.newInstance("nameWithoutAnAtSign"); + } catch (Exception e) { + exSeen = e; + } + assertNotNull(exSeen); + + + FunctionArgumentAttributeValue attrName1 = null; + FunctionArgumentAttributeValue attrName1a = null; + FunctionArgumentAttributeValue attrDifferentLocalName = null; + FunctionArgumentAttributeValue attrDifferentDomainName = null; + FunctionArgumentAttributeValue attrLocalCaseName = null; + FunctionArgumentAttributeValue attrDomainCaseName = null; + try { + attrName1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(name1)); + attrName1a = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(name1a)); + attrDifferentLocalName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(differentLocalName)); + attrDifferentDomainName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(differentDomainName)); + attrLocalCaseName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(localCaseName)); + attrDomainCaseName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(domainCaseName)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_RFC822NAME_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_RFC822NAME_EQUAL, fd.getId()); + assertEquals(DataTypeRFC822Name.newInstance().getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrName1); + arguments.add(attrName1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same Local + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrDifferentLocalName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check not same Domain + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrDifferentDomainName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test case-sensitivity in local part + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrLocalCaseName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test non-case-sensitivity in Domain part + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrDomainCaseName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * Hex Binary + */ + @Test + public void testHexBinary_Equal() { + HexBinary binary = null; + HexBinary sameBinary = null; + HexBinary differentBinary = null; + try { + binary = HexBinary.newInstance("e04fd020ea3a6910a2d808002b30309d"); + sameBinary = HexBinary.newInstance("e04fd020ea3a6910a2d808002b30309d"); + differentBinary = HexBinary.newInstance("f123a890ee3d"); + } catch (Exception e) { + fail(e.toString()); + } + + FunctionArgumentAttributeValue attrBinary = null; + FunctionArgumentAttributeValue attrSameBinary = null; + FunctionArgumentAttributeValue attrDifferentBinary = null;; + try { + attrBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(binary)); + attrSameBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(sameBinary)); + attrDifferentBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(differentBinary)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_HEXBINARY_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_HEXBINARY_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_HEXBINARY.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrBinary); + arguments.add(attrSameBinary); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrBinary); + arguments.add(attrDifferentBinary); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * Base64 Binary + */ + @Test + public void testBase64Binary_Equal() { + Base64Binary binary = null; + Base64Binary sameBinary = null; + Base64Binary differentBinary = null; + try { + binary = Base64Binary.newInstance("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"); + sameBinary = Base64Binary.newInstance("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"); + differentBinary = Base64Binary.newInstance("f123a890ee3d"); + } catch (Exception e) { + fail(e.toString()); + } + + FunctionArgumentAttributeValue attrBinary = null; + FunctionArgumentAttributeValue attrSameBinary = null; + FunctionArgumentAttributeValue attrDifferentBinary = null; + try { + attrBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(binary)); + attrSameBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(sameBinary)); + attrDifferentBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(differentBinary)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_BASE64BINARY_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BASE64BINARY_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_BASE64BINARY.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrBinary); + arguments.add(attrSameBinary); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrBinary); + arguments.add(attrDifferentBinary); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java new file mode 100755 index 0000000..e2b9efc --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java
@@ -0,0 +1,2173 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionHigherOrderBagTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + + // + // ANY-OF tests + // + + + @Test + public void testAny_of() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansTrue = null; + Bag bagStringBooleansFalse = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrb = null; + FunctionArgumentAttributeValue attrh = null; + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrb = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(b)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANY_OF, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag in first position - match + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagabcdefg); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // multiple primitives + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrb); + arguments.add(attrBagace); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate error: function:string-equal Expected 2 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // no primitives - predicate function expects 2 + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansFalse); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // extra bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate error: function:string-equal Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Got null argument at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + @Test + public void testAll_of() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + FunctionArgumentAttributeValue attrw = null; + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w)); + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ALL_OF, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrw); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attra); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no primitives - predicate function expects 2 + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansFalse); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // extra bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Got null argument at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + @Test + public void testAny_of_any() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagBooleansFalse = null; + Bag bagBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + FunctionArgumentAttributeValue attrw = null; + + + FunctionArgumentAttributeValue attrInt4 = null; + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + FunctionArgumentAttributeValue attrPredicateNof = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagBooleansTrue = new Bag(); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + bagBooleansFalse = new Bag(); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w)); + + attrInt4 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(4)); + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + attrPredicateNof = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_N_OF)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse); + FunctionArgumentBag attrBagBooleansTrue = new FunctionArgumentBag(bagBooleansTrue); + FunctionArgumentBag attrBagBooleansFalse = new FunctionArgumentBag(bagBooleansFalse); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF_ANY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANY_OF_ANY, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrw); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attra); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no primitives - predicate function expects 2 + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansFalse); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // n-of with lots of bags - success + arguments.clear(); + arguments.add(attrPredicateNof); + arguments.add(attrInt4); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // n-of with lots of bags - fail + arguments.clear(); + arguments.add(attrPredicateNof); + arguments.add(attrInt4); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Bag is empty at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate error: function:string-greater-than Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Got null argument at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + + + @Test + public void testAll_of_any() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + String x = "x"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagawx = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagBooleansFalse = null; + Bag bagBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringLessThan = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagawx = new Bag(); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(w)); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(x)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagBooleansTrue = new Bag(); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + bagBooleansFalse = new Bag(); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringLessThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_LESS_THAN)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagawx = new FunctionArgumentBag(bagawx); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF_ANY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ALL_OF_ANY, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringLessThan); + arguments.add(attrBagabcdefg); + arguments.add(attrBagawx); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagawx); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // primitive instead of bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagEmpty); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + @Test + public void testAny_of_all() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + String x = "x"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagewx = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagBooleansFalse = null; + Bag bagBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThanOrEqual = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagewx = new Bag(); + bagewx.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagewx.add(DataTypes.DT_STRING.createAttributeValue(w)); + bagewx.add(DataTypes.DT_STRING.createAttributeValue(x)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagBooleansTrue = new Bag(); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + bagBooleansFalse = new Bag(); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringGreaterThanOrEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagewx = new FunctionArgumentBag(bagewx); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF_ALL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANY_OF_ALL, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThanOrEqual); + arguments.add(attrBagewx); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagewx); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // primitive instead of bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagEmpty); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + @Test + public void testAll_of_all() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + String x = "x"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagawx = null; + Bag bagwx = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagBooleansFalse = null; + Bag bagBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagawx = new Bag(); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(w)); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(x)); + bagwx = new Bag(); + bagwx.add(DataTypes.DT_STRING.createAttributeValue(w)); + bagwx.add(DataTypes.DT_STRING.createAttributeValue(x)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagBooleansTrue = new Bag(); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + bagBooleansFalse = new Bag(); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagawx = new FunctionArgumentBag(bagawx); + FunctionArgumentBag attrBagwx = new FunctionArgumentBag(bagwx); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF_ALL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ALL_OF_ALL, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagwx); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagawx); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagwx); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // primitive instead of bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagEmpty); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagwx); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + @Test + public void testMap() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagInt123 = null; + Bag bagInt789 = null; + + + // primitive attrs + FunctionArgumentAttributeValue attrh = null; + FunctionArgumentAttributeValue attrInt7 = null; + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringNormalizeToLowerCase = null; + FunctionArgumentAttributeValue attrPredicateIntegerEqual = null; + FunctionArgumentAttributeValue attrPredicateIntegerAdd = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue("A")); + bagace.add(DataTypes.DT_STRING.createAttributeValue("C")); + bagace.add(DataTypes.DT_STRING.createAttributeValue("E")); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagInt123 = new Bag(); + bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(1)); + bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(2)); + bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(3)); + bagInt789 = new Bag(); + bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(7)); + bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(8)); + bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(9)); + + + + // create primitive attrs + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + attrInt7 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(7)); + + + // predicates passed as function arguments + attrPredicateStringNormalizeToLowerCase = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE)); + attrPredicateIntegerEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_INTEGER_EQUAL)); + attrPredicateIntegerAdd = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_INTEGER_ADD)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + FunctionArgumentBag attrBagInt789 = new FunctionArgumentBag(bagInt789); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_MAP; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_MAP, fd.getId()); + assertNull( fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertTrue(res.isBag()); + Bag bag = res.getBag(); + assertEquals(3, bag.size()); + List<AttributeValue<?>> bagAttributes = bag.getAttributeValueList(); + try { + assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("a"))); + assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("A"))); + assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("c"))); + assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("C"))); + assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("e"))); + assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("E"))); + } catch (Exception ex) { + fail("checking result e="+ex); + } + + // 2-input predicate + arguments.clear(); + arguments.add(attrPredicateIntegerAdd); + arguments.add(attrInt7); + arguments.add(attrBagInt789); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertTrue(res.isBag()); + bag = res.getBag(); + assertEquals(3, bag.size()); + bagAttributes = bag.getAttributeValueList(); + try { + assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("14"))); + assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("15"))); + assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("16"))); + } catch (Exception ex) { + fail("checking result e="+ex); + } + + + // predicate returns booleans + arguments.clear(); + arguments.add(attrPredicateIntegerEqual); + arguments.add(attrInt7); + arguments.add(attrBagInt789); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertTrue(res.isBag()); + bag = res.getBag(); + assertEquals(3, bag.size()); + bagAttributes = bag.getAttributeValueList(); + try { + assertEquals(bagAttributes.get(0), (DataTypes.DT_BOOLEAN.createAttributeValue(true))); + assertEquals(bagAttributes.get(1), (DataTypes.DT_BOOLEAN.createAttributeValue(false))); + assertEquals(bagAttributes.get(2), (DataTypes.DT_BOOLEAN.createAttributeValue(false))); + } catch (Exception ex) { + fail("checking result e="+ex); + } + + // predicate returns bag + + + + // no primitives - predicate function expects 2 + arguments.clear(); + arguments.add(attrPredicateIntegerAdd); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Predicate error: function:integer-add Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertTrue(res.isBag()); + bag = res.getBag(); + assertEquals(0, bag.size());; + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // extra bag + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate gets unexpected number of args + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Predicate error: function:string-normalize-to-lower-case Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate gets bad primitive type + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Predicate error: function:string-normalize-to-lower-case Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Got null argument at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java new file mode 100755 index 0000000..e281212 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java
@@ -0,0 +1,140 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; + +/** + * FunctionDefinitionHomogeneousSimple is an abstract class, so we have to test it by creating a sub-class. + * The constructor is tested by default when an instance of the sub-class is created for other tests. + * + * Each of these functions needs to be tested for each type of function to be sure the values are correct, + * so this is just a simple test to see that the mechanism works. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionHomogeneousSimpleTest { + + + + @Test + public void testGetDataTypeArgs() { + + // test a simple instance using the Equality class + FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + } + + @Test + public void testGetNumArgs() { + // test a simple instance using the Equality class + FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING); + assertEquals(new Integer(2), fd.getNumArgs()); + } + + @Test + public void testValidateArguments() { + // create some arguments to use later + FunctionArgumentAttributeValue stringAttr1 = null; + FunctionArgumentAttributeValue stringAttr2 = null; + FunctionArgumentAttributeValue stringAttr3 = null; + FunctionArgumentAttributeValue intAttr = null; + try { + stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def")); + stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ghi")); + intAttr = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING); + List<String> convertedValues = new ArrayList<String>(); + List<FunctionArgument> listFunctionArguments = new ArrayList<FunctionArgument>(); + + // test correct # of args, both of them strings + listFunctionArguments.add(stringAttr1); + listFunctionArguments.add(stringAttr2); + Status status = fd.validateArguments(listFunctionArguments, convertedValues); + assertTrue(status.isOk()); + assertEquals(convertedValues.size(),2); + + // test too few args + listFunctionArguments.remove(1); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Expected 2 arguments, got 1", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + + // test too many args + listFunctionArguments.add(stringAttr2); + listFunctionArguments.add(stringAttr3); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Expected 2 arguments, got 3", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + + // test with null arg + listFunctionArguments.clear(); + listFunctionArguments.add(null); + listFunctionArguments.add(stringAttr1); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Got null argument at arg index 0", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + + // test function that takes 0 args +//TODO test with func that specifies 0 args? ASSUME for now that there are no such functions since a function needs to operate on something +// fail("need to test function with 0 args and various inputs - see validateArguments code"); + + + // test with one is a bag + listFunctionArguments.clear(); + listFunctionArguments.add(stringAttr1); + Bag bag = new Bag(); + FunctionArgument bagArg = new FunctionArgumentBag(bag); + listFunctionArguments.add(bagArg); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Expected a simple value, saw a bag at arg index 1", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + + // test with string and int + listFunctionArguments.clear(); + listFunctionArguments.add(stringAttr1); + listFunctionArguments.add(intAttr); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Expected data type 'string' saw 'integer' at arg index 1", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + } + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java new file mode 100755 index 0000000..9db4610 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java
@@ -0,0 +1,402 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionLogicalTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + // use the same args for each test + FunctionArgumentAttributeValue attrT = null; + FunctionArgumentAttributeValue attrF = null; + public FunctionDefinitionLogicalTest () { + try { + attrT = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + attrF = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + } + + + @Test + public void testOR() { + FunctionArgumentAttributeValue attr5 = null; + try { + attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_OR; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_OR, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // test normal + arguments.add(attrT); + arguments.add(attrF); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + arguments.clear(); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // test no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // first true, second error + arguments.clear(); + arguments.add(attrT); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // first false, second error + arguments.clear(); + arguments.add(attrF); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:or Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // multiple false + arguments.clear(); + arguments.add(attrF); + arguments.add(attrF); + arguments.add(attrF); + arguments.add(attrF); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // non-boolean + arguments.clear(); + arguments.add(attrF); + arguments.add(attr5); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:or Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg error + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:or Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testAND() { + FunctionArgumentAttributeValue attr5 = null; + try { + attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + + FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_AND; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_AND, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // test normal + arguments.add(attrT); + arguments.add(attrF); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + arguments.clear(); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // test no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // first true, second error + arguments.clear(); + arguments.add(attrT); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:and Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first false, second error + arguments.clear(); + arguments.add(attrF); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // multiple true + arguments.clear(); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(attrT); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // non-boolean + arguments.clear(); + arguments.add(attrT); + arguments.add(attr5); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals("function:and Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg error + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals("function:and Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + @Test + public void testN_of() { + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + + FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_N_OF; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_N_OF, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // test normal + arguments.add(attr2); + arguments.add(attrT); + arguments.add(attrF); + arguments.add(attrT); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // normal fail + arguments.clear(); + arguments.add(attr2); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + + // null count + arguments.clear(); + arguments.add(null); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // 0 count + arguments.clear(); + arguments.add(attr0); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // bad object type for count + arguments.clear(); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:n-of For input string: \"true\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // count larger than list + arguments.clear(); + arguments.add(attr2); + arguments.add(attrT); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:n-of Expected 2 arguments but only 1 arguments in list after the count", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // aborts after find ok + arguments.clear(); + arguments.add(attr2); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // error before find ok + arguments.clear(); + arguments.add(attr2); + arguments.add(null); + arguments.add(attrT); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:n-of Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // non-boolean in list + arguments.clear(); + arguments.add(attr2); + arguments.add(attrT); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:n-of Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testNot() { + + FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_NOT; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_NOT, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // test normal + arguments.clear(); + arguments.add(attrT); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + arguments.clear(); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + + // test null/0 args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:not Expected 1 argument, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // test 2 args + arguments.clear(); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:not Expected 1 argument, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java new file mode 100755 index 0000000..add8069 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java
@@ -0,0 +1,99 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Tests for various classes containing only one function. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionNumberTypeConversionTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + @Test + public void testDouble_to_integer() { + FunctionArgumentAttributeValue attr1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(5.432)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionNumberTypeConversion<?, ?> fd = (FunctionDefinitionNumberTypeConversion<?, ?>) StdFunctions.FD_DOUBLE_TO_INTEGER; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(5), resValue); + } + + + @Test + public void testInteger_to_double() { + FunctionArgumentAttributeValue attr1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionNumberTypeConversion<?, ?> fd = (FunctionDefinitionNumberTypeConversion<?, ?>) StdFunctions.FD_INTEGER_TO_DOUBLE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(5.0), resValue); + } + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java new file mode 100755 index 0000000..1381076 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java
@@ -0,0 +1,491 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.IPAddress; +import com.att.research.xacml.std.datatypes.RFC2396DomainName; +import com.att.research.xacml.std.datatypes.RFC822Name; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionRegexpMatchTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @Test + public void testString() { + String v1 = new String("abc"); + String v2 = new String("def"); + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrV2 = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2)); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_STRING_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrV1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // null regex + arguments.clear(); + arguments.add(null); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null object to match + arguments.clear(); + arguments.add(attrV1); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // regex not string + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // object to match not correct type + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + @Test + public void testAnyURI() { + String regexp = new String("abc"); + URI uri1 = null; + URI uri2 = null; + try { + uri1 = new URI("abc"); + uri2 = new URI("def"); + } catch (Exception e) { + fail("Unable to create URIs, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrUri1 = null; + FunctionArgumentAttributeValue attrUri2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrUri1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri1)); + attrUri2 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_ANYURI_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrUri1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrUri2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-regexp-match Expected data type 'anyURI' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testIpAddress() { + String regexp = new String(".*123.*"); + IPAddress addr1 = null; + IPAddress addr2 = null; + try { + addr1 = IPAddress.newInstance("199.123.45.67"); + addr2 = IPAddress.newInstance("12.34.67.87"); + } catch (Exception e) { + fail("Unable to create IPAddresses, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrAddr1 = null; + FunctionArgumentAttributeValue attrAddr2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(addr1)); + attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(addr2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_IPADDRESS_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-regexp-match Expected data type 'ipAddress' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testDnsName() { + String regexp = new String("abc"); + RFC2396DomainName addr1 = null; + RFC2396DomainName addr2 = null; + try { + addr1 = RFC2396DomainName.newInstance("abc"); + addr2 = RFC2396DomainName.newInstance("def"); + } catch (Exception e) { + fail("Unable to create DNSNames, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrAddr1 = null; + FunctionArgumentAttributeValue attrAddr2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(addr1)); + attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(addr2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_DNSNAME_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-regexp-match Expected data type 'dnsName' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testRfc822Name() { + String regexp = new String(".*abc.*"); + RFC822Name addr1 = null; + RFC822Name addr2 = null; + try { + addr1 = RFC822Name.newInstance("abc@somewhere"); + addr2 = RFC822Name.newInstance("def@somewhere"); + } catch (Exception e) { + fail("Unable to create RFC822Names, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrAddr1 = null; + FunctionArgumentAttributeValue attrAddr2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(addr1)); + attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(addr2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_RFC822NAME_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-regexp-match Expected data type 'rfc822Name' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testX500Name() { + String regexp = new String(".*Duke.*"); + X500Principal addr1 = null; + X500Principal addr2 = null; + try { + addr1 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"); + addr2 = new X500Principal("CN=Policy Engine, OU=Research, O=ATT, C=US"); + } catch (Exception e) { + fail("Unable to create X500Name, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrAddr1 = null; + FunctionArgumentAttributeValue attrAddr2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(addr1)); + attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(addr2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_X500NAME_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:x500Name-regexp-match Expected data type 'x500Name' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java new file mode 100755 index 0000000..0331386 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java
@@ -0,0 +1,1883 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionSetTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + + // + // INTERSECTION tests + // + + + @Test + public void testString_intersection() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_INTERSECTION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_INTERSECTION, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(7, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // several but not all intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // one intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(f, attrValueObject.getValue() ); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(f, attrValueObject.getValue() ); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // first bag is empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // second bag is empty + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + @Test + public void testInteger_intersection() { + BigInteger a = new BigInteger("1"); + BigInteger b = new BigInteger("2"); + BigInteger c = new BigInteger("3"); + BigInteger d = new BigInteger("4"); + BigInteger e = new BigInteger("5"); + BigInteger f = new BigInteger("6"); + BigInteger g = new BigInteger("7"); + BigInteger h = new BigInteger("8"); + BigInteger j = new BigInteger("9"); + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagace.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagace.add(DataTypes.DT_INTEGER.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_INTEGER.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue("abc")); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(1)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_INTEGER_INTERSECTION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_INTERSECTION, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(7, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // several but not all intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // one intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(f, attrValueObject.getValue() ); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(f, attrValueObject.getValue() ); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // first bag is empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // second bag is empty + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + // + // AT_LEAST_ONE_MEMBER_OF tests + // + + @Test + public void testString_at_least_one_member_of() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaaccce = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaaccce = new Bag(); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_AT_LEAST_ONE_MEMBER_OF; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // several but not all intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // one intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // 2 empty bags + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first non-empty, 2nd empty + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first empty, 2nd not empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + // + // UNION tests + // + + + + + + @Test + public void testString_union() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_UNION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_UNION, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(7, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // several but not all union + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(8, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // bag one has duplicates that do not match first bag + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(8, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // bag one has duplicates that do match first bag + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // bag 2 has duplicates that do not match first bag + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(8, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // bag 2 has duplicates that do match first bag + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // two empty bags + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // first bag empty, 2nd not empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + + // first bag not empty, 2nd empty + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + // + // SUBSET tests + // + + @Test + public void testString_subset() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaaccce = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaaccce = new Bag(); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_SUBSET; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_SUBSET, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // not subset + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // subset + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // Not + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // Subset + arguments.clear(); + arguments.add(attrBagb); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // 2 empty bags + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first non-empty, 2nd empty + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first empty, 2nd not empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrBagb); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + // + // SET_EQUALS tests + // + + @Test + public void testString_set_equals() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaaccce = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaaccce = new Bag(); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_SET_EQUALS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_SET_EQUALS, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // several but not all intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // one intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // 2 empty bags + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first non-empty, 2nd empty + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first empty, 2nd not empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java new file mode 100755 index 0000000..f5c786f --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java
@@ -0,0 +1,467 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionSpecialMatchTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + @Test + public void testX500NameMatch() { + // assume that the contents of the name components are not significant and we can treat them as simple blocks of "<name>=<value>" + String A = "cn=Some person"; + String B = "O=Medico Corp"; + String C = "C=US"; + String D = "DNQUALIFIER=d string"; + String E = "SURNAME=some name"; + String F = "INITIALS=inits"; + + + X500Principal abc = new X500Principal(A + "," + B + "," + C); + X500Principal dabc = new X500Principal(D + "," + A + "," + B + "," + C); + X500Principal abcd = new X500Principal(A + "," + B + "," + C + "," + D); + X500Principal adbc = new X500Principal(A + "," + D + "," + B + "," + C); + X500Principal dcab = new X500Principal(D + "," + C + "," + A + "," + B) ; + X500Principal def = new X500Principal(D + "," + E + "," + F) ; + + + FunctionArgumentAttributeValue attrABC = null; + FunctionArgumentAttributeValue attrDABC = null; + FunctionArgumentAttributeValue attrABCD = null; + FunctionArgumentAttributeValue attrADBC = null; + FunctionArgumentAttributeValue attrDCAB = null; + FunctionArgumentAttributeValue attrDEF = null; + + FunctionArgumentAttributeValue attrBad = null; + FunctionArgumentBag attrBag = new FunctionArgumentBag(new Bag()); + + + try { + attrABC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(abc)); + attrDABC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(dabc)); + attrABCD = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(abcd)); + attrADBC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(adbc)); + attrDCAB = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(dcab)); + attrDEF = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(def)); + + attrBad = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionX500NameMatch fd = (FunctionDefinitionX500NameMatch) StdFunctions.FD_X500NAME_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_X500NAME_MATCH, fd.getId()); + assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal, first exact match for second + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrABC); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test first is end of second + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrDABC); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first exact match for sub-section but not end of second + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrABCD); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // components of first match components in second but not contiguous + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrADBC); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // components of first match components in second but not in order + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrDCAB); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first does not match second at all + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrDEF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first arg larger than 2nd arg + arguments.clear(); + arguments.add(attrABCD); + arguments.add(attrABC); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bad arg types + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrBad); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected data type 'x500Name' saw 'integer' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrABC); + arguments.add(attrABC); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrABC); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg is bag + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrBag); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected a simple value, saw a bag at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null arg + arguments.clear(); + arguments.add(null); + arguments.add(attrBag); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testRfc822NameMatch() { + + + + + FunctionArgumentAttributeValue attrStringabcxyz = null; + FunctionArgumentAttributeValue attrStringABCxyz = null; + FunctionArgumentAttributeValue attrStringabcXYZ = null; + FunctionArgumentAttributeValue attrStringcx = null; + FunctionArgumentAttributeValue attrStringwholedomainpart = null; + FunctionArgumentAttributeValue attrStringWholeDomainPart = null; + FunctionArgumentAttributeValue attrStringWholeDomain = null; + FunctionArgumentAttributeValue attrStringdomainpart = null; + FunctionArgumentAttributeValue attrStringDomainPart = null; + FunctionArgumentAttributeValue attrStringdotWholeDomain = null; + FunctionArgumentAttributeValue attrStringdomain = null; + + FunctionArgumentAttributeValue attrStringNoMatch = null; + FunctionArgumentAttributeValue attrStringMultipleAt = null; + FunctionArgumentAttributeValue attrStringMissingLocal = null; + FunctionArgumentAttributeValue attrStringMissingDomain = null; + + + FunctionArgumentAttributeValue attrRfcabcxyz = null; + FunctionArgumentAttributeValue attrRfcwholedomainpart = null; + FunctionArgumentAttributeValue attrRfcWholeDomainPart = null; + + FunctionArgumentBag attrBag = new FunctionArgumentBag(new Bag()); + + try { + attrStringabcxyz = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc@xyz")); + attrStringABCxyz = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC@xyz")); + attrStringabcXYZ = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc@XYZ")); + attrStringcx = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("c@x")); + attrStringwholedomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("whole.domain.part")); + attrStringWholeDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Whole.Domain.Part")); + attrStringWholeDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Whole.Domain")); + attrStringdomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".domain.part")); + attrStringDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".Domain.Part")); + attrStringdotWholeDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".Whole.Domain")); + attrStringdomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".domain.")); + + attrStringNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("no match to any legal name")); + attrStringMultipleAt = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("name@with@multipleAts")); + attrStringMissingLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("@multipleAts")); + attrStringMissingDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("localpart@")); + + attrRfcabcxyz = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@xyz")); + attrRfcwholedomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@whole.domain.part")); + attrRfcWholeDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@Whole.Domain.Part")); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionRFC822NameMatch fd = (FunctionDefinitionRFC822NameMatch) StdFunctions.FD_RFC822NAME_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_RFC822NAME_MATCH, fd.getId()); + assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // string identical to name - exact match on whole search term + arguments.clear(); + arguments.add(attrStringabcxyz); + arguments.add(attrRfcabcxyz); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no match local case different + arguments.clear(); + arguments.add(attrStringABCxyz); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // match domain case different + arguments.clear(); + arguments.add(attrStringabcXYZ); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // partial local + partial domain + arguments.clear(); + arguments.add(attrStringcx); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // whole domain + arguments.clear(); + arguments.add(attrStringwholedomainpart); + arguments.add(attrRfcwholedomainpart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // whole domain different case + arguments.clear(); + arguments.add(attrStringWholeDomainPart); + arguments.add(attrRfcwholedomainpart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrStringwholedomainpart); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // whole domain fail + arguments.clear(); + arguments.add(attrStringWholeDomain); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // partial domain match + arguments.clear(); + arguments.add(attrStringDomainPart); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // partial domain different case + arguments.clear(); + arguments.add(attrStringdomainpart); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // partial domain fail + arguments.clear(); + arguments.add(attrStringdotWholeDomain); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrStringdomain); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // search term contains more than 1 @ + arguments.clear(); + arguments.add(attrStringMultipleAt); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match String contained more than 1 '@' in 'name@with@multipleAts'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // search term missing local part + arguments.clear(); + arguments.add(attrStringMissingLocal); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match String missing local part in '@multipleAts'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // search term missing domain part + arguments.clear(); + arguments.add(attrStringMissingDomain); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match String missing domain part in 'localpart@'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg types + arguments.clear(); + arguments.add(attrRfcabcxyz); + arguments.add(attrStringNoMatch); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected data type 'string' saw 'rfc822Name' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrStringNoMatch); + arguments.add(attrStringNoMatch); + arguments.add(attrStringNoMatch); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrStringNoMatch); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg is bag + arguments.clear(); + arguments.add(attrStringNoMatch); + arguments.add(attrBag); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected a simple value, saw a bag at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null arg + arguments.clear(); + arguments.add(null); + arguments.add(attrStringNoMatch); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + } + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java new file mode 100755 index 0000000..8800097 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java
@@ -0,0 +1,2484 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.IPAddress; +import com.att.research.xacml.std.datatypes.IPv4Address; +import com.att.research.xacml.std.datatypes.IPv6Address; +import com.att.research.xacml.std.datatypes.ISO8601Date; +import com.att.research.xacml.std.datatypes.ISO8601DateTime; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacml.std.datatypes.ISO8601TimeZone; +import com.att.research.xacml.std.datatypes.PortRange; +import com.att.research.xacml.std.datatypes.RFC2396DomainName; +import com.att.research.xacml.std.datatypes.RFC822Name; +import com.att.research.xacml.std.datatypes.XPathDayTimeDuration; +import com.att.research.xacml.std.datatypes.XPathYearMonthDuration; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Tests for converting objects to/from Strings. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionStringConversionTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + /** + * Boolean + */ + @Test + public void testBoolean_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("true")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_BOOLEAN_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-from-string Cannot convert from \"java.lang.String\" with value \"not valid obj value\" to boolean", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_boolean() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "false"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_BOOLEAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-boolean Expected data type 'boolean' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + /** + * Integer + */ + @Test + public void testInteger_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123456")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_INTEGER_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("123456"), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-from-string For input string: \"n\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_integer() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "1234"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_INTEGER; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_INTEGER, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-integer Expected data type 'integer' saw 'double' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + /** + * Double + */ + @Test + public void testDouble_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("5.432")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DOUBLE_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(5.432), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-from-string For input string: \"not valid obj value\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_double() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObjBig = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "5.432"; + String objValueStringBig = "55555555555555555555.123455"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(objValueString)); + attrObjBig = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(objValueStringBig)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DOUBLE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DOUBLE, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + arguments.clear(); + arguments.add(attrObjBig); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("5.555555555555556E19", res.getValue().getValue()); + + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-double Expected data type 'double' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + /** + * Time + */ + @Test + public void testTime_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrString2 = null; + FunctionArgumentAttributeValue attrString3 = null; + FunctionArgumentAttributeValue attrString4 = null; + FunctionArgumentAttributeValue attrStringTimeZone = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34.323")); + attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("5:12:34.323")); + attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12")); + attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34")); + attrStringTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34.323+03:00")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_TIME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + ISO8601Time resValue = (ISO8601Time)res.getValue().getValue(); + assertEquals(new ISO8601Time(5, 12, 34, 323), resValue); + + // check missing 0 in front + arguments.clear(); + arguments.add(attrString2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-from-string Invalid hour of day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // check missing seconds/msecs + arguments.clear(); + arguments.add(attrString3); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-from-string Time string too short", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // check missing just msecs + arguments.clear(); + arguments.add(attrString4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Time)res.getValue().getValue(); + assertEquals(new ISO8601Time(5, 12, 34, 0), resValue); + + // check TimeZone + arguments.clear(); + arguments.add(attrStringTimeZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Time)res.getValue().getValue(); + assertEquals(new ISO8601Time(new ISO8601TimeZone(180), 5, 12, 34, 323), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-from-string Invalid hour of day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_time() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObj2 = null; + FunctionArgumentAttributeValue attrObjTimeZone = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:12:34.323")); + attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:01:02.323")); + attrObjTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:12:34.323+03:00")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_TIME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_TIME, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("05:12:34.323", res.getValue().getValue()); + + // missing digits in string value? + arguments.clear(); + arguments.add(attrObj2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("05:01:02.323", res.getValue().getValue()); + + // include TimeZone + arguments.clear(); + arguments.add(attrObjTimeZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("05:12:34.323+03:00", res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-time Expected data type 'time' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + /** + * Date + */ + @Test + public void testDate_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrString2 = null; + FunctionArgumentAttributeValue attrString3 = null; + FunctionArgumentAttributeValue attrString4 = null; + FunctionArgumentAttributeValue attrString5 = null; + FunctionArgumentAttributeValue attrString6 = null; + FunctionArgumentAttributeValue attrString7 = null; + FunctionArgumentAttributeValue attrString8 = null; + FunctionArgumentAttributeValue attrString9 = null; + FunctionArgumentAttributeValue attrStringDateZone = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12")); + attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-2013-05-12")); + attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1232013-05-12")); + attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-1232013-05-12")); + attrString5 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("213-05-12")); + attrString6 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-5-12")); + attrString7 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-2")); + attrString8 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-32-12")); + attrString9 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-45")); + attrStringDateZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12+03:00")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DATE_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + ISO8601Date resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(2013, 5, 12), resValue); + + // check negative + arguments.clear(); + arguments.add(attrString2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(-2013, 5, 12), resValue); + + // check big + arguments.clear(); + arguments.add(attrString3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(1232013, 5, 12), resValue); + + // check big negative + arguments.clear(); + arguments.add(attrString4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(-1232013, 5, 12), resValue); + + // bad year + arguments.clear(); + arguments.add(attrString5); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid year (must be at least 4 digits)", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad month + arguments.clear(); + arguments.add(attrString6); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid month", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad day format + arguments.clear(); + arguments.add(attrString7); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // month out of range + arguments.clear(); + arguments.add(attrString8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid month", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // day out of range + arguments.clear(); + arguments.add(attrString9); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // check TimeZone + arguments.clear(); + arguments.add(attrStringDateZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(new ISO8601TimeZone(180), 2013, 5, 12), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid year", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_date() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObj2 = null; + FunctionArgumentAttributeValue attrObjDateZone = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("2013-05-12")); + attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("0001-01-01")); + attrObjDateZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("2013-05-12+03:00")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DATE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DATE, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("2013-05-12", res.getValue().getValue()); + + // missing digits in string value? + arguments.clear(); + arguments.add(attrObj2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("1-01-01", res.getValue().getValue()); + + // include DateZone + arguments.clear(); + arguments.add(attrObjDateZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("2013-05-12+03:00", res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-date Expected data type 'date' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + /** + * DateTime + */ + @Test + public void testDateTime_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrString2 = null; + FunctionArgumentAttributeValue attrString3 = null; + FunctionArgumentAttributeValue attrString4 = null; + FunctionArgumentAttributeValue attrString5 = null; + FunctionArgumentAttributeValue attrString6 = null; + FunctionArgumentAttributeValue attrString7 = null; + FunctionArgumentAttributeValue attrString8 = null; + FunctionArgumentAttributeValue attrString9 = null; + FunctionArgumentAttributeValue attrStringDateTimeZone = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12T12:14:15.323")); + attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-2013-05-12T12:14:15.323")); + attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1232013-05-12T12:14:15.323")); + attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-1232013-05-12T12:14:15.323")); + attrString5 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("213-05-12T12:14:15.323")); + attrString6 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-5-12T12:14:15.323")); + attrString7 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-2T12:14:15.323")); + attrString8 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-32-12T12:14:15.323")); + attrString9 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-45T12:14:15.323")); + attrStringDateTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12T12:14:15.323+03:00")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DATETIME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(null, new ISO8601Date(2013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue); + + // check negative + arguments.clear(); + arguments.add(attrString2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(null, new ISO8601Date(-2013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue); + + + // check big + arguments.clear(); + arguments.add(attrString3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(null, new ISO8601Date(1232013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue); + + // check big negative + arguments.clear(); + arguments.add(attrString4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(null, new ISO8601Date(-1232013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue); + + // bad year + arguments.clear(); + arguments.add(attrString5); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid year (must be at least 4 digits)", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad month + arguments.clear(); + arguments.add(attrString6); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid month", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad day format + arguments.clear(); + arguments.add(attrString7); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // month out of range + arguments.clear(); + arguments.add(attrString8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid month", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // day out of range + arguments.clear(); + arguments.add(attrString9); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // check TimeZone + arguments.clear(); + arguments.add(attrStringDateTimeZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(new ISO8601TimeZone(180), new ISO8601Date(new ISO8601TimeZone(180), 2013, 5, 12), new ISO8601Time(new ISO8601TimeZone(180),12, 14, 15, 323)), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid year", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_dateTime() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObj2 = null; + FunctionArgumentAttributeValue attrObjDateTimeZone = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("2013-05-12T12:14:15.323")); + attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("0001-01-01T12:14:15.323")); + attrObjDateTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("2013-05-12T12:14:15.323+03:00")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DATETIME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DATETIME, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("2013-05-12T12:14:15.323", res.getValue().getValue()); + + // missing digits in string value? + arguments.clear(); + arguments.add(attrObj2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("1-01-01T12:14:15.323", res.getValue().getValue()); + + // include DateTimeZone + arguments.clear(); + arguments.add(attrObjDateTimeZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("2013-05-12T12:14:15.323+03:00", res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-dateTime Expected data type 'dateTime' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + /** + * URI + */ + @Test + public void testURI_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("http://someMachine.com/subdir")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_ANYURI_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + URI resValue = (URI)res.getValue().getValue(); + try { + assertEquals(new URI("http://someMachine.com/subdir"), resValue); + } catch (URISyntaxException e) { + fail("uri generation e="+e); + } + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-from-string Illegal character in path at index 3: not valid obj value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_anyURI() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "http://aMachine.com:8080/aRef"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_ANYURI; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_ANYURI, fd.getId()); + assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-anyURI Expected data type 'anyURI' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + /** + * XPathDayTimeDuration + */ + @Test + public void testXPathDayTimeDuration_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringNeg1 = null; + FunctionArgumentAttributeValue attrStringNeg2 = null; + FunctionArgumentAttributeValue attrStringNoDay = null; + FunctionArgumentAttributeValue attrStringNoHour = null; + FunctionArgumentAttributeValue attrStringNoMin = null; + FunctionArgumentAttributeValue attrStringNoSec = null; + FunctionArgumentAttributeValue attrStringNoP = null; + FunctionArgumentAttributeValue attrStringSecondsDot = null; + FunctionArgumentAttributeValue attrStringMissingTOk = null; + FunctionArgumentAttributeValue attrStringMissingTBad = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M23S")); + attrStringNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-P3DT10H30M23S")); + attrStringNeg2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P-3DT10H30M23S")); + attrStringNoDay = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("PT10H30M23S")); + attrStringNoHour = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT30M23S")); + attrStringNoMin = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H23S")); + attrStringNoSec = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M")); + attrStringNoP = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("3DT10H30M")); + attrStringSecondsDot = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M23.456S")); + attrStringMissingTOk = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D")); + attrStringMissingTBad = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D10H30M23S")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DAYTIMEDURATION_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + XPathDayTimeDuration resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 23), resValue); + + + // negative values in front is allowed + arguments.clear(); + arguments.add(attrStringNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(-1, 3, 10, 30, 23), resValue); + + // negative in middle of string not ok + arguments.clear(); + arguments.add(attrStringNeg2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Invalid chunk \"P-3DT10H30M23S\" at position 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // omit parts that are 0 + arguments.clear(); + arguments.add(attrStringNoDay); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 0, 10, 30, 23), resValue); + + arguments.clear(); + arguments.add(attrStringNoHour); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 0, 30, 23), resValue); + + arguments.clear(); + arguments.add(attrStringNoMin); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 10, 0, 23), resValue); + + arguments.clear(); + arguments.add(attrStringNoSec); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 0), resValue); + + // P must always be present + arguments.clear(); + arguments.add(attrStringNoP); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"3DT10H30M\" at position 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // seconds may contain decimal + arguments.clear(); + arguments.add(attrStringSecondsDot); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 23.456), resValue); + + // T must be absent iff all time items are absent + arguments.clear(); + arguments.add(attrStringMissingTOk); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 0, 0, 0), resValue); + + // negative in middle of string not ok + arguments.clear(); + arguments.add(attrStringMissingTBad); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"P3D10H30M23S\" at position 6: out of order component", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"not valid obj value\" at position 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_dayTimeDuration() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "P3DT10H30M23S"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DAYTIMEDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION, fd.getId()); + assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-dayTimeDuration Expected data type 'dayTimeDuration' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + + + + /** + * XPathYearMonthDuration + */ + @Test + public void testXPathYearMonthDuration_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringNeg1 = null; + FunctionArgumentAttributeValue attrStringNeg2 = null; + FunctionArgumentAttributeValue attrStringNoYear1 = null; + FunctionArgumentAttributeValue attrStringNoYear2 = null; + FunctionArgumentAttributeValue attrStringNoMonth1 = null; + FunctionArgumentAttributeValue attrStringNoMonth2 = null; + FunctionArgumentAttributeValue attrStringNoValue = null; + FunctionArgumentAttributeValue attrStringNoP = null; + FunctionArgumentAttributeValue attrStringBigMonths = null; + FunctionArgumentAttributeValue attrStringMissingTOk = null; + FunctionArgumentAttributeValue attrStringMissingTBad = null; + FunctionArgumentAttributeValue attrStringZeroMonths = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y2M")); + attrStringNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-P1Y2M")); + attrStringNeg2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P-1Y2M")); + attrStringNoYear1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P2M")); + attrStringNoYear2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("PY2M")); + attrStringNoMonth1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y")); + attrStringNoMonth2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1YM")); + attrStringNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P")); + attrStringNoP = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1Y2M")); + attrStringBigMonths = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y12M")); + attrStringMissingTOk = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D")); + attrStringMissingTBad = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D10H30M23S")); + attrStringZeroMonths = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P0M")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_YEARMONTHDURATION_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + XPathYearMonthDuration resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1,1, 2), resValue); + + + // negative values in front is allowed + arguments.clear(); + arguments.add(attrStringNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(-1, 1, 2), resValue); + + // negative in middle of string not ok + arguments.clear(); + arguments.add(attrStringNeg2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid chunk \"P-1Y2M\" at position 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // omit parts that are 0 + arguments.clear(); + arguments.add(attrStringNoYear1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1, 0, 2), resValue); + + arguments.clear(); + arguments.add(attrStringNoYear2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid chunk \"PY2M\" at position 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + arguments.clear(); + arguments.add(attrStringNoMonth1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1, 1, 0), resValue); + + arguments.clear(); + arguments.add(attrStringNoMonth2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid chunk \"P1YM\" at position 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // No field with a value + arguments.clear(); + arguments.add(attrStringNoValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"P\": No duration components following P", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // P must always be present + arguments.clear(); + arguments.add(attrStringNoP); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"1Y2M\" at position 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // Canonical Form of output may not have more than 12 months, but input as string is ok? + arguments.clear(); + arguments.add(attrStringBigMonths); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1, 1, 12), resValue); + + // Canonical representation of 0 Months + arguments.clear(); + arguments.add(attrStringZeroMonths); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1, 0, 0), resValue); + + // T must be absent iff all time items are absent + arguments.clear(); + arguments.add(attrStringMissingTOk); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid XPath yearMonthDuraiton \"{durationSign=1years=0months=0days=3hours=0minutes=0seconds=0millis=0}\": includes days, hours, minutes, or seconds", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // negative in middle of string not ok + arguments.clear(); + arguments.add(attrStringMissingTBad); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"P3D10H30M23S\" at position 6: out of order component", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"not valid obj value\" at position 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_yearMonthDuration() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "P1Y2M"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-yearMonthDuration Expected data type 'yearMonthDuration' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + /** + * X500Principal + * + * See http://www.ietf.org/rfc/rfc2253.txt and http://www.ietf.org/rfc/rfc2251.txt + */ + @Test + public void testX500Principal_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringNoComma = null; + FunctionArgumentAttributeValue attrStringEmpty = null; + FunctionArgumentAttributeValue attrStringNoValue = null; + FunctionArgumentAttributeValue attrStringOrder = null; + FunctionArgumentAttributeValue attrStringDottedDecimalOID = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=local, ST=NJ, O=ATT, C=USA")); + attrStringNoComma = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=local ST=NJ, O=ATT, C=USA")); + attrStringEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrStringNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=, ST=NJ, O=ATT, C=USA")); + attrStringOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("L=local, ST=NJ, O=ATT, CN=Name, C=USA")); + attrStringDottedDecimalOID = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2.5.4.3=A. N. Other")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_X500NAME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_X500NAME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + X500Principal resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal("CN=Name, L=local, ST=NJ, O=ATT, C=USA"), resValue); + + // no comma between components => next attribute/value is included as part of first value + arguments.clear(); + arguments.add(attrStringNoComma); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal("CN=Name, L=local ST=NJ, O=ATT, C=USA"), resValue); + + // nothing in name (fail) + arguments.clear(); + arguments.add(attrStringEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal(""), resValue); + + // type value with no = + arguments.clear(); + arguments.add(attrStringNoValue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal("CN=Name, L=, ST=NJ, O=ATT, C=USA"), resValue); + + // different order + arguments.clear(); + arguments.add(attrStringOrder); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertNotEquals(new X500Principal("CN=Name, L=local, ST=NJ, O=ATT, C=USA"), resValue); + + // dotted-decimal name with numbers + arguments.clear(); + arguments.add(attrStringDottedDecimalOID); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal("2.5.4.3=A. N. Other"), resValue); + + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:x500Name-from-string improperly specified input name: not valid obj value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:x500Name-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_x500Name() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "CN=Name, L=local, ST=NJ, O=ATT, C=USA"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_X500NAME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_X500NAME, fd.getId()); + assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-x500Name Expected data type 'x500Name' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + /** + * RFC822Name + */ + @Test + public void testRFC822Name_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringCapsDomain = null; + FunctionArgumentAttributeValue attrStringCapsLocal = null; + FunctionArgumentAttributeValue attrStringMissingAt = null; + FunctionArgumentAttributeValue attrStringMissingLocal = null; + FunctionArgumentAttributeValue attrStringMissingDomain = null; + FunctionArgumentAttributeValue attrStringEmpty = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@Domain")); + attrStringCapsDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@DOMAIN")); + attrStringCapsLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("LOCAL@Domain")); + attrStringMissingAt = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("localDomain")); + attrStringMissingLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("@Domain")); + attrStringMissingDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@")); + attrStringEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_RFC822NAME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + RFC822Name resValue = (RFC822Name)res.getValue().getValue(); + assertEquals(new RFC822Name("local", "domain"), resValue); + + // caps domain + arguments.clear(); + arguments.add(attrStringCapsDomain); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC822Name)res.getValue().getValue(); + assertEquals(new RFC822Name("local", "domain"), resValue); + + // caps local + arguments.clear(); + arguments.add(attrStringCapsLocal); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC822Name)res.getValue().getValue(); + assertNotEquals(new RFC822Name("local", "domain"), resValue); + + // missing at + arguments.clear(); + arguments.add(attrStringMissingAt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"localDomain\": missing local part", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // missing local + arguments.clear(); + arguments.add(attrStringMissingLocal); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"@Domain\": empty parts", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // missing domain + arguments.clear(); + arguments.add(attrStringMissingDomain); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"local@\": empty parts", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty + arguments.clear(); + arguments.add(attrStringEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"\": missing local part", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"not valid obj value\": missing local part", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_rfc822Name() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "local@DOMAIN"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_RFC822NAME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME, fd.getId()); + assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("local@domain", res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-rfc822Name Expected data type 'rfc822Name' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + /** + * IPAddress + */ + @Test + public void testIPAddress_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringFull = null; + FunctionArgumentAttributeValue attrStringMissingElement = null; + FunctionArgumentAttributeValue attrStringTooManyElement = null; + FunctionArgumentAttributeValue attrStringIllegalElement = null; + FunctionArgumentAttributeValue attrStringOutOfOrder = null; + + FunctionArgumentAttributeValue attrStringMask = null; + FunctionArgumentAttributeValue attrStringMissingMaskElement = null; + FunctionArgumentAttributeValue attrStringTooManyMaskElement = null; + FunctionArgumentAttributeValue attrStringIllegalMaskElement = null; + FunctionArgumentAttributeValue attrStringMaskNoValue = null; + + FunctionArgumentAttributeValue attrStringMinusPort = null; + FunctionArgumentAttributeValue attrStringPortMinus = null; + FunctionArgumentAttributeValue attrStringPortPort = null; + FunctionArgumentAttributeValue attrStringNoPort = null; + FunctionArgumentAttributeValue attrStringBadPort = null; + FunctionArgumentAttributeValue attrStringTooManyPorts = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + + // set up for v4 address tests - this setup and the tests are repeated for V6 + short[] addrShorts= {123, 134, 156, 255 }; + short[] addrMaskShorts= {255, 255, 255, 255 }; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255")); + attrStringFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/255.255.255.255:123-456")); + attrStringMissingElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.255")); + attrStringTooManyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.255.111.222")); + attrStringIllegalElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.256.255")); + attrStringOutOfOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.256.255:123-456/255.255.255.255")); + + attrStringMask = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/255.255.255.255")); + attrStringMissingMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/123.134.255")); + attrStringTooManyMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/122.134.155.111.222")); + attrStringIllegalMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/123.134.256.255")); + attrStringMaskNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/")); + // optional mask + // "/" with no mask (fail) + + attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:-123")); + attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:123-")); + attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:1234567-432")); + attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:")); + attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:12.34")); + attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:-123-456")); + + + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_IPADDRESS_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_IPADDRESS.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + IPAddress resValue = (IPAddress)res.getValue().getValue(); + assertEquals(new IPv4Address(addrShorts, null, null), resValue); + + // fully-loaded address + arguments.clear(); + arguments.add(attrStringFull); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, addrMaskShorts, PortRange.newInstance("123-456")), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // missing element + arguments.clear(); + arguments.add(attrStringMissingElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many elements + arguments.clear(); + arguments.add(attrStringTooManyElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255.111.222\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal element + arguments.clear(); + arguments.add(attrStringIllegalElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255\": invalid octet: \"256", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // Out of order + arguments.clear(); + arguments.add(attrStringOutOfOrder); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255:123-456/255.255.255.255\": out of order components", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // simple mask + arguments.clear(); + arguments.add(attrStringMask); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, addrMaskShorts, null), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // missing mask element + arguments.clear(); + arguments.add(attrStringMissingMaskElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many mask elements + arguments.clear(); + arguments.add(attrStringTooManyMaskElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"122.134.155.111.222\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal Mask element + arguments.clear(); + arguments.add(attrStringIllegalMaskElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255\": invalid octet: \"256", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + //mask indicator without value + arguments.clear(); + arguments.add(attrStringMaskNoValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // portrange (-port, port-, port-port) + arguments.clear(); + arguments.add(attrStringMinusPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("-123")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortMinus); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("123-")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("1234567-432")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + // ":" without port + arguments.clear(); + arguments.add(attrStringNoPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.156.255:\": no portrange given after ':'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad port number + arguments.clear(); + arguments.add(attrStringBadPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid PortRange \"12.34\": invalid port number", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad port range + arguments.clear(); + arguments.add(attrStringTooManyPorts); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid PortRange \"-123-456\": too many ranges", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Unknown IPAddress type for \"not valid obj value\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // + // V6 IP Addresses + // + + // reset the variable for IPv6 tests + FunctionArgumentAttributeValue attrStringAlternateFull = null; + FunctionArgumentAttributeValue attrStringEmptyElement = null; + FunctionArgumentAttributeValue attrString2xEmptyElement = null; + FunctionArgumentAttributeValue attrStringNoStartBracket = null; + FunctionArgumentAttributeValue attrStringNoEndBracket = null; + short[] addrv6Shorts = {(short)0x2001, (short)0xdb8, (short)0x85a3, (short)0x0, (short)0x0, (short)0x8a2e, (short)0x370, (short)0x1}; + Short prefix = new Short((short) 121); + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]")); + attrStringFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/121]:123-456")); + attrStringAlternateFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]/121:123-456")); + attrStringEmptyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e:370:1]")); + attrString2xEmptyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e::1]")); + attrStringNoStartBracket = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2002:db8:85a3::8a2e::1]")); + attrStringNoEndBracket = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e::1")); + + attrStringMissingElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:1]")); + attrStringTooManyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1:123]")); + attrStringIllegalElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:mnop:85a3:0:0:8a2e:370:1]")); + attrStringOutOfOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:mnop:85a3:0:0:8a2e:370:1:123-456/121]")); + + attrStringMask = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/21]")); + attrStringIllegalMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/130]")); + attrStringMaskNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/]")); + + attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:-123")); + attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:123-")); + attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:1234567-432")); + attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:")); + attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:12.34")); + attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:-123-456")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + + // test normal + arguments.clear(); + arguments.add(attrString1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + assertEquals(new IPv6Address(addrv6Shorts, null, null), resValue); + + // fully-loaded address - "prefix" is inside the brackets (not clear if this is correct) + arguments.clear(); + arguments.add(attrStringFull); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, new Short(prefix), PortRange.newInstance("123-456")), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // Alternate way of identifying "prefix" - outside the brackets + arguments.clear(); + arguments.add(attrStringAlternateFull); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, prefix, PortRange.newInstance("123-456")), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + + // consecutive zero elements removed + arguments.clear(); + arguments.add(attrStringEmptyElement); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, prefix, null), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // consecutive zero elements removed in two locations (no-no) + arguments.clear(); + arguments.add(attrString2xEmptyElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3::8a2e::1\": multiple zero runs", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // address must have [] on it + arguments.clear(); + arguments.add(attrStringNoStartBracket); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2002:db8:85a3::8a2e::1]\": missing opening bracket", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrStringNoEndBracket); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"[2001:db8:85a3::8a2e::1\": missing closing bracket", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // missing element + arguments.clear(); + arguments.add(attrStringMissingElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3:0:0:8a2e:1\": not enough address fields", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many elements + arguments.clear(); + arguments.add(attrStringTooManyElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3:0:0:8a2e:370:1:123\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal element + arguments.clear(); + arguments.add(attrStringIllegalElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address component \"mnop\": invalid hex", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // Out of order + arguments.clear(); + arguments.add(attrStringOutOfOrder); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:mnop:85a3:0:0:8a2e:370:1:123-456\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // simple mask + arguments.clear(); + arguments.add(attrStringMask); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, prefix, null), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // illegal Mask element + arguments.clear(); + arguments.add(attrStringIllegalMaskElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid Ipv6Address string \"[2001:db8:85a3:0:0:8a2e:370:1/130]\": prefix is larger than 128", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + //mask indicator without value + arguments.clear(); + arguments.add(attrStringMaskNoValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid Ipv6Address string \"[2001:db8:85a3:0:0:8a2e:370:1/]\": prefix designation without value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // portrange (-port, port-, port-port) + arguments.clear(); + arguments.add(attrStringMinusPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("-123")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortMinus); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("123-")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("1234567-432")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + // ":" without port + arguments.clear(); + arguments.add(attrStringNoPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6 address string \"[2001:db8:85a3:0:0:8a2e:370:1]:\": no portrange given after ':'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad port number + arguments.clear(); + arguments.add(attrStringBadPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid PortRange \"12.34\": invalid port number", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad port range + arguments.clear(); + arguments.add(attrStringTooManyPorts); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid PortRange \"-123-456\": too many ranges", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + + + } + + @Test + public void testString_from_ipAddress() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObjV6 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "123.145.255.255"; + String objValueStringV6 = "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(objValueString)); + attrObjV6 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(objValueStringV6)); + + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_IPADDRESS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS, fd.getId()); + assertEquals(DataTypes.DT_IPADDRESS.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal V4 + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // test normal V6 + arguments.clear(); + arguments.add(attrObjV6); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueStringV6.toLowerCase(), res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-ipAddress Expected data type 'ipAddress' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + + + + + /** + * RFC2396DomainName + */ + @Test + public void testRFC2396DomainName_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrString2 = null; + FunctionArgumentAttributeValue attrStringMinusPort = null; + FunctionArgumentAttributeValue attrStringPortMinus = null; + FunctionArgumentAttributeValue attrStringPortPort = null; + FunctionArgumentAttributeValue attrStringNoPort = null; + FunctionArgumentAttributeValue attrStringBadPort = null; + FunctionArgumentAttributeValue attrStringTooManyPorts = null; + + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host")); + attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host")); + + attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:-123")); + attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:123-")); + attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:1234567-432")); + attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:")); + attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:12.34")); + attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:-123-456")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DNSNAME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DNSNAME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DNSNAME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + RFC2396DomainName resValue = (RFC2396DomainName)res.getValue().getValue(); + assertEquals(new RFC2396DomainName("host", null), resValue); + + arguments.clear(); + arguments.add(attrString2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC2396DomainName)res.getValue().getValue(); + assertEquals(new RFC2396DomainName("host.host", null), resValue); + + + // portrange (-port, port-, port-port) + arguments.clear(); + arguments.add(attrStringMinusPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC2396DomainName)res.getValue().getValue(); + try { + assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("-123")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortMinus); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC2396DomainName)res.getValue().getValue(); + try { + assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("123-")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC2396DomainName)res.getValue().getValue(); + try { + assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("1234567-432")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + // ":" without port + arguments.clear(); + arguments.add(attrStringNoPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"host.host:\": no port numbers", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad port number + arguments.clear(); + arguments.add(attrStringBadPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"12.34\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad port range + arguments.clear(); + arguments.add(attrStringTooManyPorts); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"-123-456\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Invalid RFC 2396 host name \"not valid obj value\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_dnsName() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "someName.com"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DNSNAME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DNSNAME, fd.getId()); + assertEquals(DataTypes.DT_DNSNAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-dnsName Expected data type 'dnsName' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java new file mode 100755 index 0000000..81fc048 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java
@@ -0,0 +1,119 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Only one function to test here. Code copy/pasted from FunctionDefinitionEqualityTest + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-equal-ignore-case + * + * @author glenngriffin + * + */ +public class FunctionDefinitionStringEqualIgnoreCaseTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + FunctionArgumentAttributeValue stringAttr1 = null; + FunctionArgumentAttributeValue stringAttr2 = null; + FunctionArgumentAttributeValue stringAttr3 = null; + FunctionArgumentAttributeValue stringAttr4 = null; + + FunctionArgumentAttributeValue intAttr1 = null; + + public FunctionDefinitionStringEqualIgnoreCaseTest() { + try { + stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC")); + stringAttr4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def")); + intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + } + + + /** + * String match even when Case is different + */ + @Test + public void testFunctionDefinitionStringEqualIgnoreCase() { + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_STRING_EQUAL_IGNORE_CASE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + + // test normal equals and non-equals + // check "abc" with "abc" + arguments.add(stringAttr1); + arguments.add(stringAttr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check "abc" with "ABC" (should be same) + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + +//TODO - null in either first or 2nd arg => NullPointerException + } + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java new file mode 100755 index 0000000..7a3b1c5 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java
@@ -0,0 +1,1477 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionStringFunctionsTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + ExpressionResult res; + + + @Test + public void testConcatenate() { + String v1 = new String("abc"); + String v2 = new String("def"); + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrV2 = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_CONCATENATE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_CONCATENATE, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + String resValue = (String)res.getValue().getValue(); + assertEquals(v1 + v2, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals(v2, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals(v1, resValue); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-concatenate Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + @Test + public void testStringStartsWith() { + String v1 = new String("abc"); + String bigger = new String("abc some string"); + String biggerNoMatch = new String(" abc some string"); + String caps = new String("AbC"); + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_STARTS_WITH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_STARTS_WITH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-starts-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-starts-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-starts-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testAnyuriStartsWith() { + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrBigString = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlankString = null; + FunctionArgumentAttributeValue attrBlankURI = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + String v1 = new String("abc"); + URI bigger = new URI("abc.some.string"); + URI biggerNoMatch = new URI("Zabc.some.string"); + String caps = new String("AbC"); + String bigString = "thisIsSomeReallyBigStringToMatch"; + + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString)); + attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_STARTS_WITH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_STARTS_WITH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + + // two blanks + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // arguments reversed + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-starts-with Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-starts-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-starts-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-starts-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + @Test + public void testStringEndsWith() { + String v1 = new String("abc"); + String bigger = new String("abc some string abc"); + String biggerNoMatch = new String(" abc some string abc "); + String caps = new String("AbC"); + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_ENDS_WITH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_ENDS_WITH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-ends-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-ends-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-ends-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testAnyuriEndsWith() { + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrBigString = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlankString = null; + FunctionArgumentAttributeValue attrBlankURI = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + String v1 = new String("abc"); + URI bigger = new URI("abc.some.stringabc"); + URI biggerNoMatch = new URI("Zabc.some.stringabcZ"); + String caps = new String("AbC"); + String bigString = "thisIsSomeReallyBigStringToMatch"; + + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString)); + attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_ENDS_WITH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_ENDS_WITH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + + // two blanks + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // arguments reversed + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-ends-with Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-ends-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-ends-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-ends-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + @Test + public void testStringSubstring() { + String bigString = new String("abc some string abc"); + + FunctionArgumentAttributeValue attrBigString = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrDouble = null; + + FunctionArgumentAttributeValue attrInteger0 = null; + FunctionArgumentAttributeValue attrInteger1 = null; + FunctionArgumentAttributeValue attrIntegerM1 = null; + FunctionArgumentAttributeValue attrInteger8 = null; + FunctionArgumentAttributeValue attrInteger19 = null; + FunctionArgumentAttributeValue attrInteger20 = null; + + + + try { + attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attrInteger1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + attrIntegerM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1)); + attrInteger8 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(8)); + attrInteger19 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(19)); + attrInteger20 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(20)); + attrDouble = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123.4)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_SUBSTRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_SUBSTRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger1); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + String resValue = (String)res.getValue().getValue(); + assertEquals("bc some", resValue); + + // edge: start + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger0); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("abc some", resValue); + + // edge: end + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger19); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals(" string abc", resValue); + + // from index to end of string + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrIntegerM1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals(" string abc", resValue); + + // first index too low + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrIntegerM1); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Start point '-1' out of range 0-19 for string='abc some string abc'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // second index too big + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger20); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring End point '20' out of range 0-19 for string='abc some string abc'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // indexes reversed + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring End point '1' less than start point 'null' for string='abc some string abc'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // indexes the same + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // blank string with indexes both 0 + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrInteger0); + arguments.add(attrInteger0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // non-string first attribute + arguments.clear(); + arguments.add(attrDouble); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected data type 'string' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-integer 2nd attr + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrDouble); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-integer 3rd attr + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrDouble); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 4 args + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null 1st arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null 2nd arg + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrNull); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + + + + + @Test + public void testAnyURISubstring() { + String bigString = new String("http://company.com:8080/this/is/some/long/uri"); + + FunctionArgumentAttributeValue attrURI = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrDouble = null; + + FunctionArgumentAttributeValue attrInteger0 = null; + FunctionArgumentAttributeValue attrInteger1 = null; + FunctionArgumentAttributeValue attrIntegerM1 = null; + FunctionArgumentAttributeValue attrInteger8 = null; + FunctionArgumentAttributeValue attrInteger45 = null; + FunctionArgumentAttributeValue attrInteger46 = null; + + + + try { + attrURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigString)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(null)); + attrInteger0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attrInteger1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + attrIntegerM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1)); + attrInteger8 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(8)); + attrInteger45 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(45)); + attrInteger46 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(46)); + attrDouble = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123.4)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_SUBSTRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_SUBSTRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger1); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + String resValue = (String)res.getValue().getValue(); + assertEquals("ttp://c", resValue); + + // edge: start + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger0); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("http://c", resValue); + + // edge: end + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger45); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("ompany.com:8080/this/is/some/long/uri", resValue); + + // from index to end of string + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrIntegerM1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("ompany.com:8080/this/is/some/long/uri", resValue); + + // first index too low + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrIntegerM1); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Start point '-1' out of range 0-45 for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // second index too big + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger46); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring End point '46' out of range 0-45 for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // indexes reversed + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring End point '1' less than start point 'null' for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // indexes the same + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // blank string with indexes both 0 + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrInteger0); + arguments.add(attrInteger0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // non-string first attribute + arguments.clear(); + arguments.add(attrDouble); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected data type 'anyURI' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-integer 2nd attr + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrDouble); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-integer 3rd attr + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrDouble); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 4 args + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null 1st arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null 2nd arg + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrNull); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + + + + + + + + + @Test + public void testStringContains() { + String v1 = new String("abc"); + String bigger = new String("abc some string abc"); + String biggerNoMatch = new String(" abc some string abc "); + String caps = new String("AbC"); + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_CONTAINS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_CONTAINS, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrBiggerNoMatch); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-contains Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-contains Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-contains Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testAnyuriContains() { + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrBigString = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlankString = null; + FunctionArgumentAttributeValue attrBlankURI = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + String v1 = new String("abc"); + URI bigger = new URI("abc.some.stringabc"); + URI biggerNoMatch = new URI("Zabc.some.stringabcZ"); + String caps = new String("AbC"); + String bigString = "thisIsSomeReallyBigStringToMatch"; + + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString)); + attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_CONTAINS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_CONTAINS, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + + // two blanks + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // arguments reversed + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-contains Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-contains Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-contains Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-contains Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java new file mode 100755 index 0000000..a09a696 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java
@@ -0,0 +1,98 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionStringNormalizeTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + @Test + public void testString_normalize_space() { + String initialString = " First and last are whitespace "; + FunctionArgumentAttributeValue attr1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(initialString)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringNormalize fd = (FunctionDefinitionStringNormalize) StdFunctions.FD_STRING_NORMALIZE_SPACE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + String resValue = (String)res.getValue().getValue(); + assertEquals(initialString.length() - 4, resValue.length()); + assertTrue(initialString.trim().equals(resValue)); + } + + + @Test + public void testString_normalize_to_lower_case() { + String initialString = " First and last are whitespace "; + FunctionArgumentAttributeValue attr1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(initialString)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringNormalize fd = (FunctionDefinitionStringNormalize) StdFunctions.FD_STRING_NORMALIZE_TO_LOWER_CASE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + String resValue = (String)res.getValue().getValue(); + assertTrue(initialString.toLowerCase().equals(resValue)); + } + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java new file mode 100755 index 0000000..9da1f13 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java
@@ -0,0 +1,165 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML2; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionURIStringConcatenateTest { + + /* + * THE FUNCTION BEING TESTED BY THIS CLASS IS DEPRECATED + * uri-string-concatenate has been deprecated in XACML 3.0 + */ + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @SuppressWarnings("deprecation") + @Test + public void testURI_string_concatenate() { + + // URI args + FunctionArgumentAttributeValue attrURI1 = null; + + + FunctionArgumentAttributeValue attrStrAbc = null; + FunctionArgumentAttributeValue attrStrSlashMno = null; + FunctionArgumentAttributeValue attrStrSlashInMiddle = null; + FunctionArgumentAttributeValue attrStrWithSpace = null; + + + try { + attrURI1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("http://someplace")); + + + attrStrAbc = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Abc")); + attrStrSlashMno = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("/Mno")); + attrStrSlashInMiddle = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("hij/pqr")); + attrStrWithSpace = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("x y z")); + + + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + // deprecation marking in the following line is correct - this function IS deprecated but still valid for XACML 3.0 + FunctionDefinitionURIStringConcatenate fd = (FunctionDefinitionURIStringConcatenate) StdFunctions.FD_URI_STRING_CONCATENATE; + + // check identity and type of the thing created + assertEquals(XACML2.ID_FUNCTION_URI_STRING_CONCATENATE, fd.getId()); + assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // add one string to uri + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrStrAbc); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(URI.class, res.getValue().getValue().getClass()); + URI resValue = (URI)res.getValue().getValue(); + assertEquals("http://someplaceAbc", resValue.toString()); + + + // add 2 strings to uri + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrStrAbc); + arguments.add(attrStrSlashMno); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(URI.class, res.getValue().getValue().getClass()); + resValue = (URI)res.getValue().getValue(); + assertEquals("http://someplaceAbc/Mno", resValue.toString()); + + // slash in middle of string + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrStrSlashInMiddle); + arguments.add(attrStrSlashMno); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(URI.class, res.getValue().getValue().getClass()); + resValue = (URI)res.getValue().getValue(); + assertEquals("http://someplacehij/pqr/Mno", resValue.toString()); + + // create bad uri + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrStrWithSpace); + arguments.add(attrStrSlashMno); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Final string 'http://someplacex y z/Mno' not URI, Illegal character in authority at index 7: http://someplacex y z/Mno", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Expected 2 or more arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg + arguments.clear(); + arguments.add(attrURI1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Expected 2 or more arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first arg not uri + arguments.clear(); + arguments.add(attrStrAbc); + arguments.add(attrURI1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Expected data type 'anyURI' saw 'string' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // 2nd arg not string + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrURI1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Expected data type 'string' saw 'anyURI' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java new file mode 100755 index 0000000..5e622ab --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java
@@ -0,0 +1,1107 @@ +package com.att.research.xacmlatt.pdp.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdRequest; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.XPathExpressionWrapper; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdEvaluationContext; +import com.att.research.xacmlatt.pdp.std.StdFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * @author glenngriffin + * + */ +public class FunctionDefinitionXPathTest { + + // + // Strings for the Request contents + // + + String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + + "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" + + " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"" + + " ReturnPolicyIdList=\"false\"" + + " CombinedDecision=\"false\"" + + " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"" + + " xmlns:md=\"http://www.medico.com/schemas/record\"" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + + " <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>" + + " </Attribute>" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>" + + " </Attribute>" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>" + + " </Attribute>" + + "</Attributes>"; + + String reqStrResourceStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">"; + + String reqStrContentMdRecord = + " <Content>" + + "<md:record>" + + "<md:hospital_info>" + + "<md:name>ABC Hospital</md:name>" + + "<md:department>Surgery</md:department>" + + "</md:hospital_info>" + + "<md:patient_info>" + + "<md:name>Bart Simpson</md:name>" + + "<md:age>60</md:age>" + + "<md:sex>male</md:sex>" + + "<md:health_insurance>123456</md:health_insurance>" + + "</md:patient_info>" + + "<md:diagnosis_info>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Gastric Cancer</md:item>" + + "<md:item type=\"secondary\">Hyper tension</md:item>" + + "</md:diagnosis>" + + "<md:pathological_diagnosis>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" + + "</md:diagnosis>" + + "<md:date>2000-10-05</md:date>" + + "<md:malignancy type=\"yes\"/>" + + "</md:pathological_diagnosis>" + + "</md:diagnosis_info> " + + " </md:record>" + + "</Content>"; + String reqStrMalformedContent = + " <Content>" + + "<md:record>" + + "<md:hospital_info>" + + "<md:name>ABC Hospital</md:name>" + + "<md:malignancy type=\"yes\"/>" + + "</Content>"; + String reqStrResourceEnd = " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>" + + " </Attribute>" + + "</Attributes> "; + String reqStrActionStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">"; + + String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">" + + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>" + + "</Attribute>" + + "</Attributes> "; + String reqStrEnvironmentStartEnd = " <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />"; + String reqStrMainEnd = " </Request>"; + + + // combined strings for convenience + String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart; + String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd; + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + + // Name Spaces used in the XML as part of these examples (copied from the Conformance tests) - needed for compiling XPaths + NamespaceContext nameSpaceContext = new NamespaceContext() { + @Override + public Iterator<?> getPrefixes(String arg0) { return null;} + + @Override + public String getPrefix(String arg0) {return null;} + + @Override + public String getNamespaceURI(String arg0) { + if("md".equals(arg0)) { + return "http://www.medico.com/schemas/record"; + } else if ("xacml-context".equals(arg0)) { + return "urn:oasis:names:tc:xacml:3.0:context:schema:os"; + } else if ("xsi".equals(arg0)) { + return "http://www.w3.org/2001/XMLSchema-instance"; + } + return null; + } + }; + + + + // + // XPath Function Attributes available for use in tests (representing appropriate fragment of Policy) + // + + FunctionArgumentAttributeValue attrXnull = null; + FunctionArgumentAttributeValue attrXEmpty = null; + FunctionArgumentAttributeValue attrXNoCategory = null; + FunctionArgumentAttributeValue attrXNoValue = null; + FunctionArgumentAttributeValue attrXSlashSlashMdRecord = null; + FunctionArgumentAttributeValue attrXSlashSlashStar = null; + FunctionArgumentAttributeValue attrXSlashSlashMdName = null; + FunctionArgumentAttributeValue attrXSlashSlashMdMalignancy = null; + FunctionArgumentAttributeValue attrXNotInRequest = null; + FunctionArgumentAttributeValue attrXSlashSlashMdRecordSlashStar = null; + FunctionArgumentAttributeValue attrXMdPatientInfo = null; + + FunctionArgumentAttributeValue attrBadType = null; + + // String version of attrs for use in Deprecated functions + FunctionArgumentAttributeValue attrStrnull = null; + FunctionArgumentAttributeValue attrStrEmpty = null; + FunctionArgumentAttributeValue attrStrNoCategory = null; + FunctionArgumentAttributeValue attrStrNoValue = null; + FunctionArgumentAttributeValue attrStrSlashSlashMdRecord = null; + FunctionArgumentAttributeValue attrStrSlashSlashStar = null; + FunctionArgumentAttributeValue attrStrSlashSlashMdName = null; + FunctionArgumentAttributeValue attrStrSlashSlashMdMalignancy = null; + FunctionArgumentAttributeValue attrStrNotInRequest = null; + FunctionArgumentAttributeValue attrStrSlashSlashMdRecordSlashStar = null; + FunctionArgumentAttributeValue attrStrMdPatientInfo = null; + + + // + // REQUEST objects available for use in tests + // + Request requestEmpty = new StdRequest(StdStatus.STATUS_OK); + Request requestMdRecord = null; + Request requestDoubleResources = null; + Request requestResourceActionContent = null; + Request requestContentInAction = null; + + + + + /** + * Set up all variables in one place because it is complicated (lots of steps needed for each attribute) + */ + public FunctionDefinitionXPathTest() { + try { + XPathFactory xPathFactory = XPathFactory.newInstance(); + XPath xpath = xPathFactory.newXPath(); + xpath.setNamespaceContext(nameSpaceContext); + + // Create XPaths to use in expressions + XPathExpressionWrapper xEmpty = new XPathExpressionWrapper(""); + XPathExpressionWrapper xSlashSlashMdRecord = new XPathExpressionWrapper(xpath.compile("//md:record")); + XPathExpressionWrapper xSlashSlashStar = new XPathExpressionWrapper(xpath.compile("//*")); + XPathExpressionWrapper xSlashSlashMdName = new XPathExpressionWrapper(xpath.compile("//md:name")); + XPathExpressionWrapper xSlashSlashMdMalignancy = new XPathExpressionWrapper(xpath.compile("//md:malignancy")); + XPathExpressionWrapper xNotInRequest = new XPathExpressionWrapper(xpath.compile("value_Not_in_request")); + XPathExpressionWrapper xSlashSlashMdRecordSlashStar = new XPathExpressionWrapper(xpath.compile("//md:record/*")); + XPathExpressionWrapper xMdPatientInfo = new XPathExpressionWrapper(xpath.compile("md:patient_info")); + + + + // create Function Attributes out of the XPathExpressions + attrXnull = new FunctionArgumentAttributeValue(null); + attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xEmpty)); + attrXNoCategory = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecord)); + attrXNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xEmpty, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXSlashSlashMdRecord = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecord, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXSlashSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashStar, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXSlashSlashMdName = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdName, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXSlashSlashMdMalignancy = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdMalignancy, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xNotInRequest, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + + attrXSlashSlashMdRecordSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecordSlashStar, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXMdPatientInfo = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xMdPatientInfo, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + + + // Deprecated versions of args + attrStrnull = new FunctionArgumentAttributeValue(null); + attrStrEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrStrNoCategory = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record")); + attrStrNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrSlashSlashMdRecord = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrSlashSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//*", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrSlashSlashMdName = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:name", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrSlashSlashMdMalignancy = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:malignancy", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("value_Not_in_request", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + + attrStrSlashSlashMdRecordSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record/*", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrMdPatientInfo = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("md:patient_info", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + + + + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("some string")); + + + + // Request objects + // to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it. + + // single Content in the Resources section (normal valid request) + String reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceAllEnd; + File tFile = File.createTempFile("functionJunit", "request"); + BufferedWriter bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestMdRecord = DOMRequest.load(tFile); + tFile.delete(); + + // Resources included twice + reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecord +reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestDoubleResources = DOMRequest.load(tFile); + tFile.delete(); + + + // content included in both Resource and Action - ok + reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecord + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestResourceActionContent = DOMRequest.load(tFile); + tFile.delete(); + + // Content included only in Action - missing content produces non-error result according to spec + reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecord + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestContentInAction = DOMRequest.load(tFile); + tFile.delete(); + + + + // Test that Bad XML is caught + @SuppressWarnings("unused") + Request requestContentMisplaced = null; + @SuppressWarnings("unused") + Request requestMalformedContent = null; + @SuppressWarnings("unused") + Request requestDoubleContent = null; + + + // Content included twice - error + reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrContentMdRecord +reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestDoubleContent = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + // Bad XML - Content not under a Category + reqString = reqStrMainStart + reqStrContentMdRecord + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestContentMisplaced = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + // Bad XML - Content is not valid XML + reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestMalformedContent = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + } catch (Exception e) { + fail("Constructor initializing variables, e="+ e + " cause="+e.getCause()); + } + + } + + + + + + + + + @Test + public void testXpath_node_count() { + + + + FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_COUNT; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_COUNT, fd.getId()); + assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // match all elements within context + arguments.clear(); + arguments.add(attrXSlashSlashStar); + ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("18"), resValue); + + // match exactly 1 element + arguments.clear(); + arguments.add(attrXSlashSlashMdMalignancy); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("1"), resValue); + + // match a few but not all + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + + // verify variables using in other tests: count nodes immediately under md:record + arguments.clear(); + arguments.add(attrXSlashSlashMdRecordSlashStar); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("3"), resValue); + + // verify variables using in other tests: count number of records containing patient_info + arguments.clear(); + arguments.add(attrXMdPatientInfo); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("1"), resValue); + + // verify variables using in other tests: count number of records containing md:name + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + // verify variables using in other tests: count number of records containing md:malignancy + arguments.clear(); + arguments.add(attrXSlashSlashMdMalignancy); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("1"), resValue); + + + + + // match no element + arguments.clear(); + arguments.add(attrXNotInRequest); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("0"), resValue); + + // Resources included twice + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // Content in both Resource and Action categories (ok) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + // Content only in Action category (missing in Resources -> 0 according to spec) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("0"), resValue); + + + + +//TODO - any other tests???? + + // null Evaluation Context + arguments.clear(); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Request + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null Request in EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null attribute + arguments.clear(); + arguments.add(attrXnull); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null attribute at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no value + arguments.clear(); + arguments.add(attrXNoValue); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no category + arguments.clear(); + arguments.add(attrXNoCategory); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null Category at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // too many args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Expected 1 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null args + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testXpath_node_equal() { + + + FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal success - exactly the same set + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - second list is subset of first list + arguments.clear(); + arguments.add(attrXSlashSlashMdRecordSlashStar); + arguments.add(attrXMdPatientInfo); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - first list is subset of second list + arguments.clear(); + arguments.add(attrXMdPatientInfo); + arguments.add(attrXSlashSlashMdRecordSlashStar); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - second list contains children of first list + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // success - first list contains children of second list + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + + // two non-overlapping sets + arguments.clear(); + arguments.add(attrXSlashSlashMdMalignancy); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first list contains nothing + arguments.clear(); + arguments.add(attrXNotInRequest); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // second list contains nothing + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXNotInRequest); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + +//TODO + //????? + ///??????? add real tests + ////// + + + // Resources included twice + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + // Content in both Resource and Action categories (ok) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // Content only in Action category (missing in Resources -> 0 according to spec) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // null Evaluation Context + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Request + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null Request in EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null attribute + arguments.clear(); + arguments.add(attrXnull); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null attribute at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXnull); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null attribute at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no value + arguments.clear(); + arguments.add(attrXNoValue); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXNoValue); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no category + arguments.clear(); + arguments.add(attrXNoCategory); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null Category at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXNoCategory); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected data type 'xpathExpression' saw 'string' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null argument at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(null); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + @Test + public void testXpath_node_match() { + + + FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_MATCH, fd.getId()); + assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal success - exactly the same set + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - second list is subset of first list + arguments.clear(); + arguments.add(attrXSlashSlashMdRecordSlashStar); + arguments.add(attrXMdPatientInfo); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - first list is subset of second list + arguments.clear(); + arguments.add(attrXMdPatientInfo); + arguments.add(attrXSlashSlashMdRecordSlashStar); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - second list contains children of first list + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - first list contains children of second list + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + + // two non-overlapping sets + arguments.clear(); + arguments.add(attrXSlashSlashMdMalignancy); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first list contains nothing + arguments.clear(); + arguments.add(attrXNotInRequest); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // second list contains nothing + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXNotInRequest); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + +//TODO + //????? + ///??????? add real tests + ////// + + + // Resources included twice + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // Content in both Resource and Action categories (ok) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // Content only in Action category (missing in Resources -> 0 according to spec) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // null Evaluation Context + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Request + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null Request in EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null attribute + arguments.clear(); + arguments.add(attrXnull); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null attribute at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXnull); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null attribute at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no value + arguments.clear(); + arguments.add(attrXNoValue); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXNoValue); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no category + arguments.clear(); + arguments.add(attrXNoCategory); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null Category at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXNoCategory); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected data type 'xpathExpression' saw 'string' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null argument at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(null); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + } + + + + // + // DEPRECATED versions that use String arguments rather than XPATHEXPRESSIONs + // are NOT supported due to ambiguity in the semantics between 2.0 (<Request> is root and has only one <Content> in resources) + // and 3.0 (<Content> is root and there are multiple <Content> sections in any category) + // + + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java new file mode 100755 index 0000000..c5c40e3 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java
@@ -0,0 +1,4165 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONStructureException; + +/** + * Test JSON Request convert to object - Category sub-component. Does not include "Default" Categories (Subject, Action, Resource, Environment). + * Basic existance/absence of Category is tested in RequestMainTest. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOTE: + * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects + * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element. + * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object + * and we compare the resulting String to our expected String. + * This has two possible sources of error: + * - toString might not include some sub-component, and + * - the initial verification of the resulting string is done by hand and may have been incorrect. + * + * @author glenngriffin + * + */ +public class RequestCategoryTest { + + // The request object output from each test conversion from JSON string + Request request; + + + /* + * Request that uses all fields with both single and multiple entries + */ + String allFieldsRequest = + "{\"Request\": {" + + "\"ReturnPolicyIdList\" : true ," + + "\"CombinedDecision\" : true ," + + "\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," + + "\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar1\"]" + + "}]" + + "}," + + + "\"Category\": [" + + "{ " + + "\"CategoryId\": \"custom-category\", " + + "\"Id\" : \"customId\", " + + "\"Attribute\" : [" + + "{" + + "\"AttributeId\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}, " + + "{" + + "\"AttributeId\" : \"document-url\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : \"http://somewhere.over.the.com/rainbow\" " + + "}, " + + "{" + + "\"AttributeId\" : \"page-list\", " + + "\"Value\" : [1, 2, 3, 4.5, 3, 2, 1] " + + "} " + + "]" + + "}, " + + "{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "], " + + + "\"AccessSubject\":{ " + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"," + + "\"Attribute\" : []" + + "}, " + + + "\"Resource\" : {" + + "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" + + "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+ + "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" + + + + "} " + + + + "}}"; + + /* + * The following example comes directly from the JSON Profile Spec + */ + String exampleFromSpec = "{ " + + "\"Request\" : { " + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "\"Action\" : { " + + "\"Attribute\": " + + "{ " + + "\"Id\" : \"action-id\", " + + "\"Value\" : \"http://www.xacml.eu/buy\", " + + "\"DataType\" : \"anyURI\" " + + "} " + + "}, " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"book-title\", " + + "\"Value\" : \"Learn German in 90 days\" " + + "}, " + + "{ " + + "\"Id\" : \"currency\", " + + "\"Value\" : \"SEK\" " + + "}, " + + "{ " + + "\"Id\" : \"price\", " + + "\"Value\" : 123.34 " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + /* + * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples). + * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding. + */ + String xPathExampleFromSpec = "{ " + + "\"Request\" : { " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : { " + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " + + "\"Namespaces\" : [{ " + + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}, " + + "{ " + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "} " + + "], " + + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " + + "} " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Top-level of Category + @Test + public void testCategoryTopLevel() { + + // empty Category + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Missing value + try { + request = JSONRequest.load("{\"Request\" : {\"Category\" }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\" : }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category without CategoryId + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{}] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with CategoryId value missing or ="" + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\"] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"\" ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // CategoryId wrong type + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : true } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : 123 } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : \"customId\" } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category},xmlId=customId}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Id - wrong type + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : true } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : 123 } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category without Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\" } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category with standard CategoryId + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with extra unknown field + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", unknown } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"unknown\" : 123 } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with multiple sub-Category objects using same CategoryId + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"category1\" }, {\"CategoryId\" : \"category1\" } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=category1}}{super={category=category1}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + // Tests related to Attributes + @Test + public void testCategoryAttributes() { + + // Category with Attribute but none given ("Attribute" : [] ) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with empty attribute (missing both AttributeId and Id) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with AttributeId and no Value + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : \"document-id\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute missing AttributeId but with Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : \"document-id\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute missing AttributeId but with Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute including both AttributeId and Id with same value + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : \"document-id\", " + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute missing both AttributeId and Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute AttributeId not string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : true, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : 123, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute Id not string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : true, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : 123, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute with DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with DataType not string (e.g. "DataType" : 55.5 ) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : true, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with unknown DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"no such data type\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : 321, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with multiple value array + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : [\"P3D\", \"P2DT12H34M\", \"PT15M\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=3hours=0minutes=0seconds=0millis=0},factionalSeconds=0.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=2hours=12minutes=34seconds=0millis=0},factionalSeconds=0.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=0hours=0minutes=15seconds=0millis=0},factionalSeconds=0.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute multiple value with null in array + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : [\"P3D\", , \"P15M\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with array value with no values ("Attribute": [ {"AttributeId" :"a", Value:[] } ] } ) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : [ ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with no DataType and array with no values + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Issuer + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Issuer\" : \"University Press\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],issuer=University Press,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Issuer not string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Issuer\" : true, " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Issuer\" : 4.56, " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with includeInResult=true + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123, " + + "\"IncludeInResult\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=true}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with includeInResult = false + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123, " + + "\"IncludeInResult\" : false " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with includeInResult not boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123, " + + "\"IncludeInResult\" : \"abc\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123, " + + "\"IncludeInResult\" : 123.45 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + // Tests related to DataTypes within Attributes + @Test + public void testCategoryAttributesDataTypesSimple() { + + // Category Attribute using full Identifier for each data type + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : 123.34 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : \"12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : \"2002-10-10\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : \"2002-10-10T12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : \"P23DT7H12M54S\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : \"P165Y8M\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,2,35,-13,-29,-58,54,23,70,22,-58,-10,115,-29,-58,38,-10,-10,-78,6,-106,67,-46,38,38,-77,19,3,18,35,-29,-58,23,87,70,-122,-9]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : \"someone.else@A.COMPANY.com\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.COMPANY.com}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : \"121.221.43.58:12345\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute shorthand notation for each data type + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"string\", " + + "\"Value\" : \"abc\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"boolean\", " + + "\"Value\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"double\", " + + "\"Value\" : 123.34 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"time\", " + + "\"Value\" : \"12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"date\", " + + "\"Value\" : \"2002-10-10\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dateTime\", " + + "\"Value\" : \"2002-10-10T12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : \"P23DT7H12M54S\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"yearMonthDuration\", " + + "\"Value\" : \"P165Y8M\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"hexBinary\", " + + "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"base64Binary\", " + + "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,2,35,-13,-29,-58,54,23,70,22,-58,-10,115,-29,-58,38,-10,-10,-78,6,-106,67,-46,38,38,-77,19,3,18,35,-29,-58,23,87,70,-122,-9]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"rfc822Name\", " + + "\"Value\" : \"someone.else@A.COMPANY.com\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.COMPANY.com}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"x500Name\", " + + "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"ipAddress\", " + + "\"Value\" : \"121.221.43.58:12345\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dnsName\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // infer data type - only integer, boolean and double are distinguishable from strings; everything else is treated as a string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"abc\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123.34 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"2002-10-10\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"2002-10-10T12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"P23DT7H12M54S\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"P165Y8M\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"someone.else@A.COMPANY.com\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.COMPANY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"121.221.43.58:12345\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + // gets inferred to a String containing the whole structure under Value as a String + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value={XPathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource, Namespaces=[{Namespace=urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}, {Prefix=md, Namespace=urn:example:med:schemas:record}], XPath=md:record/md:patient/md:patientDoB}}],includeInResults=false}]}}]}", request.toString()); + + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + @Test + public void testCategoryAttributesDataTypesNotMatchValue() { + + // Category Attribute with DataType not matching value type (JSON type derived from syntax) + // AUTO-CONVERSION from Boolean to String! + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : 123.34 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : \"abc\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : 123.45 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : \"123\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : true " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : 123.45 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : \"123.34\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : true " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // allow integer to auto-convert to double when DataType is given + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // special JavaScript values not allowed except for -0 (inappropriate requirement in spec - check it anyway) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : \"NaN\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : \"INF\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : \"-INF\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // JavaScript 0 and -0 are ok + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : 0 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : -0 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // All other data types are checked when we convert internally, so value must be syntactically correct + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Base64 convert does not throw an exception if the contents are not Base64, so cannot test for this. + // Any problem with the data will have to be discovered later when the data is used. + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Cannot test XPathExpressions here. The XPathExpression gets converted into a simple String value within the XPathExpression object, + // but it is not evaluated or compiled at that time. Therefore we do not know whether or not the value is valid until it is used in a computation. + + } + + + @Test + public void testArrayDataTypes() { + + // array of size 0 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute value array DataType given (repeat for all data types) + // Category Attribute using full Identifier for each data type + // Category Attribute shorthand notation for each data type + // Also tests for mixes of different JSON types (trying incorrect strings for XACML data types whenever possible) + // string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"string\", " + + "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT to DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [\"abc\", true, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [\"abc\",123, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [\"abc\", 34.34, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=34.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : [true, true, false, true, false ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"boolean\", " + + "\"Value\" : [true, true, false, true, false ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : [true, \"abc\", false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : [true, 123, false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : [true, 12.34, false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // integer + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : [123, 456, 765, 234] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : [123, 456, 765, 234] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : [123, \"abc\", 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : [123, true, 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : [123, 34.56, 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // double + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"double\", " + + "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // special case - auto-convert integer to boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : [ 123.34, 111122, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=111122.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : [ 123.34, true, 3445.455, 4543,543 ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : [ 123.34, \"abb\", 3445.455, 4543,543 ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // time + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"time\", " + + "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", \"not a time\", \"12:00:00Z\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", true, \"12:00:00Z\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", 123, \"12:00:00Z\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", 12.34, \"12:00:00Z\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // date + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"date\", " + + "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",\"not a date\",\"2002-10-10\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",true,\"2002-10-10\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",123,\"2002-10-10\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",123.45,\"2002-10-10\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dateTime + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"not a dateTime\",\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",true,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",123,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",12.34,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dayTimeDuration + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",\"not a duration\",\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",true,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",123,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",11.22,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // yearMonth duration + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",\"not a duration\",\"P165Y8M\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",true,\"P165Y8M\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",123,\"P165Y8M\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",11.22,\"P165Y8M\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // anyURI + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : [ \"aValue\",true,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : [ \"aValue\",123,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : [ \"aValue\",11.111,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=11.111}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // hexBinary + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",true,\"012AEEF\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",123,\"012AEEF\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",11.44,\"012AEEF\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // base64Binary + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,18,35,-29,-58,23,87,70,-122,-9]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"base64Binary\", " + + "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,18,35,-29,-58,23,87,70,-122,-9]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : [ \"aG9y\",true,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-74,-69,-98]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : [ \"aG9y\",1123,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-41,93,-73]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : [ \"aG9y\",11.22,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-41,93,-74]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // RFC822 name + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=sne.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=one.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.CONY.com}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=sne.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=one.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.CONY.com}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"not a dns\",\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",true,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",111,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",11.22,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // x500 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"non-x500 string\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", true, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 1111, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 11.22, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // ipAddress + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"ipAddress\", " + + "\"Value\" : [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"121.221.43.58:12345\",\"not an ip address\",\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"121.221.43.58:12345\",true,\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"121.221.43.58:12345\",1111,\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"121.221.43.58:12345\",11.22,\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dnsName + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dnsName\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : [ \"aValue\", true, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=true}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // xPathExpression + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "\"simpleString\"," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "true," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "123," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "12.34," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + } + + + + + + + + @Test + public void testArrayNoDataTypes() { + + // array of size 0 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute value array DataType Not given (repeat for all data types) + // Also tests for mixes of different JSON types (trying incorrect strings for XACML data types whenever possible) + // string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT to DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"abc\", true, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"abc\",123, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"abc\", 34.34, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=34.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [true, true, false, true, false ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [true, \"abc\", false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [true, 123, false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [true, 12.34, false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // integer + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [123, 456, 765, 234] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [123, \"abc\", 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [123, true, 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // double + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // special case - auto-convert integer to boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ 123.34, 111122, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=111122.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ 123.34, true, 3445.455, 4543,543 ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ 123.34, \"abb\", 3445.455, 4543,543 ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // time - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"12:00:00Z\", true, \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"12:00:00Z\", 123, \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"12:00:00Z\", 12.34, \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // date - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"2002-10-10\",true,\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"2002-10-10\",123,\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"2002-10-10\",123.45,\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123.45}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dateTime - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",true,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",123,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",12.34,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dayTimeDuration - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + //AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P23DT7H12M54S\",true,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P23DT7H12M54S\",123,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P23DT7H12M54S\",11.22,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // yearMonth duration - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P165Y8M\",true,\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P165Y8M\",123,\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P165Y8M\",11.22,\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // anyURI - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",true,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",123,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",11.111,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // hexBinary - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",true,\"012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",123,\"012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",11.44,\"012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.44}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // base64Binary - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbj0iMS4xIj48YXV0aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aG9y\",true,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aG9y\",1123,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aG9y\",11.22,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // RFC822 name - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=one.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",true,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",111,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",11.22,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // x500 - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", true, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 1111, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 11.22, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // ipAddress - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"121.221.43.58:12345\",true,\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"121.221.43.58:12345\",1111,\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"121.221.43.58:12345\",11.22,\"121.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dnsName - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", true, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // xPathExpression - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", true, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + + @Test + public void testXPathExpression() { + // Category Attribute with XPathExpression including XPathCategory and XPath + // Category Attribute with XPathExpression with Namespaces with/without Prefix + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{ "+ + "\"Prefix\" : \"lab\", " + + "\"Namespace\" : \"http://somewhere/uri.html\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{lab,http://somewhere/uri.html}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression missing XPathCategory + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"Namespaces\" : [{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression missing XPath + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}] "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression without Namespaces + // (path does not contain namespace references) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"XPath\" : \"record/patient/patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=record/patient/patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression with 0 Namespaces + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute with XPathExpression with Namespaces without mandatory Namespace + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [{ "+ + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression with Namespaces with 2 namespaces using same prefix + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [{ "+ + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression without Namespaces which are used within the XPathExpression (NOTE: Error is not syntactic and is not found by converter) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression containing simple value (must be object) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : \"simple Value\"" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Namespaces containing simple value (must be object) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [ \"simpleValue\"," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute with Namespaces non-string Namespace + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [ {" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : 123 " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Namespaces non-string prefix + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [ {" + + "\"Prefix\" : 123, " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Namespaces non-string XPathCategory + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : 123," + + "\"Namespaces\" : [ {" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Namespaces non-string XPath + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [ {" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : 123 "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + @Test + public void testContent() { + + // Category with Content in XML, escaped properly + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"" + + "} ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]},contentRoot=[catalog: null]}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Content in XML, double quotes and back-slashes NOT escaped properly? + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"" + + "} ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Content in Base64 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" + + "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+ + "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" + + "} ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]},contentRoot=[catalog: null]}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Bad Content in Base64 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"PD94bWwgdmV\"" + + "} ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + + @Test + public void testDuplicates() { + // duplicate of same element within Category array is ok + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] }, " + + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] } " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // duplicate Attribute + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [" + + "{\"CategoryId\" : \"custom-category\"," + + " \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}], " + + " \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // dup id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] } " + + "] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // dup DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] } " + + "] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // dup Value + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "\"Value\" : \"abc\" " + + "}] } " + + "] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // duplicate Content + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{" + + "\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\" , " + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"" + + "} ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + +//TODO - Shorthand for CategoryId ???? + + +}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java new file mode 100755 index 0000000..85c3bed --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java
@@ -0,0 +1,349 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.RequestAttributes; +import com.att.research.xacml.api.RequestReference; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONStructureException; +/** + * Test JSON Request convert to object - Conformance tests + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOTE: + * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects + * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element. + * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object + * and we compare the resulting String to our expected String. + * This has two possible sources of error: + * - toString might not include some sub-component, and + * - the initial verification of the resulting string is done by hand and may have been incorrect. + * + * @author glenngriffin + * + */ +public class RequestConformanceTest { + + // where to find the conformance test XML files + private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4"; + + // The request object output from each test conversion from JSON string + Request request; + + + + + + // test just one of each top-level element. + // For simple elements also test for incorrect type + @Test + public void testConformanceRequests() { + + List<File> filesInDirectory = null; + + File conformanceDirectory = null; + + File currentFile = null; + + try { + conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH); + filesInDirectory = getRequestsInDirectory(conformanceDirectory); + } catch (Exception e) { + fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e); + } + + // run through each XML file + // - load the file from XML into an internal Request object + // - generate the JSON representation of that Request object + // - load that JSON representation into a new Request object + // - compare the 2 Request objects + Request xmlRequest = null; + Request jsonRequest = null; + try { + for (File f : filesInDirectory) { + currentFile = f; + +//// This is a simple way to select just one file for debugging - comment out when not being used +//if ( ! f.getName().equals("IIA023Request.xml")) { continue; } + +// during debugging it is helpful to know what file it is starting to work on +// System.out.println("starting file="+currentFile.getName()); + + try { + // load XML into a Request object + xmlRequest = DOMRequest.load(f); + xmlRequest.getStatus(); + } catch (Exception e) { + // if XML does not load, just note it and continue with next file + System.out.println("XML file did not load: '" + f.getName() + " e=" + e); + continue; + } + +//System.out.println(JSONRequest.toString(xmlRequest, false)); + + // generate JSON from the Request + String jsonString = JSONRequest.toString(xmlRequest, false); + + +// single-value elements +//jsonString = "{\"Request\":{\"Category\":[{\"CategoryId\":\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\",\"Attribute\":[" +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"Julius Hibbert\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":\"true\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":123,\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-string\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"true\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-boolean\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"56\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-integer\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"27.5\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-double\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"2002-03-22\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#date\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-date\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"2002-03-22T08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#dateTime\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dateTime\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"P50DT5H4M3S\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#dayTimeDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dayTimeDuration\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P5Y3M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0bf7a9876cde\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c3VyZS4=\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"j_hibbert@medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Julius Hibbert, O=Medi Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"122.45.38.245/255.255.255.64:8080-8080\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"some.host.name:147-874\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"}" +// + "]}," +// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Attribute\":[" +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:record\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/BartSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"}" +// + "]}," +// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\",\"Attribute\":[" +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"read\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"}" +// + "]}," +// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\",\"Attribute\":[" +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"}" +// + "]}],\"ReturnPolicyIdList\":false,\"CombinedDecision\":false}}"; + + + + + + +// array attributes WITH explicit data types + + + + +// String for testing Arrays of Attribute values +//jsonString = "{\"Request\":{\"Category\":[{\"CategoryId\":\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\",\"Attribute\":[" +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"test string\",\"Julius Hibbert\",\"Julius Hibbert as string\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[true, false],\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-boolean\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[56, 12],\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-integer\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[27.12, 12112.344],\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-double\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"2002-03-22\",\"1256-11-11\"],\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-date\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"2002-03-22T08:23:47-05:00\",\"1056-11-05T19:08:12-14:30\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#dateTime\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dateTime\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"P50DT5H4M3S\",\"P12DT148H18M21S\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#dayTimeDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dayTimeDuration\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P5Y3M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P28Y7M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0bf7a9876cde\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0fb8\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c3VyZS4=\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"YXN1cmUu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"j_hibbert@medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c_clown@nose_medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Julius Hibbert, O=Medi Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Crusty Clown, O=Red Nose Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"122.45.38.245/255.255.255.64:8080-8080\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"35.123.111.56/255.64.32.255:9999-9999\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"some.host.name:147-874\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"a.different.host:-45\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"}" +// + "]}," +// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Attribute\":[" +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:record\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:diagnosis_info\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/BartSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/HomerSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"}" +// + "]," +// + "\"Content\":\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><md:records xmlns:md=\\\"http://www.medico.com/schemas/record\\\">\\r\\n \\t<md:record>\\r\\n \\t<md:patient_info>\\r\\n \\t<md:name>Bart Simpson</md:name>\\r\\n \\t<md:age>60</md:age>\\r\\n \\t<md:sex>male</md:sex>\\r\\n \\t<md:health_insurance>123456</md:health_insurance>\\r\\n \\t</md:patient_info>\\r\\n \\t<md:diagnosis_info>\\r\\n \\t<md:diagnosis>\\r\\n \\t<md:item type=\\\"primary\\\">Gastric Cancer</md:item>\\r\\n \\t<md:item type=\\\"secondary\\\">Hyper tension</md:item>\\r\\n \\t</md:diagnosis>\\r\\n \\t<md:pathological_diagnosis>\\r\\n \\t<md:diagnosis>\\r\\n \\t<md:item type=\\\"primary\\\">Well differentiated adeno carcinoma</md:item>\\r\\n \\t</md:diagnosis>\\r\\n \\t<md:date>2000-10-05</md:date>\\r\\n \\t<md:malignancy type=\\\"yes\\\"/>\\r\\n \\t</md:pathological_diagnosis>\\r\\n \\t</md:diagnosis_info> \\r\\n \\t</md:record>\\r\\n \\t<md:record>\\r\\n \\t<md:patient_info>\\r\\n \\t<md:name>Homer Simpson</md:name>\\r\\n \\t<md:age>80</md:age>\\r\\n \\t<md:sex>male</md:sex>\\r\\n \\t<md:health_insurance>123456</md:health_insurance>\\r\\n \\t</md:patient_info>\\r\\n \\t<md:diagnosis_info>\\r\\n \\t<md:diagnosis>\\r\\n \\t<md:item type=\\\"primary\\\">Gastric Cancer</md:item>\\r\\n \\t<md:item type=\\\"secondary\\\">Hyper tension</md:item>\\r\\n \\t</md:diagnosis>\\r\\n \\t<md:pathological_diagnosis>\\r\\n \\t<md:diagnosis>\\r\\n \\t<md:item type=\\\"primary\\\">Well differentiated adeno carcinoma</md:item>\\r\\n \\t</md:diagnosis>\\r\\n \\t<md:date>2000-10-05</md:date>\\r\\n \\t<md:malignancy type=\\\"yes\\\"/>\\r\\n \\t</md:pathological_diagnosis>\\r\\n \\t</md:diagnosis_info> \\r\\n \\t</md:record>\\r\\n\\t </md:records>\"}," +// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\",\"Attribute\":[" +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"read\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"write\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"}" +// + "]}," +// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\",\"Attribute\":[" +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"}," +// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"22:12:10Z\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"}]}]" +// + ",\"ReturnPolicyIdList\":false,\"CombinedDecision\":false}}"; + + + + + // load JSON into a Request + jsonRequest = JSONRequest.load(jsonString); + + // compare the two Request objects + + // check simple things first + assertEquals("File '" + currentFile.getName() + "' CombinedDecision", xmlRequest.getCombinedDecision(), jsonRequest.getCombinedDecision()); + assertEquals("File '" + currentFile.getName() + "' getReturnPolicyIdList", xmlRequest.getReturnPolicyIdList(), jsonRequest.getReturnPolicyIdList()); + assertEquals("File '" + currentFile.getName() + "' requestDefaults", xmlRequest.getRequestDefaults(), jsonRequest.getRequestDefaults()); + + // multiRequests (guaranteed to not be null) + // We do NOT care about ordering, so compare the two collections inefficiently + Collection<RequestReference> xmlCollection = xmlRequest.getMultiRequests(); + Collection<RequestReference> jsonCollection = jsonRequest.getMultiRequests(); + String errorMessage = null; + if (jsonCollection.size() != xmlCollection.size()) { + errorMessage = "File '" + currentFile.getName() + "' MultiRequests not same size. "; + } else if (! jsonCollection.containsAll(xmlCollection)) { + errorMessage = "File '" + currentFile.getName() + "' MultiRequests have different contents. "; + } + if (errorMessage != null) { + String xmlContents = ""; + String jsonContents = ""; + Iterator<RequestReference> rrIt = xmlCollection.iterator(); + while (rrIt.hasNext()) { + xmlContents += "\n " + rrIt.next().toString(); + } + rrIt = jsonCollection.iterator(); + while (rrIt.hasNext()) { + jsonContents += "\n " + rrIt.next().toString(); + } + fail(errorMessage + "\nXML(" + xmlCollection.size() + ")='" + xmlContents + + "' \nJSON(" + jsonCollection.size() + ")='" + jsonContents + + "'" + + "\njson='" + jsonString + "'"); + } + + // attributes (guaranteed to not be null) + // We do NOT care about ordering, so compare the two collections inefficiently + Collection<RequestAttributes> xmlAttrCollection = xmlRequest.getRequestAttributes(); + Collection<RequestAttributes> jsonAttrCollection = jsonRequest.getRequestAttributes(); + errorMessage = null; + if (jsonAttrCollection.size() != xmlAttrCollection.size()) { + errorMessage = "File '" + currentFile.getName() + "' RequestAttributes not same size. "; + } else if (! jsonAttrCollection.containsAll(xmlAttrCollection)) { + String attrName = ""; + Iterator<RequestAttributes> rait = xmlAttrCollection.iterator(); + while (rait.hasNext()) { + RequestAttributes ra = rait.next(); + if (jsonAttrCollection.contains(ra) == false) { + attrName = ra.toString(); + } + } + errorMessage = "File '" + currentFile.getName() + "' RequestAttributes have different contents. JSON is missing attr=" + attrName; + } + if (errorMessage != null) { + String xmlContents = ""; + String jsonContents = ""; + Iterator<RequestAttributes> rrIt = xmlAttrCollection.iterator(); + while (rrIt.hasNext()) { + RequestAttributes ras = rrIt.next(); + xmlContents += "\n " + ras.toString(); + if (ras.getContentRoot() != null) { + StringWriter writer = new StringWriter(); + Transformer transformer = null; + try { + transformer = TransformerFactory.newInstance().newTransformer(); + transformer.transform(new DOMSource(ras.getContentRoot()), new StreamResult(writer)); + } catch (Exception e) { + throw new JSONStructureException("Unable to Content node to string; e="+e); + } + + xmlContents += "\n Content: " + writer.toString(); + } + } + rrIt = jsonAttrCollection.iterator(); + while (rrIt.hasNext()) { + RequestAttributes ras = rrIt.next(); + jsonContents += "\n " + ras.toString(); + if (ras.getContentRoot() != null) { + StringWriter writer = new StringWriter(); + Transformer transformer = null; + try { + transformer = TransformerFactory.newInstance().newTransformer(); + transformer.transform(new DOMSource(ras.getContentRoot()), new StreamResult(writer)); + } catch (Exception e) { + throw new JSONStructureException("Unable to Content node to string; e="+e); + } + + jsonContents += "\n Content: " + writer.toString(); + } + } + fail(errorMessage + "\nXML(" + xmlAttrCollection.size() + ")='" + xmlContents + + "' \nJSON(" + jsonAttrCollection.size() + ")='" + jsonContents + + "\njson='" + jsonString + "'"); + } + + + } + + } catch (Exception e) { + fail ("Failed test with '" + currentFile.getName() + "', e=" + e); + } + + + } + + // + // HELPER to get list of all Request files in the given directory + // + + private List<File> getRequestsInDirectory(File directory) { + List<File> fileList = new ArrayList<File>(); + + File[] fileArray = directory.listFiles(); + for (File f : fileArray) { + if (f.isDirectory()) { + List<File> subDirList = getRequestsInDirectory(f); + fileList.addAll(subDirList); + } + if (f.getName().endsWith("Request.xml")) { + fileList.add(f); + } + } + return fileList; + + } + +} + + + + +/* +Place to dump very long trace/exception strings that need manual editing to understand + + + + + + + */ + + + + + + + + +
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java new file mode 100755 index 0000000..f919878 --- /dev/null +++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java
@@ -0,0 +1,1418 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacmlatt.pdp.std.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONStructureException; +/** + * Test JSON Request convert to object - Default Category object tests + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOTE: + * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects + * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element. + * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object + * and we compare the resulting String to our expected String. + * This has two possible sources of error: + * - toString might not include some sub-component, and + * - the initial verification of the resulting string is done by hand and may have been incorrect. + * + * @author glenngriffin + * + */ +public class RequestDefaultCategoryTest { + + // The request object output from each test conversion from JSON string + Request request; + + + /* + * Request that uses all fields with both single and multiple entries + */ + String allFieldsRequest = + "{\"Request\": {" + + "\"ReturnPolicyIdList\" : true ," + + "\"CombinedDecision\" : true ," + + "\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," + + "\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar1\"]" + + "}]" + + "}," + + + "\"Category\": [" + + "{ " + + "\"CategoryId\": \"custom-category\", " + + "\"Id\" : \"customId\", " + + "\"Attribute\" : [" + + "{" + + "\"AttributeId\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}, " + + "{" + + "\"AttributeId\" : \"document-url\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : \"http://somewhere.over.the.com/rainbow\" " + + "}, " + + "{" + + "\"AttributeId\" : \"page-list\", " + + "\"Value\" : [1, 2, 3, 4.5, 3, 2, 1] " + + "} " + + "]" + + "}, " + + "{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "], " + + + "\"AccessSubject\":{ " + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"," + + "\"Attribute\" : []" + + "}, " + + + "\"Resource\" : {" + + "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" + + "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+ + "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" + + + + "} " + + + + "}}"; + + /* + * The following example comes directly from the JSON Profile Spec + */ + String exampleFromSpec = "{ " + + "\"Request\" : { " + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "\"Action\" : { " + + "\"Attribute\": " + + "{ " + + "\"Id\" : \"action-id\", " + + "\"Value\" : \"http://www.xacml.eu/buy\", " + + "\"DataType\" : \"anyURI\" " + + "} " + + "}, " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"book-title\", " + + "\"Value\" : \"Learn German in 90 days\" " + + "}, " + + "{ " + + "\"Id\" : \"currency\", " + + "\"Value\" : \"SEK\" " + + "}, " + + "{ " + + "\"Id\" : \"price\", " + + "\"Value\" : 123.34 " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + /* + * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples). + * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding. + */ + String xPathExampleFromSpec = "{ " + + "\"Request\" : { " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : { " + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " + + "\"Namespaces\" : [{ " + + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}, " + + "{ " + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "} " + + "], " + + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " + + "} " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + // test Shorthand Category notation for elements not tested in their own section below. + // Categories that are more commonly used are fully tested. + // Given that the functions within the categories are the same irrespective of the name of the category, + // we assume that the contents of the category will work ok once the Shorthand notation is recognized, so all we need to test is the shorthand + // The ones that are tested in their own sections are: + // AccessSubject + // Action + // Resource + // Environment + // test Subject + @Test + public void testCategoryShorthand() { + + // RecipientSubject present both as element within Category and as separate RecipientSubject element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"RecipientSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // IntermediarySubject present both as element within Category and as separate IntermediarySubject element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"IntermediarySubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Codebase present both as element within Category and as separate Codebase element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:codebase\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:codebase\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Codebase\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // RequestingMachine present both as element within Category and as separate RequestingMachine element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"RequestingMachine\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + + + + + + + + + + + + + + // test AccessSubject + // Include test for backward compatibility with "Subject" + @Test + public void testAccessSubjectRequest() { + + // AccessSubject absent + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject as normal element under Category (with CategoryId==subject category id) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // multiple AccessSubjects under Category + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject present both as element within Category and as separate AccessSubject element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject present, no other Category element + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Subject present, no other Category element (Backward Compatibility + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Subject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject present, 1/multiple other Category element also present + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // 2 AccessSubjects - duplicates fail + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject with correct Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : { " + + "\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject with wrong Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : { " + + "\"CategoryId\" : \"notthesubject\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject with array of sub-object AccessSubjects (Multi Decision) + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : [" + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Arless\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Somewhere\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Barry\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Elsewhere\" " + + "} " + + "] " + + "} " + + "]" + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Somewhere}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Barry}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Elsewhere}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + + + + + + + // Action ... duplicate all AccessSubject tests... + // test Action + @Test + public void testActionRequest() { + + // Action absent + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action as normal element under Category (with CategoryId==subject category id) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // multiple Actions under Category + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action present both as element within Category and as separate Action element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action present, no other Category element + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action present, 1/multiple other Category element also present + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // 2 Actions - duplicates fail + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action with correct Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : { " + + "\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action with wrong Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : { " + + "\"CategoryId\" : \"notthesubject\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action with array of sub-object Actions (Multi Decision) + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : [" + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Arless\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Somewhere\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Barry\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Elsewhere\" " + + "} " + + "] " + + "} " + + "]" + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false