Initial commit.
This commit is contained in:
parent
deb8052f73
commit
4b74eca03f
|
@ -0,0 +1,198 @@
|
|||
/* Copyright 2012-2015 SAP SE
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package eu.aniketos.securebpmn.xacml.finder;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNNodeKind;
|
||||
import org.tmatesoft.svn.core.SVNProperties;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
|
||||
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCUtil;
|
||||
|
||||
public class MySVNClient {
|
||||
private SVNRepository repository;
|
||||
private String svn_url, username, password;
|
||||
private long version;
|
||||
|
||||
private Logger logger = Logger.getLogger(MySVNClient.class);
|
||||
|
||||
public static final String COMMIT_VERSION = "svn:entry:committed-rev",
|
||||
COMMIT_DATE = "svn:entry:committed-date",
|
||||
VERION = "svn:entry:revision";
|
||||
|
||||
|
||||
public MySVNClient(String svn_url, String username, String password, long version) {
|
||||
this.svn_url = svn_url;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.version = version;
|
||||
init();
|
||||
}
|
||||
|
||||
public MySVNClient(List<String> args) {
|
||||
if ( args.size() < 3 ) {
|
||||
throw new RuntimeException("Missing parameters for " + this.getClass().toString());
|
||||
} else {
|
||||
svn_url = args.get(0);
|
||||
username = args.get(1);
|
||||
password = args.get(2);
|
||||
|
||||
version = -1;
|
||||
|
||||
if ( args.size() >= 4 ) {
|
||||
try {
|
||||
version = Integer.parseInt(args.get(3));
|
||||
} catch(NumberFormatException e) {
|
||||
logger.warn("Could not retreive int value from " + args.get(3) + ", using -1 as default");
|
||||
}
|
||||
}
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
// String svn_url, String username, String password, int version
|
||||
private void init() {
|
||||
logger.info("Creating MySVNClient for svn " + svn_url + ", username " + username + ", password " + password.replaceAll(".", "\\*"));
|
||||
|
||||
DAVRepositoryFactory.setup( );
|
||||
SVNURL url;
|
||||
try {
|
||||
url = SVNURL.parseURIDecoded(svn_url);
|
||||
repository = SVNRepositoryFactory.create( url );
|
||||
|
||||
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager( username , password );
|
||||
repository.setAuthenticationManager( authManager );
|
||||
} catch (SVNException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public long getCheckinSVNVersion(String svn_path) {
|
||||
|
||||
SVNProperties props = new SVNProperties();
|
||||
try {
|
||||
repository.getFile(svn_path, version, props, null);
|
||||
return Long.parseLong(props.getStringValue(COMMIT_VERSION));
|
||||
} catch (SVNException e) {
|
||||
logger.error("Could not retreive file infos for " + svn_path + ": " + e.getMessage(), e);
|
||||
return -1;
|
||||
} catch (NumberFormatException e) {
|
||||
logger.warn("Could not transform committed revision " + props.getStringValue("svn:entry:committed-rev") + " to a long value");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public long getSVNVersion(String svn_path) {
|
||||
|
||||
SVNProperties props = new SVNProperties();
|
||||
try {
|
||||
repository.getFile(svn_path, version, props, null);
|
||||
return Long.parseLong(props.getStringValue(VERION));
|
||||
} catch (SVNException e) {
|
||||
logger.error("Could not retreive file infos for " + svn_path + ": " + e.getMessage(), e);
|
||||
return -1;
|
||||
} catch (NumberFormatException e) {
|
||||
logger.warn("Could not transform committed revision " + props.getStringValue("svn:entry:committed-rev") + " to a long value");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public long downloadFile(String svn_path, String local_path) throws SVNException, IOException {
|
||||
SVNNodeKind nodeKind = repository.checkPath(svn_path, version);
|
||||
|
||||
if ( nodeKind == SVNNodeKind.FILE ) {
|
||||
SVNProperties props = new SVNProperties();
|
||||
FileOutputStream fOS = new FileOutputStream(new File(local_path));
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
long updated = repository.getFile(svn_path, version, props, fOS);
|
||||
buffer.flush();
|
||||
buffer.close();
|
||||
try {
|
||||
updated = Long.parseLong(props.getStringValue(COMMIT_VERSION));
|
||||
} catch (NumberFormatException e) {
|
||||
logger.warn("Could not transform committed revision " + props.getStringValue("svn:entry:committed-rev") + " to a long value");
|
||||
}
|
||||
return updated;
|
||||
} else {
|
||||
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.BAD_FILENAME, "requested file " + svn_path + " is not a file"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getTextFile(String name) throws SVNException {
|
||||
return getTextFile(name, this.version, null, null);
|
||||
}
|
||||
|
||||
public String getTextFile(String name, int version) throws SVNException {
|
||||
return getTextFile(name, version, null, null);
|
||||
}
|
||||
|
||||
public String getTextFile(String name, long version, SVNProperties props, ByteArrayOutputStream buffer) throws SVNException {
|
||||
if ( logger.isDebugEnabled() ) {
|
||||
logger.debug("Try to retreive file " + repository.getLocation().toString() + "/" + name + " in version " + version);
|
||||
}
|
||||
SVNNodeKind nodeKind = repository.checkPath(name, version );
|
||||
|
||||
if ( nodeKind == SVNNodeKind.FILE ) {
|
||||
if ( buffer == null ) {
|
||||
buffer = new ByteArrayOutputStream();
|
||||
} else {
|
||||
buffer.reset();
|
||||
}
|
||||
long revision = repository.getFile( name , version , props , buffer );
|
||||
if ( logger.isDebugEnabled() ) {
|
||||
logger.debug("got " + name + " in revision " + revision);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
} else {
|
||||
logger.error("URL \"" + svn_url + "/" + name + "\" does not point to a file or does not exist");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getSvn_url() {
|
||||
return svn_url;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
/* Copyright 2012-2015 SAP SE
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package eu.aniketos.securebpmn.xacml.finder;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNProperties;
|
||||
|
||||
import eu.aniketos.securebpmn.xacml.SVNPDPConfig;
|
||||
import eu.aniketos.securebpmn.xacml.support.finder.FilePolicyModule;
|
||||
|
||||
import com.sun.xacml.AbstractPolicy;
|
||||
import com.sun.xacml.PDPConfig;
|
||||
import com.sun.xacml.ParsingException;
|
||||
import com.sun.xacml.finder.PolicyFinder;
|
||||
import com.sun.xacml.support.finder.PolicyReader;
|
||||
|
||||
public class SVNPolicyFinderModule extends FilePolicyModule {
|
||||
|
||||
|
||||
protected String svn_url;
|
||||
protected long version;
|
||||
|
||||
private static Logger logger = Logger.getLogger(SVNPolicyFinderModule.class);
|
||||
|
||||
public static final String XACML_FOLDER = "xacml";
|
||||
|
||||
protected MySVNClient svn;
|
||||
|
||||
public SVNPolicyFinderModule(List<String> args) {
|
||||
super(args);
|
||||
}
|
||||
|
||||
|
||||
public SVNPolicyFinderModule(String svn_url, String username, String password, int version) {
|
||||
svn = new MySVNClient(svn_url, username, password, version);
|
||||
}
|
||||
|
||||
public SVNPolicyFinderModule(MySVNClient svnClient) {
|
||||
svn = svnClient;
|
||||
}
|
||||
|
||||
public SVNPolicyFinderModule() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void init(PolicyFinder finder) {
|
||||
|
||||
logger.debug("Initializing SVNPolicyFinderModule");
|
||||
|
||||
svnInit(finder);
|
||||
|
||||
this.svn_url = svn.getSvn_url();
|
||||
this.version = svn.getVersion();
|
||||
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
List<String> policyFiles = null;
|
||||
try {
|
||||
policyFiles = getPolicyFileNames(version, buffer);
|
||||
} catch (SVNException e) {
|
||||
logger.error("SVNException when reading file " + SVNPDPConfig.POLICY_FILE + " from repository: " + e.getMessage() + ", will not be able to retrieve policies from SVN storage");
|
||||
policyFiles = new Vector<String>();
|
||||
}
|
||||
|
||||
List<AbstractPolicy> policies = getPolicies(finder, policyFiles, version, buffer);
|
||||
for ( AbstractPolicy policy : policies ) {
|
||||
super.addPolicy(policy);
|
||||
}
|
||||
// svn client is not required any more, release resources locally
|
||||
svn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does some initialization of for a SVN finder, i.e., getting
|
||||
* a SVN client and setting other parameters such as useLines
|
||||
* @param finder
|
||||
*/
|
||||
protected void svnInit(PolicyFinder finder) {
|
||||
PDPConfig pdpConfig = finder.getPDPConfiguration();
|
||||
|
||||
// if we did not get the svn client with the constructor
|
||||
if ( svn != null ) {
|
||||
svn = getSVNClient(pdpConfig, finder);
|
||||
}
|
||||
|
||||
pdpConfig.setCustomAttr(SVNPDPConfig.SVN_CLIENT, svn);
|
||||
|
||||
//check if we have to use lines parser
|
||||
if ( super.enf_useLines ) {
|
||||
useLines = true;
|
||||
}
|
||||
// check use lines configuration
|
||||
else if ( confParams.containsKey(CONF_USELINES)) {
|
||||
useLines = getBool(confParams.get(CONF_USELINES));
|
||||
logger.debug("Use lines: " + useLines + " (loaded from FinderModule configuration)");
|
||||
} else if ( pdpConfig.getCustomAttr(CONF_USELINES) != null ) {
|
||||
useLines = getBool( (String) pdpConfig.getCustomAttr(CONF_USELINES));
|
||||
logger.debug("Use lines: " + useLines + " (loaded from PDP wide configuration)");
|
||||
}
|
||||
}
|
||||
|
||||
protected MySVNClient getSVNClient(PDPConfig pdpConfig, PolicyFinder finder) {
|
||||
|
||||
// first, check if there is a local configuration
|
||||
List<String> confArgs = null;
|
||||
if ( confParams.containsKey(SVNPDPConfig.SVN_URL) && confParams.containsKey(SVNPDPConfig.USERNAME) &&
|
||||
confParams.containsKey(SVNPDPConfig.PASSWORD) ) {
|
||||
confArgs = new Vector<String>();
|
||||
confArgs.add(confParams.get(SVNPDPConfig.SVN_URL));
|
||||
confArgs.add(confParams.get(SVNPDPConfig.USERNAME));
|
||||
confArgs.add(confParams.get(SVNPDPConfig.PASSWORD));
|
||||
if (confParams.get(SVNPDPConfig.VERSION) != null ) {
|
||||
confArgs.add(confParams.get(SVNPDPConfig.VERSION));
|
||||
}
|
||||
logger.info("Loading SVN configuration from FinderModule configuration: " +
|
||||
confParams.get(SVNPDPConfig.SVN_URL) +" in version " + confParams.get(SVNPDPConfig.VERSION));
|
||||
}
|
||||
// check if we can reuse an existing client
|
||||
else if (pdpConfig.getCustomAttr(SVNPDPConfig.SVN_CLIENT) != null) {
|
||||
MySVNClient client = (MySVNClient) pdpConfig.getCustomAttr(SVNPDPConfig.SVN_CLIENT);
|
||||
logger.info("Using PDP wide SVN client and configuration: " + svn.getSvn_url() +
|
||||
" in version " + svn.getVersion());
|
||||
return client;
|
||||
}
|
||||
// check if there is a pdp wide svn configuration
|
||||
else if (pdpConfig.getCustomAttr(SVNPDPConfig.SVN_URL) != null && pdpConfig.getCustomAttr(SVNPDPConfig.USERNAME) != null &&
|
||||
pdpConfig.getCustomAttr(SVNPDPConfig.PASSWORD) != null ) {
|
||||
confArgs = new Vector<String>();
|
||||
confArgs.add( (String) pdpConfig.getCustomAttr(SVNPDPConfig.SVN_URL));
|
||||
confArgs.add( (String) pdpConfig.getCustomAttr(SVNPDPConfig.USERNAME));
|
||||
confArgs.add( (String) pdpConfig.getCustomAttr(SVNPDPConfig.PASSWORD));
|
||||
if ( pdpConfig.getCustomAttr(SVNPDPConfig.VERSION) != null ) {
|
||||
confArgs.add( (String) pdpConfig.getCustomAttr(SVNPDPConfig.VERSION));
|
||||
}
|
||||
logger.info("Loading SVN configuration from PDP wide configuration: " +
|
||||
pdpConfig.getCustomAttr(SVNPDPConfig.SVN_URL) +" in version " + pdpConfig.getCustomAttr(SVNPDPConfig.VERSION));
|
||||
} else {
|
||||
logger.fatal("No configuration for SVN access found; No policies will be loaded");
|
||||
}
|
||||
|
||||
if (confArgs != null ) {
|
||||
return new MySVNClient(confArgs);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected List<String> getPolicyFileNames(long version, ByteArrayOutputStream buffer) throws SVNException {
|
||||
List<String> fileNames = new Vector<String>();
|
||||
|
||||
String policiesFile = svn.getTextFile(XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE, version, null, buffer);
|
||||
if ( policiesFile == null ) {
|
||||
logger.error("Could not find policies file (" + svn_url + "/" + XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE);
|
||||
throw new RuntimeException("Could not find policies file (" + svn_url + "/" + XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE);
|
||||
}
|
||||
|
||||
BufferedReader reader = new BufferedReader(new StringReader(policiesFile));
|
||||
try {
|
||||
String filePolicy = null;
|
||||
while ( (filePolicy = reader.readLine()) != null ) {
|
||||
if ( ! ( filePolicy.startsWith("#") || filePolicy.length() == 0) ) {
|
||||
fileNames.add(filePolicy.trim());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// must not happen as stream is got from a string...
|
||||
}
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
protected List<AbstractPolicy> getPolicies(PolicyFinder finder,
|
||||
List<String> policyFileNames, long version, ByteArrayOutputStream buffer) {
|
||||
List<AbstractPolicy> policies = new Vector<AbstractPolicy>();
|
||||
|
||||
SVNProperties props = new SVNProperties();
|
||||
PolicyReader reader = new PolicyReader(finder,
|
||||
java.util.logging.Logger.getLogger(this.getClass().getName()), null);
|
||||
if ( buffer == null ) {
|
||||
buffer = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
for ( String policyFile : policyFileNames ) {
|
||||
String policy;
|
||||
try {
|
||||
policy = svn.getTextFile(XACML_FOLDER + "/" + policyFile, version, props, buffer);
|
||||
|
||||
if ( policy == null ) {
|
||||
logger.error("Could not retreive " + policyFile + " from SVN repository. WARNING: This policy will not be loaded");
|
||||
} else {
|
||||
policies.add(reader.readPolicy(new ByteArrayInputStream(policy.getBytes())));
|
||||
logger.info("Loaded policies from " + policyFile + " (checked in with version " +
|
||||
props.getStringValue(MySVNClient.COMMIT_VERSION) + " on " +
|
||||
props.getStringValue(MySVNClient.COMMIT_DATE) + ")"); //
|
||||
props.clear();
|
||||
}
|
||||
} catch (SVNException e) {
|
||||
logger.error("SVN Error at retreiving " + policyFile + ": " + e.getMessage() + ". WARNING: This policy will not be loaded");
|
||||
} catch (ParsingException e) {
|
||||
logger.error("ParsingException at parsing " + policyFile + ": " + e.getMessage() + ". WARNING: This policy will not be loaded");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return policies;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// try {
|
||||
// String policiesFile = svn.getTextFile(XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE, version, props, buffer);
|
||||
//
|
||||
// if ( policiesFile == null ) {
|
||||
// logger.error("Could not find policies file (" + svn_url + "/" + XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE);
|
||||
// throw new RuntimeException("Could not find policies file (" + svn_url + "/" + XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE);
|
||||
// }
|
||||
//
|
||||
// BufferedReader reader = new BufferedReader(new StringReader(policiesFile));
|
||||
//
|
||||
//
|
||||
// String filePolicy = null;
|
||||
// try {
|
||||
// while ( (filePolicy = reader.readLine()) != null ) {
|
||||
// if ( ! ( filePolicy.startsWith("#") || filePolicy.length() == 0) ) {
|
||||
// policyFiles.add(filePolicy.trim());
|
||||
// }
|
||||
// }
|
||||
// } catch (IOException e) {
|
||||
// logger.error("IOExeption when reading file " + SVNPDPConfig.POLICY_FILE + " from repository: " + e.getMessage());
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// } catch (SVNException e) {
|
||||
// logger.error("SVNException when reading file " + SVNPDPConfig.POLICY_FILE + " from repository: " + e.getMessage());
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
// SVNProperties props = new SVNProperties();
|
||||
// PolicyReader reader = new PolicyReader(finder,
|
||||
// java.util.logging.Logger.getLogger(this.getClass().getName()), null);
|
||||
//
|
||||
// for ( String policyFile : policyFiles ) {
|
||||
// String policy;
|
||||
// try {
|
||||
// policy = svn.getTextFile(XACML_FOLDER + "/" + policyFile, version, props, buffer);
|
||||
//
|
||||
// if ( policy == null ) {
|
||||
// logger.error("Could not retreive " + policyFile + " from SVN repository. WARNING: This policy will not be loaded");
|
||||
// } else {
|
||||
// super.addPolicy(reader.readPolicy(new ByteArrayInputStream(policy.getBytes())));
|
||||
// logger.info("Loaded policies from " + policyFile + " (checked in with version " +
|
||||
// props.getStringValue(MySVNClient.COMMIT_VERSION) + " on " +
|
||||
// props.getStringValue(MySVNClient.COMMIT_DATE) + ")"); //
|
||||
// props.clear();
|
||||
// }
|
||||
// } catch (SVNException e) {
|
||||
// logger.error("SVN Error at retreiving " + policyFile + ": " + e.getMessage() + ". WARNING: This policy will not be loaded");
|
||||
// } catch (ParsingException e) {
|
||||
// logger.error("ParsingException at parsing " + policyFile + ": " + e.getMessage() + ". WARNING: This policy will not be loaded");
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// private void checkForConfig() {
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
/* Copyright 2012-2015 SAP SE
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package eu.aniketos.securebpmn.xacml.finder;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
|
||||
import eu.aniketos.securebpmn.xacml.SVNPDPConfig;
|
||||
import eu.aniketos.securebpmn.xacml.support.finder.IPDPStateEvaluationContext;
|
||||
|
||||
import com.sun.xacml.AbstractPolicy;
|
||||
import com.sun.xacml.EvaluationCtx;
|
||||
import com.sun.xacml.PolicyMetaData;
|
||||
import com.sun.xacml.VersionConstraints;
|
||||
import com.sun.xacml.ctx.Status;
|
||||
import com.sun.xacml.finder.PolicyFinder;
|
||||
import com.sun.xacml.finder.PolicyFinderResult;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class retrieves, in contrast to the super class SVNPolicyFinderModule,
|
||||
* the information which svn version to use from the context, which has to be
|
||||
* a IPDPStateEvaluationContext. For this, a "main" instance manages all "sub"
|
||||
* instances which hold a specific version.
|
||||
* <br/>
|
||||
* This class may be enhanced for productive usage, i.e., check if a new policy
|
||||
* version will become active in a specific time frame, remove policies which will
|
||||
* not be used any more from the cache, allow to trigger a load operation to
|
||||
* circumvent delays for requests first using a new policy version.
|
||||
*
|
||||
*/
|
||||
public class SVNStatePolicyFinderModule extends SVNPolicyFinderModule {
|
||||
|
||||
/*
|
||||
* there typ "types" of this class: the main instance manages
|
||||
* all sub instances, i.e., a instance has either the policyCache
|
||||
* or the version set to a reasonable value
|
||||
*/
|
||||
private Map<Long, SVNStatePolicyFinderModule> policyCache = null;
|
||||
private PolicyFinder finder;
|
||||
|
||||
private long version = -1;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SVNStatePolicyFinderModule.class);
|
||||
|
||||
|
||||
@Override
|
||||
public void init(PolicyFinder finder) {
|
||||
logger.debug("Creating " + SVNStatePolicyFinderModule.class.getSimpleName() + " as main instance");
|
||||
this.finder = finder;
|
||||
policyCache = new HashMap<Long, SVNStatePolicyFinderModule>();
|
||||
// do the init, e.g., get svn client
|
||||
super.svnInit(finder);
|
||||
}
|
||||
|
||||
|
||||
protected synchronized SVNStatePolicyFinderModule loadVersion(Long version) {
|
||||
if ( policyCache.containsKey(version)) {
|
||||
return policyCache.get(version);
|
||||
} else {
|
||||
SVNStatePolicyFinderModule module = new SVNStatePolicyFinderModule(finder, svn, version.longValue());
|
||||
policyCache.put(version, module);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected SVNStatePolicyFinderModule(PolicyFinder finder, MySVNClient client, long version) {
|
||||
logger.debug("Creating " + SVNStatePolicyFinderModule.class.getSimpleName() + " as sub instance");
|
||||
super.svn = client;
|
||||
|
||||
super.svnInit(finder);
|
||||
// create a buffer which can be used for all coming read operations
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
List<String> policyFileNames = null;
|
||||
try {
|
||||
policyFileNames = super.getPolicyFileNames(version, buffer);
|
||||
} catch (SVNException e) {
|
||||
logger.error("SVNException when reading file " + SVNPDPConfig.POLICY_FILE + " from repository: " + e.getMessage() + ", will not be able to retrieve policies from SVN storage");
|
||||
policyFileNames = new Vector<String>();
|
||||
}
|
||||
|
||||
List<AbstractPolicy> policies = getPolicies(finder, policyFileNames, version, buffer);
|
||||
for ( AbstractPolicy policy : policies ) {
|
||||
super.addPolicy(policy);
|
||||
}
|
||||
super.svn = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PolicyFinderResult findPolicy(EvaluationCtx context) {
|
||||
// check if we are the "main" finder which manages the policy cache
|
||||
if ( policyCache != null ) {
|
||||
if ( context instanceof IPDPStateEvaluationContext ) {
|
||||
IPDPStateEvaluationContext stateContext = (IPDPStateEvaluationContext) context;
|
||||
|
||||
SVNStatePolicyFinderModule module = policyCache.get(new Long(stateContext.getVersion()));
|
||||
if ( module == null ) {
|
||||
module = loadVersion(new Long(version));
|
||||
}
|
||||
return module.findPolicy(context);
|
||||
} else {
|
||||
return new PolicyFinderResult(Status.createStatus(Status.STATUS_PROCESSING_ERROR, "SVNStatePolicyFinderModule requires IPDPStateEvaluationContext"));
|
||||
}
|
||||
} else {
|
||||
// we are a "sub" finder, i.e., we can use our super class impl to find what we neeed
|
||||
return super.findPolicy(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PolicyFinderResult findPolicy(EvaluationCtx context,
|
||||
URI idReference, int type,
|
||||
VersionConstraints constraints,
|
||||
PolicyMetaData parentMetaData) {
|
||||
|
||||
// check if we are the "main" finder which manages the policy cache
|
||||
if ( policyCache != null ) {
|
||||
// we do not need to do checks any more - they must have been failed when searching the main policy
|
||||
return policyCache.get(new Long( ((IPDPStateEvaluationContext) context).getVersion())).
|
||||
findPolicy(context, idReference, type, constraints, parentMetaData);
|
||||
} else {
|
||||
return super.findPolicy(context, idReference, type, constraints, parentMetaData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// private long getCurrentPolicyVersion(AttributeFinder finder) {
|
||||
// try {
|
||||
// BasicEvaluationCtx ctx = new BasicEvaluationCtx(new RequestCtx(new HashSet<RequestElement>(), null, null));
|
||||
// EvaluationResult evalResult = finder.findAttribute(Constants.ENVIRONMENT_CAT, TypeIdentifierConstants.INTEGER_URI, PDPSTATE_URI, null, ctx);
|
||||
//
|
||||
// return getCurrentPolicyVersion(evalResult);
|
||||
// } catch (IllegalArgumentException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (ParsingException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// public static long getCurrentPolicyVersion(EvaluationCtx context) {
|
||||
// return getCurrentPolicyVersion(
|
||||
// context.getAttribute(
|
||||
// Constants.ENVIRONMENT_CAT, TypeIdentifierConstants.INTEGER_URI, PDPSTATE_URI, null));
|
||||
// }
|
||||
//
|
||||
// private static long getCurrentPolicyVersion(EvaluationResult evalResult) {
|
||||
// if ( !evalResult.getAttributeValue().isBag() ||
|
||||
// ((BagAttribute) evalResult.getAttributeValue()).size() != 1 ) {
|
||||
// logger.error("Did not retreive a bag with one (" +((BagAttribute) evalResult.getAttributeValue()).size() +
|
||||
// ") entry after attribute search for current svn policy version number " +
|
||||
// "SVNStatePolicyFinderModule requires exactly one attribute to be defined");
|
||||
// return -1;
|
||||
// }
|
||||
// IntegerAttribute attrVal = (IntegerAttribute) ((BagAttribute) evalResult.getAttributeValue()).iterator().next();
|
||||
//
|
||||
// return attrVal.getValue();
|
||||
// }
|
||||
//
|
||||
|
||||
//TODO create policy cache
|
||||
// get policies in correct version from policy cache - key is svn ID
|
||||
//
|
||||
// TODO create a time stamp for when the active policy version was checked
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* Copyright 2012-2015 SAP SE
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package eu.aniketos.securebpmn.xacml.finder.impl;
|
||||
|
||||
import com.sun.xacml.finder.AttributeFinderModule;
|
||||
|
||||
/**
|
||||
* retreives information
|
||||
*
|
||||
*/
|
||||
public class PDPStateModule extends AttributeFinderModule {
|
||||
|
||||
// role
|
||||
// relationship
|
||||
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
/* Copyright 2012-2015 SAP SE
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package eu.aniketos.securebpmn.xacml.finder.impl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
|
||||
import eu.aniketos.securebpmn.xacml.SVNPDPConfig;
|
||||
import eu.aniketos.securebpmn.xacml.finder.MySVNClient;
|
||||
import eu.aniketos.securebpmn.xacml.finder.SVNPolicyFinderModule;
|
||||
|
||||
import com.sun.xacml.ConfigurationStore;
|
||||
import com.sun.xacml.Constants;
|
||||
import com.sun.xacml.EvaluationCtx;
|
||||
import com.sun.xacml.attr.AttributeValue;
|
||||
import com.sun.xacml.attr.BagAttribute;
|
||||
import com.sun.xacml.attr.StringAttribute;
|
||||
import com.sun.xacml.attr.TypeIdentifierConstants;
|
||||
import com.sun.xacml.cond.EvaluationResult;
|
||||
import com.sun.xacml.finder.AttributeFinderModule;
|
||||
|
||||
/**
|
||||
*
|
||||
* This module selects a bag of roles which are assigned
|
||||
* to the subject in the current evaluation context.
|
||||
* The role assignment is read from a configuration
|
||||
* file roles.config at startup of the PDP. This is
|
||||
* intended for simple tests, for a more sohpisticated
|
||||
* setup use PDPStateModule which retrieves the current
|
||||
* state of the assignment from a database at runtime.
|
||||
*
|
||||
*/
|
||||
public class RoleFinderFileModule extends AttributeFinderModule {
|
||||
|
||||
public static final String USER_ROLES = "subject-roles",
|
||||
CONFIG_FILE = "roles.config";
|
||||
|
||||
|
||||
public static final URI USER_ROLES_URI = URI.create(USER_ROLES);
|
||||
|
||||
private Map<String, Collection<AttributeValue>> roleAssignments;
|
||||
|
||||
private ConfigurationStore conf;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(RoleFinderFileModule.class);
|
||||
|
||||
public RoleFinderFileModule() {
|
||||
// roleAssignments = readConfig(
|
||||
// "burli:Role1;MasterGuru;UseCaseCaptain\n" +
|
||||
// "maxi:fuzzi;Ruzzi;bulli\n" +
|
||||
// "\n" +
|
||||
// " \n" +
|
||||
// "root:Role1;MasterGuru;Nurse;asdf"
|
||||
// );
|
||||
}
|
||||
|
||||
|
||||
public boolean isDesignatorSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void setConfigurationStore(ConfigurationStore conf) {
|
||||
this.conf = conf;
|
||||
if (this.conf != null) {
|
||||
String config = null;
|
||||
//check, if there is a svn client
|
||||
MySVNClient svn = (MySVNClient) conf.getCustomAttr(SVNPDPConfig.SVN_CLIENT);
|
||||
|
||||
if ( svn != null ) {
|
||||
try {
|
||||
roleAssignments = readConfig(svn.getTextFile(SVNPolicyFinderModule.XACML_FOLDER + "/" + CONFIG_FILE));
|
||||
} catch (SVNException e) {
|
||||
logger.error("Could not retreive " + CONFIG_FILE + " for role configuration from SVN storage");
|
||||
}
|
||||
} else
|
||||
|
||||
//if there is no config from the svn
|
||||
if ( config == null ) {
|
||||
String baseDir = conf.getBaseDir();
|
||||
File confFile = new File(baseDir + CONFIG_FILE);
|
||||
logger.debug("Try to load role configuration from file: " + confFile.getAbsolutePath() + " (baseDir: " + baseDir + ")");
|
||||
if ( confFile.exists() ) {
|
||||
try {
|
||||
roleAssignments = readConfig(new InputStreamReader(new FileInputStream(confFile)));
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.error("File (role configuration) not found: " + confFile.getAbsolutePath() + ": " + e.getMessage(), e);
|
||||
}
|
||||
} else {
|
||||
logger.error("File (role configuration) not found: " + confFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.error("Did not retreive a valid configuration!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Collection<AttributeValue>> readConfig(Reader in) {
|
||||
|
||||
Map<String, Collection<AttributeValue>> roleConfig
|
||||
= new HashMap<String, Collection<AttributeValue>>();
|
||||
BufferedReader reader = new BufferedReader(in);
|
||||
|
||||
String line = null, user, roles;
|
||||
try {
|
||||
for ( int i = 0; (line = reader.readLine()) != null ; ++i) {
|
||||
if ( line.startsWith("#") || line.trim().length() == 0) {
|
||||
//ignore comments;
|
||||
continue;
|
||||
}
|
||||
int a = line.indexOf(":");
|
||||
if ( a < 1 ) {
|
||||
logger.warn("Error in line " + i + ": Did not find \":\"");
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
user = line.substring(0, a).trim();
|
||||
roles = line.substring(a + 1, line.length());
|
||||
StringTokenizer tokenizer = new StringTokenizer(roles, ";");
|
||||
Collection<AttributeValue> tmpCol = new Vector<AttributeValue>();
|
||||
|
||||
while ( tokenizer.hasMoreElements()) {
|
||||
tmpCol.add(StringAttribute.getInstance(tokenizer.nextToken().trim()));
|
||||
}
|
||||
roleConfig.put(user, tmpCol);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return roleConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* helper function to read the configuration and save it into the local map
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
private Map<String, Collection<AttributeValue>> readConfig(String config) {
|
||||
return readConfig(new StringReader(config));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EvaluationResult findAttribute(URI category, URI attributeType,
|
||||
URI attributeId, URI issuer,
|
||||
EvaluationCtx context) {
|
||||
|
||||
if ( USER_ROLES_URI.equals(attributeId) &&
|
||||
TypeIdentifierConstants.STRING_URI.equals(attributeType) ) {
|
||||
String user = getUserID(context);
|
||||
if ( user == null || roleAssignments.get(user) == null
|
||||
|| roleAssignments.get(user).size() == 0 ) {
|
||||
logger.warn("Found no role assignments for user " + user);
|
||||
} else {
|
||||
return new EvaluationResult(new BagAttribute(attributeType, roleAssignments.get(user)));
|
||||
}
|
||||
}
|
||||
// if found nothing or not responsible, return empty bag
|
||||
return new EvaluationResult(BagAttribute.createEmptyBag(attributeType));
|
||||
}
|
||||
|
||||
|
||||
private String getUserID(EvaluationCtx context) {
|
||||
|
||||
// if ( context instanceof AttrCachingEvaluationCtx ) {
|
||||
// AttrCachingEvaluationCtx c_context = (AttrCachingEvaluationCtx) context;
|
||||
// }
|
||||
|
||||
// if ( context instanceof EvaluationIdContext )
|
||||
// more efficient impl
|
||||
// else get "classical"
|
||||
|
||||
// if user == null
|
||||
//logger.warn("Could not retreive the subject-id from the current context");
|
||||
|
||||
EvaluationResult result = context.getAttribute(Constants.SUBJECT_CAT, TypeIdentifierConstants.STRING_URI,
|
||||
Constants.SUBJECT_ID, null);
|
||||
|
||||
if (! result.getAttributeValue().isBag()) {
|
||||
logger.error("Did not retreive a bag after attribute search");
|
||||
return null;
|
||||
} else {
|
||||
Iterator<AttributeValue> it = ((BagAttribute) result.getAttributeValue()).iterator();
|
||||
String firstUser = null;
|
||||
for ( int i = 0; it.hasNext(); ++i) {
|
||||
String user = ((StringAttribute)it.next()).getValue();
|
||||
if ( i > 0) {
|
||||
logger.warn("Retreived more than subjectID: " + user + " which will be ignored");
|
||||
} else {
|
||||
firstUser = user;
|
||||
}
|
||||
}
|
||||
return firstUser;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue