Update of /cvsroot/sunxacml/sunxacml/com/sun/xacml
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21866/com/sun/xacml
Modified Files:
AbstractPolicy.java Policy.java PolicyReference.java
PolicySet.java Rule.java Target.java TargetMatch.java
VersionConstraints.java
Added Files:
PolicyMetaData.java TargetMatchGroup.java TargetSection.java
Log Message:
substantial update to align 2.0 features (Target and Condition) and code
re-factoring to better handle Expression/Evaluatable, versions, Target, etc.
Index: PolicySet.java
===================================================================
RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/PolicySet.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** PolicySet.java 7 Jan 2005 23:46:33 -0000 1.6
--- PolicySet.java 5 Dec 2005 23:34:51 -0000 1.7
***************
*** 261,264 ****
--- 261,265 ----
HashMap policyParameters = new HashMap();
HashMap policySetParameters = new HashMap();
+ PolicyMetaData metaData = getMetaData();
// collect the PolicySet-specific elements
***************
*** 273,279 ****
policies.add(Policy.getInstance(child));
} else if (name.equals("PolicySetIdReference")) {
! policies.add(PolicyReference.getInstance(child, finder));
} else if (name.equals("PolicyIdReference")) {
! policies.add(PolicyReference.getInstance(child, finder));
} else if (name.equals("PolicyCombinerParameters")) {
paramaterHelper(policyParameters, child, "Policy");
--- 274,282 ----
policies.add(Policy.getInstance(child));
} else if (name.equals("PolicySetIdReference")) {
! policies.add(PolicyReference.getInstance(child, finder,
! metaData));
} else if (name.equals("PolicyIdReference")) {
! policies.add(PolicyReference.getInstance(child, finder,
! metaData));
} else if (name.equals("PolicyCombinerParameters")) {
paramaterHelper(policyParameters, child, "Policy");
Index: TargetMatch.java
===================================================================
RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/TargetMatch.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** TargetMatch.java 17 Mar 2004 18:03:37 -0000 1.6
--- TargetMatch.java 5 Dec 2005 23:34:51 -0000 1.7
***************
*** 3,7 ****
* @(#)TargetMatch.java
*
! * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
--- 3,7 ----
* @(#)TargetMatch.java
*
! * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
***************
*** 70,77 ****
/**
! * Represents the SubjectMatch, ResourceMatch, or ActionMatch XML types in
! * XACML, depending on the value of the type field. This is the part of the
! * Target that actually evaluates whether the specified attribute values in the
! * Target match the corresponding attribute values in the request context.
*
* @since 1.0
--- 70,78 ----
/**
! * Represents the SubjectMatch, ResourceMatch, ActionMatch, or EnvironmentMatch
! * (in XACML 2.0 and later) XML types in XACML, depending on the value of the
! * type field. This is the part of the Target that actually evaluates whether
! * the specified attribute values in the Target match the corresponding
! * attribute values in the request context.
*
* @since 1.0
***************
*** 96,103 ****
public static final int ACTION = 2;
! //
private int type;
private Function function;
private Evaluatable eval;
private AttributeValue attrValue;
--- 97,122 ----
public static final int ACTION = 2;
! /**
! * An integer value indicating that this class represents an
! * EnvironmentMatch
! */
! public static final int ENVIRONMENT = 3;
!
! /**
! * Mapping from the 4 match types to their string representations
! */
! public static final String [] NAMES = { "Subject", "Resource", "Action",
! "Environment" };
!
! // the type of this target match
private int type;
+
+ // the function used for matching
private Function function;
+
+ // the designator or selector
private Evaluatable eval;
+
+ // the value
private AttributeValue attrValue;
***************
*** 122,126 ****
if ((type != SUBJECT) &&
(type != RESOURCE) &&
! (type != ACTION))
throw new IllegalArgumentException("Unknown TargetMatch type");
--- 141,146 ----
if ((type != SUBJECT) &&
(type != RESOURCE) &&
! (type != ACTION) &&
! (type != ENVIRONMENT))
throw new IllegalArgumentException("Unknown TargetMatch type");
***************
*** 136,139 ****
--- 156,164 ----
* or ActionMatch.
*
+ * @deprecated As of 2.0 you should avoid using this method and should
+ * instead use the version that takes a
+ * <code>PolicyMetaData</code> instance. This method will
+ * only work for XACML 1.x policies.
+ *
* @param root the node to parse for the <code>TargetMatch</code>
* @param prefix a String indicating what type of <code>TargetMatch</code>
***************
*** 152,156 ****
throws ParsingException, IllegalArgumentException
{
! int type;
Function function;
Evaluatable eval = null;
--- 177,211 ----
throws ParsingException, IllegalArgumentException
{
! int i = 0;
! while ((i < NAMES.length) && (! NAMES[i].equals(prefix)))
! i++;
!
! if (i == NAMES.length)
! throw new IllegalArgumentException("Unknown TargetMatch type");
!
! return getInstance(root, i,
! new PolicyMetaData(
! PolicyMetaData.XACML_1_0_IDENTIFIER,
! xpathVersion));
! }
!
! /**
! * Creates a <code>TargetMatch</code> by parsing a node, using the
! * input prefix to determine whether this is a SubjectMatch, ResourceMatch,
! * or ActionMatch.
! *
! * @param root the node to parse for the <code>TargetMatch</code>
! * @param matchType the type of <code>TargetMatch</code> as specified by
! * the SUBJECT, RESOURCE, ACTION, or ENVIRONMENT fields
! * @param metaData the policy's meta-data
! *
! * @return a new <code>TargetMatch</code> constructed by parsing
! *
! * @throws ParsingException if there was an error during parsing
! */
! public static TargetMatch getInstance(Node root, int matchType,
! PolicyMetaData metaData)
! throws ParsingException
! {
Function function;
Evaluatable eval = null;
***************
*** 159,174 ****
AttributeFactory attrFactory = AttributeFactory.getInstance();
! // first off, figure out which of three types we are
! if (prefix.equals("Subject")) {
! type = SUBJECT;
! } else if (prefix.equals("Resource")) {
! type = RESOURCE;
! } else if (prefix.equals("Action")) {
! type = ACTION;
! } else {
! throw new IllegalArgumentException("Unknown TargetMatch type");
! }
!
! // now get the function type, making sure that it's really a correct
// Target function
String funcName = root.getAttributes().
--- 214,218 ----
AttributeFactory attrFactory = AttributeFactory.getInstance();
! // get the function type, making sure that it's really a correct
// Target function
String funcName = root.getAttributes().
***************
*** 200,207 ****
String name = node.getNodeName();
! if (name.equals(prefix + "AttributeDesignator")) {
! eval = AttributeDesignator.getInstance(node, type);
} else if (name.equals("AttributeSelector")) {
! eval = AttributeSelector.getInstance(node, xpathVersion);
} else if (name.equals("AttributeValue")) {
try {
--- 244,252 ----
String name = node.getNodeName();
! if (name.equals(NAMES[matchType] + "AttributeDesignator")) {
! eval = AttributeDesignator.getInstance(node, matchType,
! metaData);
} else if (name.equals("AttributeSelector")) {
! eval = AttributeSelector.getInstance(node, metaData);
} else if (name.equals("AttributeValue")) {
try {
***************
*** 219,228 ****
function.checkInputsNoBag(inputs);
! return new TargetMatch(type, function, eval, attrValue);
}
/**
* Returns the type of this <code>TargetMatch</code>, either
! * <code>SUBJECT</code>, <code>RESOURCE</code>, or <code>ACTION</code>.
*
* @return the type
--- 264,274 ----
function.checkInputsNoBag(inputs);
! return new TargetMatch(matchType, function, eval, attrValue);
}
/**
* Returns the type of this <code>TargetMatch</code>, either
! * <code>SUBJECT</code>, <code>RESOURCE</code>, <code>ACTION</code>, or
! * <code>ENVIRONMENT</code>.
*
* @return the type
***************
*** 373,386 ****
PrintStream out = new PrintStream(output);
String indent = indenter.makeString();
! String tagName = null;
!
! switch (type) {
! case SUBJECT: tagName = "SubjectMatch";
! break;
! case RESOURCE: tagName = "ResourceMatch";
! break;
! case ACTION: tagName = "ActionMatch";
! break;
! }
out.println(indent + "<" + tagName + " MatchId=\"" +
--- 419,423 ----
PrintStream out = new PrintStream(output);
String indent = indenter.makeString();
! String tagName = NAMES[type] + "Match";
out.println(indent + "<" + tagName + " MatchId=\"" +
Index: AbstractPolicy.java
===================================================================
RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/AbstractPolicy.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** AbstractPolicy.java 17 Feb 2005 15:58:24 -0000 1.13
--- AbstractPolicy.java 5 Dec 2005 23:34:50 -0000 1.14
***************
*** 76,85 ****
{
- /**
- * XPath 1.0 identifier, the only version we support right now
- */
- public static final String XPATH_1_0_VERSION =
- "http://www.w3.org/TR/1999/Rec-xpath-19991116";
-
// atributes associated with this policy
private URI idAttr;
--- 76,79 ----
***************
*** 94,97 ****
--- 88,94 ----
private String defaultVersion;
+ // the meta-data associated with this policy
+ private PolicyMetaData metaData;
+
// the child elements under this policy represented simply as the
// PolicyTreeElements...
***************
*** 181,184 ****
--- 178,184 ----
this.version = version;
+ // FIXME: this needs to fill in the meta-data correctly
+ metaData = null;
+
if (obligations == null)
this.obligations = Collections.EMPTY_SET;
***************
*** 249,257 ****
}
obligations = new HashSet();
parameters = new ArrayList();
- // now read the policy elements
- NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
--- 249,271 ----
}
+ // do an initial pass through the elements to pull out the
+ // defaults, if any, so we can setup the meta-data
+ NodeList children = root.getChildNodes();
+ String xpathVersion = null;
+
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if (child.getNodeName().equals(policyPrefix + "Defaults"))
+ handleDefaults(child);
+ }
+
+ // with the defaults read, create the meta-data
+ metaData = new PolicyMetaData(root.getNamespaceURI(), defaultVersion);
+
+ // now read the remaining policy elements
obligations = new HashSet();
parameters = new ArrayList();
+ children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
***************
*** 261,269 ****
description = child.getFirstChild().getNodeValue();
} else if (cname.equals("Target")) {
! target = Target.getInstance(child, defaultVersion);
} else if (cname.equals("Obligations")) {
parseObligations(child);
- } else if (cname.equals(policyPrefix + "Defaults")) {
- handleDefaults(child);
} else if (cname.equals("CombinerParameters")) {
handleParameters(child);
--- 275,281 ----
description = child.getFirstChild().getNodeValue();
} else if (cname.equals("Target")) {
! target = Target.getInstance(child, metaData);
} else if (cname.equals("Obligations")) {
parseObligations(child);
} else if (cname.equals("CombinerParameters")) {
handleParameters(child);
***************
*** 271,276 ****
}
! // finally, make sure the set of obligations is immutable
obligations = Collections.unmodifiableSet(obligations);
}
--- 283,289 ----
}
! // finally, make sure the obligations and parameters are immutable
obligations = Collections.unmodifiableSet(obligations);
+ parameters = Collections.unmodifiableList(parameters);
}
***************
*** 300,309 ****
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
! if (node.getNodeName().equals("XPathVersion")) {
defaultVersion = node.getFirstChild().getNodeValue();
- if (! defaultVersion.equals(XPATH_1_0_VERSION)) {
- throw new ParsingException("Unknown XPath version");
- }
- }
}
}
--- 313,318 ----
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
! if (node.getNodeName().equals("XPathVersion"))
defaultVersion = node.getFirstChild().getNodeValue();
}
}
***************
*** 332,336 ****
/**
! * Returns the version of this policy
*
* @return the policy version
--- 341,346 ----
/**
! * Returns the version of this policy. If this is an XACML 1.x policy
! * then this will always return <code>"1.0"</code>.
*
* @return the policy version
***************
*** 350,353 ****
--- 360,373 ----
/**
+ * Returns the list of input parameters for the combining algorithm. If
+ * this is an XACML 1.x policy then the list will always be empty.
+ *
+ * @return a <code>List</code> of <code>CombinerParameter</code>s
+ */
+ public List getCombiningParameters() {
+ return parameters;
+ }
+
+ /**
* Returns the given description of this policy or null if there is no
* description
***************
*** 411,414 ****
--- 431,441 ----
/**
+ * Returns the meta-data associated with this policy
+ */
+ public PolicyMetaData getMetaData() {
+ return metaData;
+ }
+
+ /**
* Given the input context sees whether or not the request matches this
* policy. This must be called by combining algorithms before they
--- NEW FILE: PolicyMetaData.java ---
/*
* @(#)PolicyMetaData.java
*
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
/**
* This is used to share polcy meta-data throughout the policy tree. Examples
* of common meta-data include the version of XACML or XPath being used in
* a policy.
*
* @since 2.0
* @author Seth Proctor
*/
public class PolicyMetaData
{
/**
* XACML 1.0 identifier
*/
public static final String XACML_1_0_IDENTIFIER =
"urn:oasis:names:tc:xacml:1.0:policy";
/**
* XACML 2.0 identifier
*/
public static final String XACML_2_0_IDENTIFIER =
"urn:oasis:names:tc:xacml:2.0:policy:schema:os";
/**
* Version identifier for XACML 1.0
*/
public static final int XACML_VERSION_1_0 = 0;
/**
* Version identifier for XACML 1.1 (which isn't a formal release
* so has no namespace string, but still exists as a separate
* specification)
*/
public static final int XACML_VERSION_1_1 = 1;
/**
* Version identifier for XACML 1.2
*/
public static final int XACML_VERSION_2_0 = 2;
/**
* The default version of XACML, 1.0, used if no namespace string
* is specified
*/
public static final int XACML_DEFAULT_VERSION = XACML_VERSION_1_0;
// private mapping from XACML version number to identifier string
private static String [] xacmlIdentifiers = { XACML_1_0_IDENTIFIER,
XACML_1_0_IDENTIFIER,
XACML_2_0_IDENTIFIER };
/**
* XPath 1.0 identifier
*/
public static final String XPATH_1_0_IDENTIFIER =
"http://www.w3.org/TR/1999/Rec-xpath-19991116";
/**
* Version identifier for an unspecified version of XPath
*/
public static final int XPATH_VERSION_UNSPECIFIED = 0;
/**
* Version identifier for XPath 1.0
*/
public static final int XPATH_VERSION_1_0 = 1;
// private mapping from XPath version number to identifier string
private static String [] xpathIdentifiers = { null,
XPATH_1_0_IDENTIFIER };
// the version of XACML
private int xacmlVersion;
// the version of XPath, or null if none is specified
private int xpathVersion;
/**
* Creates a <code>PolicyMetaData</code> instance with the given
* parameters.
*
* @param xacmlVersion the version of XACML used in a policy
* @param xpathVersion the XPath version to use in any selectors
*/
public PolicyMetaData(int xacmlVersion, int xpathVersion) {
this.xacmlVersion = xacmlVersion;
this.xpathVersion = xpathVersion;
}
/**
* Creates a <code>PolicyMetaData</code> instance with the given
* parameters.
*
* @param xacmlVersion the version of XACML used in a policy
* @param xpathVersion the XPath version to use in any selectors, or
* null if this is unspecified (ie, not supplied in
* the defaults section of the policy)
*
* @throws IllegalArgumentException if the identifier strings are unknown
*/
public PolicyMetaData(String xacmlVersion, String xpathVersion) {
if (xacmlVersion == null)
this.xacmlVersion = XACML_DEFAULT_VERSION;
else if (xacmlVersion.equals(XACML_1_0_IDENTIFIER))
this.xacmlVersion = XACML_VERSION_1_0;
else if (xacmlVersion.equals(XACML_2_0_IDENTIFIER))
this.xacmlVersion = XACML_VERSION_2_0;
else
throw new IllegalArgumentException("Unknown XACML version " +
"string: " + xacmlVersion);
if (xpathVersion != null) {
if (! xpathVersion.equals(XPATH_1_0_IDENTIFIER))
throw new IllegalArgumentException("Unsupported XPath " +
" version: " +
xpathVersion);
this.xpathVersion = XPATH_VERSION_1_0;
} else {
this.xpathVersion = XPATH_VERSION_UNSPECIFIED;
}
}
/**
* Returns which version of XACML is specified in this meta-data.
*
* @return the XACML version
*/
public int getXACMLVersion() {
return xacmlVersion;
}
/**
* Returns the identifier string for the specified version of XACML.
*
* @return the identifier string
*/
public String getXACMLIdentifier() {
return xacmlIdentifiers[xacmlVersion];
}
/**
* Returns which version of XPath is specified in this meta-data.
*
* @return the XPath version or null
*/
public int getXPathVersion() {
return xpathVersion;
}
/**
* Returns the identifier string for the specified version of XPath, or
* null if no version is specified.
*
* @return the identifier string or null
*/
public String getXPathIdentifier() {
return xpathIdentifiers[xpathVersion];
}
}
Index: Target.java
===================================================================
RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/Target.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** Target.java 4 Jun 2004 17:50:39 -0000 1.8
--- Target.java 5 Dec 2005 23:34:51 -0000 1.9
***************
*** 3,7 ****
* @(#)Target.java
*
! * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
--- 3,7 ----
* @(#)Target.java
*
! * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
***************
*** 37,50 ****
package com.sun.xacml;
- import com.sun.xacml.ctx.Status;
-
import java.io.OutputStream;
import java.io.PrintStream;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Iterator;
- import java.util.List;
-
import java.util.logging.Level;
import java.util.logging.Logger;
--- 37,43 ----
***************
*** 56,62 ****
/**
* Represents the TargetType XML type in XACML. This also stores several
! * other XML types: Subjects, Resources, and Actions. The target is
! * used to quickly identify whether the parent element (a policy set,
! * policy, or rule) is applicable to a given request.
*
* @since 1.0
--- 49,55 ----
/**
* Represents the TargetType XML type in XACML. This also stores several
! * other XML types: Subjects, Resources, Actions, and Environments (in XACML
! * 2.0 and later). The target is used to quickly identify whether the parent
! * element (a policy set, policy, or rule) is applicable to a given request.
*
* @since 1.0
***************
*** 66,73 ****
{
! // the elements in a Target, all of which are required
! private List subjects;
! private List resources;
! private List actions;
// the logger we'll use for all messages
--- 59,70 ----
{
! // the four sections of a Target
! private TargetSection subjectsSection;
! private TargetSection resourcesSection;
! private TargetSection actionsSection;
! private TargetSection environmentsSection;
!
! // the version of XACML of the policy containing this target
! private int xacmlVersion;
// the logger we'll use for all messages
***************
*** 76,109 ****
/**
! * Constructor that creates a <code>Target</code> from components.
*
! * @param subjects A <code>List</code> containing the subjects or null
! * if this represents AnySubject. The list is of the
! * form described in <code>getSubjects</code>.
! * @param resources A <code>List</code> containing the resources or null
! * if this represents AnyResource The list is of the
! * form described in <code>getResources</code>.
! * @param actions A <code>List</code> containing the actions or null
! * if this represents AnyAction The list is of the
! * form described in <code>getActions</code>.
*/
! public Target(List subjects, List resources, List actions) {
! if (subjects == null)
! this.subjects = subjects;
! else
! this.subjects = Collections.
! unmodifiableList(new ArrayList(subjects));
! if (resources == null)
! this.resources = resources;
! else
! this.resources = Collections.
! unmodifiableList(new ArrayList(resources));
! if (actions == null)
! this.actions = actions;
! else
! this.actions = Collections.
! unmodifiableList(new ArrayList(actions));
}
--- 73,134 ----
/**
! * Constructor that creates an XACML 1.x <code>Target</code> from
! * components. Each of the sections must be non-null, but they may match
! * any request. Because this is only used for 1.x Targets, there is no
! * Environments section.
*
! * @param subjectsSection a <code>TargetSection</code> representing
! * the Subjects section of this target
! * @param resourcesSection a <code>TargetSection</code> representing
! * the Resources section of this target
! * @param actionsSection a <code>TargetSection</code> representing
! * the Actions section of this target
*/
! public Target(TargetSection subjectsSection,
! TargetSection resourcesSection,
! TargetSection actionsSection) {
! if ((subjectsSection == null) || (resourcesSection == null) ||
! (actionsSection == null))
! throw new ProcessingException("All sections of a Target must " +
! "be non-null");
!
! this.subjectsSection = subjectsSection;
! this.resourcesSection = resourcesSection;
! this.actionsSection = actionsSection;
! this.environmentsSection =
! new TargetSection(null, TargetMatch.ENVIRONMENT,
! PolicyMetaData.XACML_VERSION_1_0);
! this.xacmlVersion = PolicyMetaData.XACML_VERSION_1_0;
! }
! /**
! * Constructor that creates an XACML 2.0 <code>Target</code> from
! * components. Each of the sections must be non-null, but they may
! * match any request.
! *
! * @param subjectsSection a <code>TargetSection</code> representing
! * the Subjects section of this target
! * @param resourcesSection a <code>TargetSection</code> representing
! * the Resources section of this target
! * @param actionsSection a <code>TargetSection</code> representing
! * the Actions section of this target
! * @param environmentsSection a <code>TargetSection</code> representing
! * the Environments section of this target
! */
! public Target(TargetSection subjectsSection,
! TargetSection resourcesSection,
! TargetSection actionsSection,
! TargetSection environmentsSection)
! {
! if ((subjectsSection == null) || (resourcesSection == null) ||
! (actionsSection == null) || (environmentsSection == null))
! throw new ProcessingException("All sections of a Target must " +
! "be non-null");
! this.subjectsSection = subjectsSection;
! this.resourcesSection = resourcesSection;
! this.actionsSection = actionsSection;
! this.environmentsSection = environmentsSection;
! this.xacmlVersion = PolicyMetaData.XACML_VERSION_2_0;
}
***************
*** 111,114 ****
--- 136,144 ----
* Creates a <code>Target</code> by parsing a node.
*
+ * @deprecated As of 2.0 you should avoid using this method and should
+ * instead use the version that takes a
+ * <code>PolicyMetaData</code> instance. This method will
+ * only work for XACML 1.x policies.
+ *
* @param root the node to parse for the <code>Target</code>
* @param xpathVersion the XPath version to use in any selectors, or
***************
*** 123,129 ****
throws ParsingException
{
! List subjects = null;
! List resources = null;
! List actions = null;
NodeList children = root.getChildNodes();
--- 153,177 ----
throws ParsingException
{
! return getInstance(root,
! new PolicyMetaData(
! PolicyMetaData.XACML_1_0_IDENTIFIER,
! xpathVersion));
! }
!
! /**
! * Creates a <code>Target</code> by parsing a node.
! *
! * @param root the node to parse for the <code>Target</code>
! * @return a new <code>Target</code> constructed by parsing
! *
! * @throws ParsingException if the DOM node is invalid
! */
! public static Target getInstance(Node root, PolicyMetaData metaData)
! throws ParsingException
! {
! TargetSection subjects = null;
! TargetSection resources = null;
! TargetSection actions = null;
! TargetSection environments = null;
NodeList children = root.getChildNodes();
***************
*** 133,247 ****
if (name.equals("Subjects")) {
! subjects = getAttributes(child, "Subject", xpathVersion);
} else if (name.equals("Resources")) {
! resources = getAttributes(child, "Resource", xpathVersion);
} else if (name.equals("Actions")) {
! actions = getAttributes(child, "Action", xpathVersion);
}
}
! return new Target(subjects, resources, actions);
! }
!
! /**
! * Helper method that parses the contents of the Subjects,
! * Resources, or Actions types, depending on the input prefix,
! * which must be either "Subject", "Resource", or "Action".
! * A null List specifies any attributes will match;
! * it represents AnySubject, AnyResource, or AnyAction.
! */
! private static List getAttributes(Node root, String prefix,
! String xpathVersion)
! throws ParsingException
! {
! List matches = new ArrayList();
! NodeList children = root.getChildNodes();
! for (int i = 0; i < children.getLength(); i++) {
! Node child = children.item(i);
! String name = child.getNodeName();
! if (name.equals(prefix)) {
! matches.add(getMatches(child, prefix, xpathVersion));
! } else if (name.equals("Any" + prefix)) {
! return null;
! }
}
-
- return matches;
}
/**
! * Helper method that parses the contents of a SubjectMatch,
! * ResourceMatch, or ActionMatch type, depending on the input
! * prefix, which must be either "Subject", "Resource" or "Action"
*/
! private static List getMatches(Node root, String prefix,
! String xpathVersion)
! throws ParsingException
! {
! List list = new ArrayList();
! NodeList children = root.getChildNodes();
!
! for (int i = 0; i < children.getLength(); i++) {
! Node child = children.item(i);
! String name = child.getNodeName();
!
! if (name.equals(prefix + "Match"))
! list.add(TargetMatch.getInstance(child, prefix, xpathVersion));
! }
! return Collections.unmodifiableList(list);
}
/**
! * Returns an unmodifiable <code>List</code> that represents the Subjects
! * section of this target. Each entry in the <code>List</code> is
! * another <code>List</code> that represents the Subject section. In turn,
! * each of these <code>List</code>s contains <code>TargetMatch</code>
! * objects that represent SubjectMatch XML structures.
! * <p>
! * Note that future versions of this code may use intermediary classes to
! * make the structure clearer, but this depends on the future structure
! * of XACML Targets.
*
! * @return the matching elements or null of the match is any
*/
! public List getSubjects() {
! return subjects;
}
/**
! * Returns an unmodifiable <code>List</code> that represents the Resources
! * section of this target. Each entry in the <code>List</code> is
! * another <code>List</code> that represents the Resource section. In turn,
! * each of these <code>List</code>s contains <code>TargetMatch</code>
! * objects that represent ResourceMatch XML structures.
! * <p>
! * Note that future versions of this code may use intermediary classes to
! * make the structure clearer, but this depends on the future structure
! * of XACML Targets.
*
! * @return the matching elements or null of the match is any
*/
! public List getResources() {
! return resources;
}
/**
! * Returns an unmodifiable <code>List</code> that represents the Actions
! * section of this target. Each entry in the <code>List</code> is
! * another <code>List</code> that represents the Action section. In turn,
! * each of these <code>List</code>s contains <code>TargetMatch</code>
! * objects that represent ActionMatch XML structures.
! * <p>
! * Note that future versions of this code may use intermediary classes to
! * make the structure clearer, but this depends on the future structure
! * of XACML Targets.
*
! * @return the matching elements or null of the match is any
*/
! public List getActions() {
! return actions;
}
--- 181,270 ----
if (name.equals("Subjects")) {
! subjects =
! TargetSection.getInstance(child, TargetMatch.SUBJECT,
! metaData);
} else if (name.equals("Resources")) {
! resources =
! TargetSection.getInstance(child, TargetMatch.RESOURCE,
! metaData);
} else if (name.equals("Actions")) {
! actions =
! TargetSection.getInstance(child, TargetMatch.ACTION,
! metaData);
! } else if (name.equals("Environments")) {
! environments =
! TargetSection.getInstance(child, TargetMatch.ENVIRONMENT,
! metaData);
}
}
! // starting in 2.0 an any-matching section is represented by a
! // missing element, and in 1.x there were no Environments elements,
! // so these need to get turned into non-null arguments
! int version = metaData.getXACMLVersion();
! if (subjects == null)
! subjects = new TargetSection(null, TargetMatch.SUBJECT, version);
! if (resources == null)
! resources = new TargetSection(null, TargetMatch.RESOURCE, version);
! if (actions == null)
! actions = new TargetSection(null, TargetMatch.ACTION, version);
! if (version == PolicyMetaData.XACML_VERSION_2_0) {
! if (environments == null)
! environments = new TargetSection(null, TargetMatch.ENVIRONMENT,
! version);
! return new Target(subjects, resources, actions, environments);
! } else {
! return new Target(subjects, resources, actions);
}
}
/**
! * Returns the Subjects section of this Target.
! *
! * @return a <code>TargetSection</code> representing the Subjects
*/
! public TargetSection getSubjectsSection() {
! return subjectsSection;
! }
! /**
! * Returns the Resources section of this Target.
! *
! * @return a <code>TargetSection</code> representing the Resources
! */
! public TargetSection getResourcesSection() {
! return resourcesSection;
}
/**
! * Returns the Actions section of this Target.
*
! * @return a <code>TargetSection</code> representing the Actions
*/
! public TargetSection getActionsSection() {
! return actionsSection;
}
/**
! * Returns the Environments section of this Target. Note that if this is
! * an XACML 1.x policy, then the section will always match anything,
! * since XACML 1.x doesn't support matching on the Environment.
*
! * @return a <code>TargetSection</code> representing the Environments
*/
! public TargetSection getEnvironmentsSection() {
! return environmentsSection;
}
/**
! * Returns whether or not this <code>Target</code> matches any request.
*
! * @return true if this Target matches any request, false otherwise
*/
! public boolean matchesAny() {
! return subjectsSection.matchesAny() && resourcesSection.matchesAny() &&
! actionsSection.matchesAny() && environmentsSection.matchesAny();
}
***************
*** 255,338 ****
*/
public MatchResult match(EvaluationCtx context) {
! // first look to see if there are any subjects to match
! if (subjects != null) {
! MatchResult result = checkSet(subjects, context);
! if (result.getResult() != MatchResult.MATCH) {
! logger.finer("failed to match Subjects section of Target");
! return result;
! }
! }
! // now look to see if there is a resource to match
! if (resources != null) {
! MatchResult result = checkSet(resources, context);
! if (result.getResult() != MatchResult.MATCH) {
! logger.finer("failed to match Resources section of Target");
! return result;
! }
! }
! // finally, see if there are any actions to match
! if (actions != null) {
! MatchResult result = checkSet(actions, context);
! if (result.getResult() != MatchResult.MATCH) {
! logger.finer("failed to match Actions section of Target");
! return result;
! }
}
! // if we got here, then everything matched
! return new MatchResult(MatchResult.MATCH);
! }
!
! /**
! * Helper function that determines whether there is at least
! * one positive match between each section of the Target element
! * and the input request
! */
! private MatchResult checkSet(List matchList, EvaluationCtx context) {
! Iterator it = matchList.iterator();
! boolean allFalse = true;
! Status firstIndeterminateStatus = null;
!
! // for each item in this loop, there must be at least one match
! while (it.hasNext()) {
! // first off, get the next set of objects
! List list = (List)(it.next());
! Iterator it2 = list.iterator();
! MatchResult result = null;
!
! // now we go through the set, every one of which must match
! while (it2.hasNext()) {
! TargetMatch tm = (TargetMatch)(it2.next());
! result = tm.match(context);
! if (result.getResult() != MatchResult.MATCH)
! break;
! }
!
! // if the last one was a MATCH, then all of the matches
! // matched, so we're done
! if (result.getResult() == MatchResult.MATCH)
! return result;
! // if we didn't match then it was either a NO_MATCH or
! // INDETERMINATE...in the second case, we need to remember
! // it happened, 'cause if we don't get a MATCH, then we'll
! // be returning INDETERMINATE
! if (result.getResult() == MatchResult.INDETERMINATE) {
! allFalse = false;
! if (firstIndeterminateStatus == null)
! firstIndeterminateStatus = result.getStatus();
! }
}
! // if we got here, then none of the sub-matches passed, so
! // we have to see if we got any INDETERMINATE cases
! if (allFalse)
! return new MatchResult(MatchResult.NO_MATCH);
! else
! return new MatchResult(MatchResult.INDETERMINATE,
! firstIndeterminateStatus);
}
--- 278,317 ----
*/
public MatchResult match(EvaluationCtx context) {
! MatchResult result = null;
! // before matching, see if this target matches any request
! if (matchesAny())
! return new MatchResult(MatchResult.MATCH);
! // first, try matching the Subjects section
! result = subjectsSection.match(context);
! if (result.getResult() != MatchResult.MATCH) {
! logger.finer("failed to match Subjects section of Target");
! return result;
}
! // now try matching the Resources section
! result = resourcesSection.match(context);
! if (result.getResult() != MatchResult.MATCH) {
! logger.finer("failed to match Resources section of Target");
! return result;
! }
! // next, look at the Actions section
! result = actionsSection.match(context);
! if (result.getResult() != MatchResult.MATCH) {
! logger.finer("failed to match Actions section of Target");
! return result;
! }
! // finally, match the Environments section
! result = environmentsSection.match(context);
! if (result.getResult() != MatchResult.MATCH) {
! logger.finer("failed to match Environments section of Target");
! return result;
}
! // if we got here, then everything matched
! return result;
}
***************
*** 360,413 ****
String indent = indenter.makeString();
! out.println(indent + "<Target>");
! indenter.in();
!
! encodeSection(out, indenter, "Subject", subjects);
! encodeSection(out, indenter, "Resource", resources);
! encodeSection(out, indenter, "Action", actions);
!
! indenter.out();
! out.println(indent + "</Target>");
! }
!
! /**
! * Helper function that encodes a section of the target.
! */
! private void encodeSection(PrintStream output, Indenter indenter,
! String name, List list) {
! String indent = indenter.makeString();
!
! output.println(indent + "<" + name + "s>");
!
! indenter.in();
! String indentNext = indenter.makeString();
! if (list == null) {
! // the match is any
! output.println(indentNext + "<Any" + name + "/>");
} else {
! String nextIndent = indenter.makeString();
!
! Iterator it = list.iterator();
indenter.in();
! while (it.hasNext()) {
! List items = (List)(it.next());
! output.println(indentNext + "<" + name + ">");
!
! Iterator matchIterator = items.iterator();
! while (matchIterator.hasNext()) {
! TargetMatch tm = (TargetMatch)(matchIterator.next());
! tm.encode(output, indenter);
! }
!
! output.println(indentNext + "</" + name + ">");
! }
!
indenter.out();
}
-
- indenter.out();
- output.println(indent + "</" + name + "s>");
}
--- 339,367 ----
String indent = indenter.makeString();
! // see if this Target matches anything
! boolean matchesAny = (subjectsSection.matchesAny() &&
! resourcesSection.matchesAny() &&
! actionsSection.matchesAny() &&
! environmentsSection.matchesAny());
! if (matchesAny && (xacmlVersion == PolicyMetaData.XACML_VERSION_2_0)) {
! // in 2.0, if all the sections match any request, then the Target
! // element is empty and should be encoded simply as en empty tag
! out.println("<Target/>");
} else {
! out.println(indent + "<Target>");
indenter.in();
! subjectsSection.encode(output, indenter);
! resourcesSection.encode(output, indenter);
! actionsSection.encode(output, indenter);
!
! // we should only do this if we're a 2.0 policy
! if (xacmlVersion == PolicyMetaData.XACML_VERSION_2_0)
! environmentsSection.encode(output, indenter);
!
indenter.out();
+ out.println(indent + "</Target>");
}
}
Index: PolicyReference.java
===================================================================
RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/PolicyReference.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** PolicyReference.java 7 Jan 2005 23:47:42 -0000 1.8
--- PolicyReference.java 5 Dec 2005 23:34:51 -0000 1.9
***************
*** 109,113 ****
/**
! * Creates a new <code>PolicyReference</code>.
*
* @param reference the reference to the policy
--- 109,133 ----
/**
! * Creates a new <code>PolicyReference</code> instance. This has no
! * constraints on version matching. Note that an XACML 1.x reference may
! * not have any constraints.
! *
! * @param reference the reference to the policy
! * @param policyType one of the two fields in this class
! * @param finder the <code>PolicyFinder</code> used to handle the reference
! *
! * @throws IllegalArgumentException if the input policyType isn't valid
! */
! public PolicyReference(URI reference, int policyType, PolicyFinder finder)
! throws IllegalArgumentException
! {
! this(reference, policyType, new VersionConstraints(null, null, null),
! finder);
! }
!
! /**
! * Creates a new <code>PolicyReference</code> instance with version
! * constraints. Note that an XACML 1.x reference may not have any
! * constraints.
*
* @param reference the reference to the policy
***************
*** 142,145 ****
--- 162,170 ----
* a DOM node.
*
+ * @deprecated As of 2.0 you should avoid using this method and should
+ * instead use the version that takes a
+ * <code>PolicyMetaData</code> instance. This method will
+ * only work for XACML 1.x policies.
+ *
* @param root the DOM root of a PolicyIdReference or a
* PolicySetIdReference XML type
***************
*** 151,154 ****
--- 176,200 ----
throws ParsingException
{
+ return getInstance(root, finder,
+ new PolicyMetaData(
+ PolicyMetaData.XACML_VERSION_1_0,
+ PolicyMetaData.XPATH_VERSION_UNSPECIFIED));
+ }
+
+ /**
+ * Creates an instance of a <code>PolicyReference</code> object based on
+ * a DOM node.
+ *
+ * @param root the DOM root of a PolicyIdReference or a
+ * PolicySetIdReference XML type
+ * @param finder the <code>PolicyFinder</code> used to handle the reference
+ * @param metaData the meta-data associated with the containing policy
+ *
+ * @exception ParsingException if the node is invalid
+ */
+ public static PolicyReference getInstance(Node root, PolicyFinder finder,
+ PolicyMetaData metaData)
+ throws ParsingException
+ {
URI reference = null;
int policyType;
***************
*** 339,342 ****
--- 385,400 ----
/**
+ * Returns the meta-data associated with this policy. If the policy is
+ * invalid or can't be retrieved, then a runtime exception is thrown.
+ *
+ * @return the policy's meta-data
+ *
+ * @throws ProcessingException if the referenced policy can't be retrieved
+ */
+ public PolicyMetaData getMetaData() {
+ return resolvePolicy().getMetaData();
+ }
+
+ /**
* Given the input context sees whether or not the request matches this
* policy. This must be called by combining algorithms before they
***************
*** 456,460 ****
/**
! * Private helper method that encodes the variable constraints info
*/
private String encodeConstraints() {
--- 514,520 ----
/**
! * Private helper method that encodes the variable constraints info. Note
! * that if this is a pre-2.0 policy the constraints are always null, so
! * nothing will be added here.
*/
private String encodeConstraints() {
Index: VersionConstraints.java
===================================================================
RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/VersionConstraints.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** VersionConstraints.java 7 Jan 2005 23:47:42 -0000 1.1
--- VersionConstraints.java 5 Dec 2005 23:34:51 -0000 1.2
***************
*** 172,177 ****
// ...and a version too
if (version == null)
! return false;
// setup tokenizers
--- 172,180 ----
// ...and a version too
+ // FIXME: this originally returned false, but I think it should
+ // return true, since we always match if the contstraint is
+ // unbound (null) ... is that right?
if (version == null)
! return true;
// setup tokenizers
--- NEW FILE: TargetSection.java ---
/*
* @(#)TargetSection.java
*
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.ctx.Status;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This is a container class for instances of <code>TargetMatchGroup</code>
* and represents the Subjects, Resources, Actions, and Environments
* sections of an XACML Target. This section may apply to any request.
*
* @since 2.0
* @author Seth Proctor
*/
public class TargetSection
{
// the list of match groups
private List matchGroups;
// the match type contained in this group
private int matchType;
// the version of XACML used by the containing Target
private int xacmlVersion;
/**
* Constructor that takes a group and a version. The if the group is
* null or empty, then this represents a section that matches any request.
*
* @param matchGroups a possibly null <code>List</code> of
* <code>TargetMatchGroup</code>s
* @param xacmlVersion the version XACML being used
* @param matchType
*/
public TargetSection(List matchGroups, int matchType, int xacmlVersion) {
if (matchGroups == null)
this.matchGroups = Collections.unmodifiableList(new ArrayList());
else
this.matchGroups = Collections.
unmodifiableList(new ArrayList(matchGroups));
this.matchType = matchType;
this.xacmlVersion = xacmlVersion;
}
/**
* Creates a <code>Target</code> by parsing a node.
*
* @param root the node to parse for the <code>Target</code>
* @param matchType
* @param metaData
*
* @return a new <code>Target</code> constructed by parsing
*
* @throws ParsingException if the DOM node is invalid
*/
public static TargetSection getInstance(Node root, int matchType,
PolicyMetaData metaData)
throws ParsingException
{
List groups = new ArrayList();
NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
String name = child.getNodeName();
String typeName = TargetMatch.NAMES[matchType];
if (name.equals(typeName)) {
groups.add(TargetMatchGroup.getInstance(child, matchType,
metaData));
} else if (name.equals("Any" + typeName)) {
// in a schema-valid policy, the Any element will always be
// the only element, so if we find this we stop
break;
}
}
// at this point the list is non-empty (it has specific groups to
// match) or is empty (it applies to any request using the 1.x or
// 2.0 syntax)
return new TargetSection(groups, matchType,
metaData.getXACMLVersion());
}
/**
* Returns the <code>TargetMatchGroup</code>s contained in this group.
*
* @return a <code>List</code> of <code>TargetMatchGroup</code>s
*/
public List getMatchGroups() {
return matchGroups;
}
/**
* Returns whether this section matches any request.
*
* @return true if this section matches any request, false otherwise
*/
public boolean matchesAny() {
return matchGroups.isEmpty();
}
/**
* Determines whether this <code>TargetSection</code> matches
* the input request (whether it is applicable).
*
* @param context the representation of the request
*
* @return the result of trying to match the target and the request
*/
public MatchResult match(EvaluationCtx context) {
// if we apply to anything, then we always match
if (matchGroups.isEmpty())
return new MatchResult(MatchResult.MATCH);
// there are specific matching elements, so prepare to iterate
// through the list
Iterator it = matchGroups.iterator();
Status firstIndeterminateStatus = null;
// in order for this section to match, one of the groups must match
while (it.hasNext()) {
// get the next group and try matching it
TargetMatchGroup group = (TargetMatchGroup)(it.next());
MatchResult result = group.match(context);
// we only need one match, so if this matched, then we're done
if (result.getResult() == MatchResult.MATCH)
return result;
// if we didn't match then it was either a NO_MATCH or
// INDETERMINATE...in the second case, we need to remember
// it happened, 'cause if we don't get a MATCH, then we'll
// be returning INDETERMINATE
if (result.getResult() == MatchResult.INDETERMINATE) {
if (firstIndeterminateStatus == null)
firstIndeterminateStatus = result.getStatus();
}
}
// if we got here, then none of the sub-matches passed, so
// we have to see if we got any INDETERMINATE cases
if (firstIndeterminateStatus == null)
return new MatchResult(MatchResult.NO_MATCH);
else
return new MatchResult(MatchResult.INDETERMINATE,
firstIndeterminateStatus);
}
/**
* Encodes this <code>TargetSection</code> into its XML representation
* and writes this encoding to the given <code>OutputStream</code> with
* no indentation.
*
* @param output a stream into which the XML-encoded data is written
*/
public void encode(OutputStream output) {
...
[truncated message content] |