This repository has been archived on 2018-08-08. You can view files and clone it, but cannot push or open issues or pull requests.
SecureBPMN/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/FilePolicyModule.java

329 lines
12 KiB
Java

/*
* @(#)FilePolicyModule.java
*
* Copyright 2003-2006 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.support.finder;
import com.sun.xacml.AbstractPolicy;
import com.sun.xacml.ConfigurationStore;
import com.sun.xacml.EvaluationCtx;
import com.sun.xacml.ParsingException;
import com.sun.xacml.finder.PolicyFinder;
import com.sun.xacml.finder.PolicyFinderModule;
import com.sun.xacml.finder.PolicyFinderResult;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This module represents a collection of files containing polices,
* each of which will be searched through when trying to find a
* policy that is applicable to a specific request. It does not support
* policy references.
* <p>
* Note that this class used to be provided in the
* <code>com.sun.xacml.finder.impl</code> package with a warning that it
* would move out of the core packages eventually. This is partly because
* this class doesn't represent standard functionality, and partly because
* it isn't designed to be generally useful as anything more than an
* example. Because so many people have used this class, however, it stayed
* in place until the 2.0 release.
* <p>
* As of the 2.0 release, you may still use this class (in its new location),
* but you are encouraged to migrate to the new support modules that are
* much richer and designed for general-purpose use. Also, note that the
* <code>loadPolicy</code> methods that used to be available from this class
* have been removed. That functionality has been replaced by the much more
* useful <code>PolicyReader</code> class. If you need to load policies
* directly, you should consider that new class.
*
* @since 1.0
* @author Seth Proctor
*/
public class FilePolicyModule extends PolicyFinderModule {
// the schema file we're using, if any
private File schemaFile = null;
// the filenames for the files we'll load
private Set<String> fileNames;
// the actual loaded policies
protected PolicyCollection policies;
// the logger we'll use for all messages
private static final Logger logger =
Logger.getLogger(FilePolicyModule.class.getName());
// configuration: keep track of lines when loadig policies (slow! use only for debugging!)
protected boolean useLines = false, enf_useLines = false;
protected Map<String, String> confParams = new HashMap<String, String>();
protected static final String CONF_PREFIX = "conf:",
FILE_PREFIX = "file:",
CONF_USELINES = "useLines";
/**
* Constructor which retrieves the schema file to validate policies against
* from the <code>PolicyReader.POLICY_SCHEMA_PROPERTY</code>. If the
* retrieved property is null, then no schema validation will occur.
*/
public FilePolicyModule() {
this.fileNames = new HashSet<String>();
this.policies = new PolicyCollection();
String schemaName =
System.getProperty(PolicyReader.POLICY_SCHEMA_PROPERTY);
if (schemaName != null) {
this.schemaFile = new File(schemaName);
}
}
/**
* Constructor that uses the specified <code>File</code> as the schema
* file for XML validation. If schema validation is not desired, a null
* value should be used.
*
* @param schemaFile the schema file to validate policies against,
* or null if schema validation is not desired.
*/
public FilePolicyModule(File schemaFile) {
this.fileNames = new HashSet<String>();
this.policies = new PolicyCollection();
this.schemaFile = schemaFile;
}
/**
* Constructor that uses the specified <code>String</code> as the schema
* file for XML validation. If schema validation is not desired, a null
* value should be used.
*
* @param schemaFile the schema file to validate policies against,
* or null if schema validation is not desired.
*/
public FilePolicyModule(String schemaFile) {
this((schemaFile != null) ? new File(schemaFile) : null);
}
/**
* Constructor that specifies a set of initial policy files to use. This
* retrieves the schema file to validate policies against from the
* <code>PolicyReader.POLICY_SCHEMA_PROPERTY</code>. If the retrieved
* property is null, then no schema validation will occur.
*
* @param fileNames a <code>List</code> of <code>String</code>s that
* identify policy files
*/
public FilePolicyModule(List<String> fileNames) {
this();
if (fileNames != null) {
for ( String fileName : fileNames ) {
if ( fileName.startsWith(CONF_PREFIX) ) {
String tmp = fileName.substring(5);
try {
String confId = tmp.substring(0, tmp.indexOf(":"));
String value = tmp.substring(tmp.indexOf(":") + 1);
confParams.put(confId, value);
} catch(Exception e) {
logger.warning("Could not add configuration: " + tmp);
}
} else {
if ( fileName.startsWith(FILE_PREFIX) ) {
this.fileNames.add(fileName.substring(5));
} else {
this.fileNames.add(fileName);
}
}
}
}
if ( enf_useLines ) {
useLines = true;
} else if ( confParams.containsKey(CONF_USELINES)) {
useLines = getBool(confParams.get(CONF_USELINES));
}
}
/**
* Constructor that specifies a set of initial policy files to use and
* the schema file used to validate the policies. If schema validation is
* not desired, a null value should be used.
*
* @param fileNames a <code>List</code> of <code>String</code>s that
* identify policy files
* @param schemaFile the schema file to validate policies against,
* or null if schema validation is not desired.
*/
public FilePolicyModule(List<String> fileNames, String schemaFile) {
this(schemaFile);
if (fileNames != null) {
this.fileNames.addAll(fileNames);
}
}
/**
* Adds a file (containing a policy) to the collection of filenames
* associated with this module. Note that this doesn't actually load the
* policy file. Policies aren't loaded from their files until the
* module is initialized through the <code>init</code> method (which
* is called automatically by the <code>PolicyFinder</code> when the
* system comes up).
*
* @param filename the file to add to this module's collection of files
*
* @return true or false depending on the success of this operation.
*/
public boolean addPolicy(String filename) {
return this.fileNames.add(filename);
}
/**
* Indicates whether this module supports finding policies based on
* a request (target matching). Since this module does support
* finding policies based on requests, it returns true.
*
* @return true, since finding policies based on requests is supported
*/
public boolean isRequestSupported() {
return true;
}
/**
* Initializes the <code>FilePolicyModule</code> by loading
* the policies contained in the collection of files associated
* with this module. This method also uses the specified
* <code>PolicyFinder</code> to help in instantiating PolicySets.
*
* @param finder a PolicyFinder used to help in instantiating PolicySets
*/
public void init(PolicyFinder finder) {
Object o = finder.getPDPConfiguration().getCustomAttr(ConfigurationStore.BASEDIR);
String baseDir = "";
if ( o != null) {
baseDir = (String) o;
}
PolicyReader reader = new PolicyReader(finder, logger,
this.schemaFile, this.useLines);
for (String fname : this.fileNames ) {
try {
AbstractPolicy policy =
reader.readPolicy(new FileInputStream(baseDir + fname), fname);
this.policies.addPolicy(policy);
} catch (FileNotFoundException fnfe) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, "File couldn't be read: "
+ fname, fnfe);
}
} catch (ParsingException pe) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, "Error reading policy from file "
+ fname, pe);
}
}
}
}
/**
* Finds a policy based on a request's context. If more than one
* applicable policy is found, this will return an error. Note that
* this is basically just a subset of the OnlyOneApplicable Policy
* Combining Alg that skips the evaluation step. See comments in there
* for details on this algorithm.
*
* @param context the representation of the request data
*
* @return the result of trying to find an applicable policy
*/
public PolicyFinderResult findPolicy(EvaluationCtx context) {
try {
context.newEvent(this);
AbstractPolicy policy = this.policies.getPolicy(context);
if (policy == null) {
context.closeCurrentEvent();
return new PolicyFinderResult();
}
context.closeCurrentEvent(policy.getId().toString());
return new PolicyFinderResult(policy);
} catch (TopLevelPolicyException tlpe) {
context.closeCurrentEvent();
return new PolicyFinderResult(tlpe.getStatus());
}
}
protected static boolean getBool(String value) {
try {
Boolean val = new Boolean(value);
return val.booleanValue();
} catch (Exception e) {
logger.log(Level.WARNING, "Could not read boolean value " + value + "; Using false as default");
return false;
}
}
/**
* this method can be used to enforce the usage of lines parsing
* programatically
* @param useLines
*/
public void enforceUseLines() {
this.enf_useLines = true;
this.useLines = true;
}
}