Re-added XACML support.
This commit is contained in:
parent
bbe054c1b9
commit
83f41d285c
|
@ -0,0 +1,27 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Activiti Designer - SecureBPMN: XACML Export
|
||||
Bundle-SymbolicName: eu.aniketos.securebpmn.export.xacml;singleton:=true
|
||||
Bundle-Version: 5.8.0
|
||||
Bundle-Activator: eu.aniketos.securebpmn.export.xacml.bundle.Activator
|
||||
Bundle-Vendor: SAP SE
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
org.activiti.designer.eclipse,
|
||||
org.activiti.designer.model,
|
||||
org.activiti.designer.gui,
|
||||
org.eclipse.emf,
|
||||
org.eclipse.graphiti.mm,
|
||||
org.eclipse.graphiti.ui,
|
||||
org.eclipse.core.resources
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Import-Package: eu.aniketos.securebpmn.util,
|
||||
org.activiti.designer.util.preferences
|
||||
Bundle-ClassPath: .,
|
||||
com.sun.xacml-0.1.jar,
|
||||
xalan-2.7.1.jar,
|
||||
serializer-2.7.1.jar,
|
||||
xml-apis-1.3.04.jar,
|
||||
jdi.jar,
|
||||
jdimodel.jar,
|
||||
junit.jar
|
|
@ -0,0 +1,5 @@
|
|||
source.. = src/main/java/
|
||||
bin.includes = META-INF/,\
|
||||
plugin.xml,\
|
||||
.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.6"?>
|
||||
<plugin>
|
||||
<extension point="org.activiti.designer.eclipse.extension.export.ExportMarshaller">
|
||||
<ExportMarshaller class="eu.aniketos.securebpmn.export.xacml.export.XacmlExportMarshaller">
|
||||
</ExportMarshaller>
|
||||
</extension>
|
||||
</plugin>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.activiti.designer</groupId>
|
||||
<artifactId>org.activiti.designer.parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<relativePath>../org.activiti.designer.parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>eu.aniketos.securebpmn.export.xacml</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
<name>Activiti Designer - SecureBPMN: XACML Export</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.sun.xacml</groupId>
|
||||
<artifactId>com.sun.xacml</artifactId>
|
||||
<version>0.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,56 @@
|
|||
/* 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.export.xacml.bundle;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class Activator implements BundleActivator {
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "eu.aniketos.securebpmn.export.xacml"; //$NON-NLS-1$
|
||||
private static BundleContext context;
|
||||
|
||||
static BundleContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
|
||||
* )
|
||||
*/
|
||||
public void start(BundleContext bundleContext) throws Exception {
|
||||
Activator.context = bundleContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext bundleContext) throws Exception {
|
||||
Activator.context = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
/* 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.export.xacml.export;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.securebpmn2.ActivityAction;
|
||||
import org.eclipse.securebpmn2.BindingOfDuty;
|
||||
import org.eclipse.securebpmn2.Permission;
|
||||
|
||||
/**
|
||||
* Creates the ASLan representation of a SecureBPMN BindingOfDuty element.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class BindingOfDutyExport {
|
||||
//
|
||||
// /**
|
||||
// * Generates the ASLan representation of the provided BindingOfDuty element
|
||||
// * and sends the output to the provided AslanFileBuilder.
|
||||
// *
|
||||
// * @param bod
|
||||
// * The BindingOfDuty element for which the representation should
|
||||
// * be generated.
|
||||
// * @param afb
|
||||
// * The AslanFileBuilder the output is sent to.
|
||||
// */
|
||||
// public static void createBindingOfDutyElements(BindingOfDuty bod,
|
||||
// XacmlFileBuilder afb) {
|
||||
//
|
||||
// if (bod.isDynamicEnforcement())
|
||||
// return;
|
||||
//
|
||||
// List<String> assignTasks = new ArrayList<String>();
|
||||
// List<String> claimTasks = new ArrayList<String>();
|
||||
// List<String> completeTasks = new ArrayList<String>();
|
||||
//
|
||||
// for (Permission p : bod.getPermissions()) {
|
||||
//
|
||||
// if (p.getActions().size() == 0) {
|
||||
// System.err
|
||||
// .println("[WARNING] The permission with name=\""
|
||||
// + p.getPName()
|
||||
// + "\" and id=\""
|
||||
// + p.getId()
|
||||
// + "\" has no action. This should never happen! Check your .activiti diagram file.");
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// // Permissions only have one Action
|
||||
// if (p.getActions().get(0) instanceof ActivityAction) {
|
||||
// ActivityAction a = (ActivityAction) p.getActions().get(0);
|
||||
//
|
||||
// if (a.getActionName().equals("Complete")) {
|
||||
//
|
||||
// completeTasks.add(a.getActivity().getId());
|
||||
//
|
||||
// } else if (a.getActionName().equals("Claim")) {
|
||||
//
|
||||
// claimTasks.add(a.getActivity().getId());
|
||||
//
|
||||
// } else if (a.getActionName().equals("Assign")) {
|
||||
//
|
||||
// assignTasks.add(a.getActivity().getId());
|
||||
//
|
||||
// } else if (a.getActionName().equals("Full Access")) {
|
||||
//
|
||||
// assignTasks.add(a.getActivity().getId());
|
||||
// claimTasks.add(a.getActivity().getId());
|
||||
// completeTasks.add(a.getActivity().getId());
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (assignTasks.size() > 1) {
|
||||
// // TODO what to check? only executed() is persistent...
|
||||
// }
|
||||
//
|
||||
// if (claimTasks.size() > 1) {
|
||||
// // TODO what to check? only executed() is persistent...
|
||||
// }
|
||||
//
|
||||
// if (completeTasks.size() > 1) {
|
||||
// // safe default assumptions
|
||||
// int maxUsers = 1;
|
||||
// int numActions = completeTasks.size();
|
||||
//
|
||||
// if (bod.getMaxUsers() == null) {
|
||||
// System.out
|
||||
// .println("[SCVM-EXPORT-ASLAN] maximum users for BoD \""
|
||||
// + bod.getId() + "\" not set, using " + maxUsers
|
||||
// + ".");
|
||||
// } else {
|
||||
// if (bod.getMaxUsers() < 1) {
|
||||
// System.err
|
||||
// .println("[SCVM-EXPORT-ASLAN] invalid input for maximum users at BoD \""
|
||||
// + bod.getId()
|
||||
// + "\", using "
|
||||
// + maxUsers
|
||||
// + ".");
|
||||
// } else {
|
||||
// maxUsers = bod.getMaxUsers();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (bod.getSameUserActionCount() == null) {
|
||||
// System.out
|
||||
// .println("[SCVM-EXPORT-ASLAN] number of actions for BoD \""
|
||||
// + bod.getId()
|
||||
// + "\" not set, using "
|
||||
// + numActions + ".");
|
||||
// } else {
|
||||
// if (bod.getSameUserActionCount() > completeTasks.size()
|
||||
// || bod.getSameUserActionCount() < 1) {
|
||||
// System.err
|
||||
// .println("[SCVM-EXPORT-ASLAN] invalid input for number of actions at BoD \""
|
||||
// + bod.getId()
|
||||
// + "\", using "
|
||||
// + numActions
|
||||
// + ".");
|
||||
// } else {
|
||||
// numActions = bod.getSameUserActionCount();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // calculate numeric partitions
|
||||
// final List<int[]> allPartitions = ExportUtil
|
||||
// .generateIntegerPartitions(completeTasks.size());
|
||||
//
|
||||
// // select invalid partitions
|
||||
// List<int[]> selectedPartitions = new ArrayList<int[]>();
|
||||
// for (int[] part : allPartitions) {
|
||||
// boolean invalidSummandFound = false;
|
||||
// for (int i : part) {
|
||||
// if (i != numActions)
|
||||
// invalidSummandFound = true;
|
||||
// }
|
||||
// if (part.length > 0
|
||||
// && (part.length > maxUsers || invalidSummandFound)) {
|
||||
// selectedPartitions.add(part);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // create goals for partitions
|
||||
// String[] tasks = new String[completeTasks.size()];
|
||||
// for (int i = 0; i < completeTasks.size(); i++) {
|
||||
// tasks[i] = completeTasks.get(i);
|
||||
// }
|
||||
// List<int[]> permList = ExportUtil
|
||||
// .generateLocationPermutations(tasks.length);
|
||||
//
|
||||
// for (int[] part : selectedPartitions) {
|
||||
// // we assume that tasks.lengh equals the sum of each partition
|
||||
// List<List<Set<String>>> sets = new ArrayList<List<Set<String>>>();
|
||||
//
|
||||
// // loop over index permutations
|
||||
// for (int[] perm : permList) {
|
||||
// int indexStart = 0;
|
||||
// // list of sets (parts of the partition) for the current
|
||||
// // permutation
|
||||
// List<Set<String>> setList = new ArrayList<Set<String>>();
|
||||
// // create the sets
|
||||
// for (int partLength : part) {
|
||||
// Set<String> partTasks = new HashSet<String>();
|
||||
// // get the tasks and add them to the set
|
||||
// for (int i = 0; i < partLength; i++) {
|
||||
// partTasks.add(tasks[perm[indexStart + i] - 1]);
|
||||
// }
|
||||
// indexStart += partLength;
|
||||
// setList.add(partTasks);
|
||||
// }
|
||||
// // check if partition config already exists
|
||||
// boolean newSet = true;
|
||||
// for (List<Set<String>> presentSetList : sets) {
|
||||
// if (presentSetList.equals(setList)) {
|
||||
// newSet = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// // add partition config if new
|
||||
// if (newSet) {
|
||||
// sets.add(setList);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// // create goals for this partition
|
||||
// for (List<Set<String>> setArray : sets) {
|
||||
// // generate goal
|
||||
// int numUsers = setArray.size();
|
||||
// int numTasks = tasks.length;
|
||||
// List<String> natVars = new ArrayList<String>();
|
||||
// StringBuilder goalString = new StringBuilder();
|
||||
// goalString.append("(");
|
||||
//
|
||||
// // generate user variables
|
||||
// for (int i = 0; i < numUsers; i++) {
|
||||
// afb.addType("user", "U" + i);
|
||||
// if (i > 0)
|
||||
// goalString.append(",");
|
||||
// goalString.append("U" + i);
|
||||
// }
|
||||
//
|
||||
// // generate task nat variables
|
||||
// for (int i = 0; i < numTasks; i++) {
|
||||
// String currentVar = afb.addNatVar();
|
||||
// natVars.add(currentVar);
|
||||
// goalString.append("," + currentVar);
|
||||
// }
|
||||
//
|
||||
// goalString.append("):=");
|
||||
//
|
||||
// // generate "executed" facts
|
||||
// int natVarPos = 0;
|
||||
// for (int i = 0; i < numUsers; i++) {
|
||||
// for (String currentTask : setArray.get(i)) {
|
||||
// goalString.append(" executed(U" + i + ",task("
|
||||
// + currentTask + ","
|
||||
// + natVars.get(natVarPos) + ")).");
|
||||
// natVarPos++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // generate "not equal" facts
|
||||
// StringBuilder neqString = new StringBuilder();
|
||||
// for (int i = 0; i < numUsers - 1; i++) {
|
||||
// for (int j = i + 1; j < numUsers; j++) {
|
||||
// neqString.append("& not(equal(U" + i + ",U" + j
|
||||
// + "))");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // add goal
|
||||
// String finalGoalString = goalString.toString();
|
||||
// afb.addGoal(
|
||||
// "bod_" + bod.getId() + "_",
|
||||
// finalGoalString.substring(0,
|
||||
// finalGoalString.length() - 1)
|
||||
// + neqString.toString());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/* 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.export.xacml.export;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.bpmn2.ExclusiveGateway;
|
||||
import org.eclipse.bpmn2.FlowElement;
|
||||
import org.eclipse.bpmn2.Gateway;
|
||||
import org.eclipse.bpmn2.SequenceFlow;
|
||||
import org.eclipse.bpmn2.StartEvent;
|
||||
import org.eclipse.bpmn2.Task;
|
||||
|
||||
/**
|
||||
* Creates the ASLan representation for a BPMN 2.0 ExclusiveGateway element.
|
||||
*
|
||||
*/
|
||||
public class ExclusiveGatewayExport {
|
||||
//
|
||||
// /**
|
||||
// * Generates the ASLan representation of the provided ExclusiveGateway
|
||||
// * element and sends the output to the provided AslanFileBuilder.
|
||||
// *
|
||||
// * @param exclusiveGateway
|
||||
// * The ExclusiveGateway for which the representation should be
|
||||
// * generated.
|
||||
// * @param afb
|
||||
// * The AslanFileBuilder the output is sent to.
|
||||
// */
|
||||
// public static void createExclusiveGatewayElements(
|
||||
// ExclusiveGateway exclusiveGateway, XacmlFileBuilder afb) {
|
||||
//
|
||||
// final List<SequenceFlow> incoming = exclusiveGateway.getIncoming();
|
||||
//
|
||||
// if (incoming.size() > 1) {
|
||||
//
|
||||
// // XOR-join
|
||||
// final List<SequenceFlow> outgoing = exclusiveGateway.getOutgoing();
|
||||
//
|
||||
// FlowElement successor = null;
|
||||
// String auxFact = "";
|
||||
//
|
||||
// if (outgoing.size() > 0) {
|
||||
// successor = outgoing.get(0).getTargetRef();
|
||||
// auxFact += exclusiveGateway.getId() + "_to_"
|
||||
// + successor.getId();
|
||||
// }
|
||||
//
|
||||
// int branchCounter = 1;
|
||||
// for (SequenceFlow parentFlow : incoming) {
|
||||
//
|
||||
// final FlowElement predecessor = parentFlow.getSourceRef();
|
||||
//
|
||||
// String lhs = "";
|
||||
//
|
||||
// if (predecessor instanceof Task) {
|
||||
//
|
||||
// String natVar = afb.addNatVar();
|
||||
//
|
||||
// lhs += "(" + natVar + ") := done(task("
|
||||
// + predecessor.getId() + "," + natVar + "))";
|
||||
//
|
||||
// } else if (predecessor instanceof Gateway) {
|
||||
//
|
||||
// lhs += " := " + predecessor.getId() + "_to_"
|
||||
// + exclusiveGateway.getId();
|
||||
//
|
||||
// } else if (predecessor instanceof StartEvent) {
|
||||
//
|
||||
// lhs += " := start_event_" + predecessor.getId();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if (lhs.length() > 0) {
|
||||
//
|
||||
// afb.addType("fact", auxFact);
|
||||
// afb.addRule("step " + exclusiveGateway.getId() + "_branch"
|
||||
// + branchCounter + lhs + " => " + auxFact);
|
||||
//
|
||||
// branchCounter++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// // XOR-split
|
||||
// FlowElement predecessor = null;
|
||||
//
|
||||
// if (incoming.size() > 0) {
|
||||
// predecessor = incoming.get(0).getSourceRef();
|
||||
// } else {
|
||||
// // ExclusiveGateway not reachable
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// String lhs = "";
|
||||
//
|
||||
// if (predecessor instanceof Task) {
|
||||
//
|
||||
// String natVar = afb.addNatVar();
|
||||
//
|
||||
// lhs += "(" + natVar + ") := done(task(" + predecessor.getId()
|
||||
// + "," + natVar + "))";
|
||||
//
|
||||
// } else if (predecessor instanceof Gateway) {
|
||||
//
|
||||
// lhs += " := " + predecessor.getId() + "_to_"
|
||||
// + exclusiveGateway.getId();
|
||||
//
|
||||
// } else if (predecessor instanceof StartEvent) {
|
||||
//
|
||||
// lhs += " := start_event_" + predecessor.getId();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// int branchCounter = 1;
|
||||
// for (SequenceFlow childFlow : exclusiveGateway.getOutgoing()) {
|
||||
//
|
||||
// final String auxFact = exclusiveGateway.getId() + "_to_"
|
||||
// + childFlow.getTargetRef().getId();
|
||||
//
|
||||
// afb.addType("fact", auxFact);
|
||||
// afb.addRule("step " + exclusiveGateway.getId() + "_branch"
|
||||
// + branchCounter + lhs + " => " + auxFact);
|
||||
//
|
||||
// branchCounter++;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/* 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.export.xacml.export;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class contains utility methods that are being used in the XACML export.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ExportUtil {
|
||||
|
||||
private static int permLevel = -1;
|
||||
|
||||
/**
|
||||
* Generates integer partitions in anti-lexicographic order using the
|
||||
* algorithm ZS1 as described in Zoghbi, A. and Stojmenovic, I.
|
||||
* "Fast Algorithms for Generating Integer Partitions", published in 1998.
|
||||
* For each partition, the parts are provided in descending order.
|
||||
*
|
||||
* @param n
|
||||
* The integer for which the partitions should be generated.
|
||||
* @return A List containing the integer partitions, each represented as a
|
||||
* integer Array.
|
||||
*/
|
||||
public static List<int[]> generateIntegerPartitions(int n) {
|
||||
|
||||
List<int[]> res = new ArrayList<int[]>();
|
||||
|
||||
int[] x = new int[n];
|
||||
|
||||
for (int i = 1; i <= n; i++) {
|
||||
x[i - 1] = 1;
|
||||
}
|
||||
|
||||
x[0] = n;
|
||||
int m = 1;
|
||||
int h = 1;
|
||||
|
||||
res.add(copySubarray(x, 0, 1));
|
||||
|
||||
while (x[0] != 1) {
|
||||
|
||||
if (x[h - 1] == 2) {
|
||||
m = m + 1;
|
||||
x[h - 1] = 1;
|
||||
h = h - 1;
|
||||
} else {
|
||||
int r = x[h - 1] - 1;
|
||||
int t = m - h + 1;
|
||||
x[h - 1] = r;
|
||||
|
||||
while (t >= r) {
|
||||
h = h + 1;
|
||||
x[h - 1] = r;
|
||||
t = t - r;
|
||||
}
|
||||
|
||||
if (t == 0) {
|
||||
m = h;
|
||||
} else {
|
||||
m = h + 1;
|
||||
|
||||
if (t > 1) {
|
||||
h = h + 1;
|
||||
x[h - 1] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
res.add(copySubarray(x, 0, m));
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a subarray of a given array and returns it.
|
||||
*
|
||||
* @param src
|
||||
* The source array that should be used.
|
||||
* @param start
|
||||
* The start index.
|
||||
* @param end
|
||||
* The end index.
|
||||
* @return A subarray of the source array, including the value at the start
|
||||
* index and excluding the value at the end index.
|
||||
*/
|
||||
private static int[] copySubarray(int[] src, int start, int end) {
|
||||
|
||||
int[] res = new int[end - start];
|
||||
int resPos = 0;
|
||||
|
||||
for (int i = start; i < end; i++) {
|
||||
res[resPos] = src[i];
|
||||
resPos++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates all permutations of a sequence containing the numbers from 1 to
|
||||
* n.
|
||||
*
|
||||
* @param n
|
||||
* The upper bound of the permutations.
|
||||
* @return A List with all permutations of the sequence.
|
||||
*/
|
||||
public static List<int[]> generateLocationPermutations(int n) {
|
||||
List<int[]> res = new ArrayList<int[]>();
|
||||
permLevel = -1;
|
||||
|
||||
int[] value = new int[n];
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
value[i] = 0;
|
||||
}
|
||||
permVisit(value, n, 0, res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for generating the integer sequence permutations. Should
|
||||
* not be used on its own!
|
||||
*
|
||||
*/
|
||||
private static void permVisit(int[] value, int n, int k, List<int[]> res) {
|
||||
permLevel = permLevel + 1;
|
||||
value[k] = permLevel;
|
||||
|
||||
if (permLevel == n) {
|
||||
res.add(copySubarray(value, 0, value.length));
|
||||
} else {
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (value[i] == 0)
|
||||
permVisit(value, n, i, res);
|
||||
}
|
||||
}
|
||||
permLevel = permLevel - 1;
|
||||
value[k] = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/* 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.export.xacml.export;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.bpmn2.EndEvent;
|
||||
import org.eclipse.bpmn2.FlowElement;
|
||||
import org.eclipse.bpmn2.Gateway;
|
||||
import org.eclipse.bpmn2.ParallelGateway;
|
||||
import org.eclipse.bpmn2.SequenceFlow;
|
||||
import org.eclipse.bpmn2.StartEvent;
|
||||
import org.eclipse.bpmn2.Task;
|
||||
|
||||
/**
|
||||
* Creates the ASLan representation for a BPMN 2.0 ParallelGateway element.
|
||||
*
|
||||
*/
|
||||
public class ParallelGatewayExport {
|
||||
//
|
||||
// /**
|
||||
// * Generates the ASLan representation of the provided ParallelGateway
|
||||
// * element and sends the output to the provided AslanFileBuilder.
|
||||
// *
|
||||
// * @param parallelGateway
|
||||
// * The ParallelGateway for which the representation should be
|
||||
// * generated.
|
||||
// * @param afb
|
||||
// * The AslanFileBuilder the output is sent to.
|
||||
// */
|
||||
// public static void createParallelGatewayElements(
|
||||
// ParallelGateway parallelGateway, XacmlFileBuilder afb) {
|
||||
//
|
||||
// final List<SequenceFlow> incoming = parallelGateway.getIncoming();
|
||||
// String rule = "step w_" + parallelGateway.getId();
|
||||
//
|
||||
// if (incoming.size() > 0) {
|
||||
//
|
||||
// // AND-join, AND-split
|
||||
// String ruleDef = " := ";
|
||||
//
|
||||
// boolean firstDone = true;
|
||||
// List<String> natVars = new ArrayList<String>();
|
||||
// for (SequenceFlow parentFlow : incoming) {
|
||||
//
|
||||
// final FlowElement predecessor = parentFlow.getSourceRef();
|
||||
//
|
||||
// if (predecessor instanceof Task) {
|
||||
//
|
||||
// if (firstDone) {
|
||||
// firstDone = false;
|
||||
// } else {
|
||||
// ruleDef += ". ";
|
||||
// }
|
||||
//
|
||||
// String natVar = afb.addNatVar();
|
||||
//
|
||||
// ruleDef += "done(task(" + predecessor.getId() + ","
|
||||
// + natVar + "))";
|
||||
// natVars.add(natVar);
|
||||
//
|
||||
// } else if (predecessor instanceof Gateway) {
|
||||
//
|
||||
// if (firstDone) {
|
||||
// firstDone = false;
|
||||
// } else {
|
||||
// ruleDef += ". ";
|
||||
// }
|
||||
//
|
||||
// ruleDef += predecessor.getId() + "_to_"
|
||||
// + parallelGateway.getId();
|
||||
//
|
||||
// } else if (predecessor instanceof StartEvent) {
|
||||
//
|
||||
// if (firstDone) {
|
||||
// firstDone = false;
|
||||
// } else {
|
||||
// ruleDef += ". ";
|
||||
// }
|
||||
//
|
||||
// ruleDef += "start_event_" + predecessor.getId();
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (natVars.size() > 0) {
|
||||
//
|
||||
// rule += "(";
|
||||
//
|
||||
// for (int i = 0; i < natVars.size() - 1; i++) {
|
||||
// rule += natVars.get(i) + ",";
|
||||
// }
|
||||
// rule += natVars.get(natVars.size() - 1) + ")";
|
||||
//
|
||||
// }
|
||||
//
|
||||
// rule += ruleDef + " => ";
|
||||
//
|
||||
// boolean firstAuxFact = true;
|
||||
// for (SequenceFlow childFlow : parallelGateway.getOutgoing()) {
|
||||
//
|
||||
// final FlowElement successor = childFlow.getTargetRef();
|
||||
//
|
||||
// if (successor instanceof Task || successor instanceof Gateway
|
||||
// || successor instanceof EndEvent) {
|
||||
//
|
||||
// final String auxFact = parallelGateway.getId() + "_to_"
|
||||
// + successor.getId();
|
||||
// afb.addType("fact", auxFact);
|
||||
//
|
||||
// if (firstAuxFact) {
|
||||
// rule += auxFact;
|
||||
// firstAuxFact = false;
|
||||
// } else {
|
||||
// rule += ". " + auxFact;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// afb.addRule(rule);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
/* 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.export.xacml.export;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.securebpmn2.ActivityAction;
|
||||
import org.eclipse.securebpmn2.Permission;
|
||||
import org.eclipse.securebpmn2.SeparationOfDuty;
|
||||
|
||||
/**
|
||||
* Creates the XACML representation of a SecureBPMN SeparationOfDuty element.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class SeparationOfDutyExport {
|
||||
|
||||
/**
|
||||
* Generates the XACML representation of the provided SeparationOfDuty element
|
||||
* and sends the output to the provided XacmlFileBuilder.
|
||||
*
|
||||
* @param sod
|
||||
* The SeparationOfDuty element for which the representation should
|
||||
* be generated.
|
||||
* @param afb
|
||||
* The XacmlFileBuilder the output is sent to.
|
||||
*/
|
||||
public static void createSeparationOfDutyElements(SeparationOfDuty sod, XacmlFileBuilder xfb) {
|
||||
|
||||
if (sod.isDynamicEnforcement()) return;
|
||||
|
||||
List<String> assignTasks = new ArrayList<String>();
|
||||
List<String> claimTasks = new ArrayList<String>();
|
||||
List<String> completeTasks = new ArrayList<String>();
|
||||
|
||||
for (Permission p : sod.getPermissions()) {
|
||||
|
||||
if (p.getActions().size() == 0) {
|
||||
System.err.println("[WARNING] The permission with name=\"" + p.getPName() + "\" and id=\"" + p.getId() + "\" has no action. This should never happen! Check your .activiti diagram file.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Permissions only have one Action
|
||||
if (p.getActions().get(0) instanceof ActivityAction) {
|
||||
ActivityAction a = (ActivityAction) p.getActions().get(0);
|
||||
|
||||
if (a.getActionName().equals("Complete")) {
|
||||
|
||||
completeTasks.add(a.getActivity().getId());
|
||||
|
||||
} else if (a.getActionName().equals("Claim")) {
|
||||
|
||||
claimTasks.add(a.getActivity().getId());
|
||||
|
||||
} else if (a.getActionName().equals("Assign")) {
|
||||
|
||||
assignTasks.add(a.getActivity().getId());
|
||||
|
||||
} else if (a.getActionName().equals("Full Access")) {
|
||||
|
||||
assignTasks.add(a.getActivity().getId());
|
||||
claimTasks.add(a.getActivity().getId());
|
||||
completeTasks.add(a.getActivity().getId());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (assignTasks.size() > 1) {
|
||||
// TODO what to check? only executed() is persistent...
|
||||
}
|
||||
|
||||
if (claimTasks.size() > 1) {
|
||||
// TODO what to check? only executed() is persistent...
|
||||
}
|
||||
|
||||
if (completeTasks.size() > 1) {
|
||||
// safe default assumptions
|
||||
int minUsers = completeTasks.size();
|
||||
int maxActions = 1;
|
||||
|
||||
if (sod.getMinimumUsers() == null) {
|
||||
System.out.println("[SCVM-EXPORT-XACML] minimum users for SoD \"" + sod.getId() + "\" not set, using " + minUsers + ".");
|
||||
} else {
|
||||
if (sod.getMinimumUsers() > completeTasks.size() || sod.getMinimumUsers() < 1) {
|
||||
System.err.println("[SCVM-EXPORT-XACML] invalid input for minimum users at SoD \"" + sod.getId() + "\", using " + minUsers + ".");
|
||||
} else {
|
||||
minUsers = sod.getMinimumUsers();
|
||||
}
|
||||
}
|
||||
|
||||
if (sod.getMaxUserActionsPermitted() == null) {
|
||||
System.out.println("[SCVM-EXPORT-XACML] maximum permitted actions for SoD \"" + sod.getId() + "\" not set, using " + maxActions + ".");
|
||||
} else {
|
||||
if (sod.getMaxUserActionsPermitted() < 1) {
|
||||
System.err.println("[SCVM-EXPORT-XACML] invalid input for maximum permitted actions at SoD \"" + sod.getId() + "\", using " + maxActions + ".");
|
||||
} else {
|
||||
maxActions = sod.getMaxUserActionsPermitted();
|
||||
}
|
||||
}
|
||||
|
||||
// calculate numeric partitions
|
||||
final List<int[]> allPartitions = ExportUtil.generateIntegerPartitions(completeTasks.size());
|
||||
|
||||
// select invalid partitions
|
||||
List<int[]> selectedPartitions = new ArrayList<int[]>();
|
||||
for (int[] part : allPartitions) {
|
||||
if (part.length > 0 && (part.length < minUsers
|
||||
|| part[0] > maxActions)) {
|
||||
selectedPartitions.add(part);
|
||||
}
|
||||
}
|
||||
|
||||
// create goals for partitions
|
||||
String[] tasks = new String[completeTasks.size()];
|
||||
for (int i = 0; i < completeTasks.size(); i++) {
|
||||
tasks[i] = completeTasks.get(i);
|
||||
}
|
||||
List<int[]> permList = ExportUtil.generateLocationPermutations(tasks.length);
|
||||
|
||||
for (int[] part : selectedPartitions) {
|
||||
// we assume that tasks.lengh equals the sum of each partition
|
||||
List<List<Set<String>>> sets = new ArrayList<List<Set<String>>>();
|
||||
|
||||
// loop over index permutations
|
||||
for (int[] perm : permList) {
|
||||
int indexStart = 0;
|
||||
// list of sets (parts of the partition) for the current permutation
|
||||
List<Set<String>> setList = new ArrayList<Set<String>>();
|
||||
// create the sets
|
||||
for (int partLength : part) {
|
||||
Set<String> partTasks = new HashSet<String>();
|
||||
// get the tasks and add them to the set
|
||||
for (int i = 0; i < partLength; i++) {
|
||||
partTasks.add(tasks[perm[indexStart + i]-1]);
|
||||
}
|
||||
indexStart += partLength;
|
||||
setList.add(partTasks);
|
||||
}
|
||||
// check if partition config already exists
|
||||
boolean newSet = true;
|
||||
for (List<Set<String>> presentSetList : sets) {
|
||||
if (presentSetList.equals(setList)) {
|
||||
newSet = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// add partition config if new
|
||||
if (newSet) {
|
||||
sets.add(setList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
// create goals for this partition
|
||||
for (List<Set<String>> setArray : sets) {
|
||||
// generate goal
|
||||
int numUsers = setArray.size();
|
||||
int numTasks = tasks.length;
|
||||
List<String> natVars = new ArrayList<String>();
|
||||
StringBuilder goalString = new StringBuilder();
|
||||
goalString.append("(");
|
||||
|
||||
// generate user variables
|
||||
for (int i = 0; i < numUsers; i++) {
|
||||
afb.addType("user", "U" + i);
|
||||
if (i > 0) goalString.append(",");
|
||||
goalString.append("U" + i);
|
||||
}
|
||||
|
||||
// generate task nat variables
|
||||
for (int i = 0; i < numTasks; i++) {
|
||||
String currentVar = afb.addNatVar();
|
||||
natVars.add(currentVar);
|
||||
goalString.append("," + currentVar);
|
||||
}
|
||||
|
||||
goalString.append("):=");
|
||||
|
||||
// generate facts
|
||||
int natVarPos = 0;
|
||||
for (int i = 0; i < numUsers; i++) {
|
||||
for (String currentTask : setArray.get(i)) {
|
||||
goalString.append(" executed(U" + i + ",task(" + currentTask + "," + natVars.get(natVarPos) + ")).");
|
||||
natVarPos++;
|
||||
}
|
||||
}
|
||||
|
||||
// add goal
|
||||
String finalGoalString = goalString.toString();
|
||||
afb.addGoal("sod_" + sod.getId() + "_", finalGoalString.substring(0, finalGoalString.length()-1));
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/* 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.export.xacml.export;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
|
||||
import org.activiti.designer.eclipse.preferences.PreferencesUtil;
|
||||
import org.activiti.designer.util.preferences.Preferences;
|
||||
|
||||
import org.eclipse.bpmn2.Task;
|
||||
import org.eclipse.bpmn2.UserTask;
|
||||
|
||||
import org.eclipse.securebpmn2.ActivityAction;
|
||||
import org.eclipse.securebpmn2.Permission;
|
||||
import org.eclipse.securebpmn2.Role;
|
||||
|
||||
import com.sun.xacml.combine.DenyOverridesRuleAlg;
|
||||
import com.sun.xacml.combine.RuleCombiningAlgorithm;
|
||||
|
||||
/**
|
||||
* Creates the RBAC XACML-Rules for each HumanTask in the Diagram
|
||||
*
|
||||
*/
|
||||
public class TaskExport {
|
||||
|
||||
/**
|
||||
* Gathers information needed for the XACML-Policy rules section.
|
||||
*
|
||||
* @param task
|
||||
* The {@link Task} element for which the information should be
|
||||
* gathered
|
||||
*
|
||||
* @param xfb
|
||||
* The {@link XacmlFileBuilder} used to create the rules
|
||||
*
|
||||
*/
|
||||
public static void gatherTaskInfo(Task task, XacmlFileBuilder xfb) {
|
||||
|
||||
final String taskID = task.getId();
|
||||
|
||||
boolean isHumanTask = false;
|
||||
//boolean isSodTask = false;
|
||||
|
||||
if (task instanceof UserTask
|
||||
|| PreferencesUtil
|
||||
.getBooleanPreference(Preferences.ALL_TASKS_AS_HUMANTASKS))
|
||||
isHumanTask = true;
|
||||
|
||||
if (isHumanTask) {
|
||||
|
||||
/*
|
||||
UserTask userTask = (UserTask) task;
|
||||
List<CandidateGroup> candidateGroups = userTask.getCandidateGroups();
|
||||
List<String> groups = new ArrayList<String>();
|
||||
|
||||
for (Iterator<CandidateGroup> iterator = candidateGroups.iterator(); iterator.hasNext();) {
|
||||
CandidateGroup candidateGroup = (CandidateGroup) iterator.next();
|
||||
groups.add(candidateGroup.getGroup());
|
||||
}
|
||||
|
||||
for (Iterator<String> iterator = groups.iterator(); iterator.hasNext();) {
|
||||
String string = (String) iterator.next();
|
||||
try {
|
||||
xfb.createTargetMatch(1, string);
|
||||
xfb.createTargetMatch(2, taskID);
|
||||
xfb.createTargetMatch(3, "Full Access");
|
||||
|
||||
if (task.getIncomingSecurityFlow().isEmpty()) {
|
||||
xfb.createRule(
|
||||
URI.create("rule_for_" + taskID), 0,
|
||||
task.getName(), xfb.createTarget(),
|
||||
null);
|
||||
RuleCombiningAlgorithm ruleCombiningAlgorithm = new DenyOverridesRuleAlg();
|
||||
xfb.createPolicy(
|
||||
URI.create("policy_for_" + taskID),
|
||||
ruleCombiningAlgorithm,
|
||||
xfb.createTarget(), xfb.getRules());
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// SecureBPMN RBAC
|
||||
for (ActivityAction a : task.getActivityActions()) {
|
||||
if (a.getActionName() != null
|
||||
&& (a.getActionName().equals("Assign") || a
|
||||
.getActionName().equals("Full Access"))) {
|
||||
try {
|
||||
xfb.createTargetMatch(3, a.getActionName());
|
||||
} catch (URISyntaxException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Permission p : a.getPermissions()) {
|
||||
for (Role r : p.getRoles()) {
|
||||
try {
|
||||
xfb.createTargetMatch(2, taskID);
|
||||
|
||||
xfb.createTargetMatch(1, r.getName().toLowerCase());
|
||||
|
||||
} catch (URISyntaxException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// TODO see todo below
|
||||
/*
|
||||
if(!task.getIncomingSecurityFlow().isEmpty()) {
|
||||
isSodTask = task
|
||||
.getIncomingSecurityFlow().get(0)
|
||||
.getSourceRefNode().getId()
|
||||
.startsWith("securitySod");
|
||||
}*/
|
||||
|
||||
|
||||
// simple human task
|
||||
//if (task.getIncomingSecurityFlow().isEmpty()) {
|
||||
xfb.createRule(
|
||||
URI.create("rule_for_" + taskID), 0,
|
||||
task.getName(), xfb.createTarget(),
|
||||
null);
|
||||
RuleCombiningAlgorithm ruleCombiningAlgorithm = new DenyOverridesRuleAlg();
|
||||
xfb.createPolicy(
|
||||
URI.create("policy_for_" + taskID),
|
||||
ruleCombiningAlgorithm,
|
||||
xfb.createTarget(), xfb.getRules());
|
||||
//}// TODO insert condition for SoD-Task
|
||||
/*
|
||||
else if (isSodTask) {
|
||||
|
||||
List<Task> connectedTasks = new ArrayList<Task>();
|
||||
for (Iterator<SecurityFlow> it = task
|
||||
.getIncomingSecurityFlow().iterator(); it
|
||||
.hasNext();) {
|
||||
SecurityFlow securityFlow = (SecurityFlow) it
|
||||
.next();
|
||||
Task connectedTask = (Task) securityFlow.getTargetRefNode();
|
||||
connectedTasks.add(connectedTask);
|
||||
|
||||
}
|
||||
|
||||
xfb.createRule(
|
||||
URI.create("rule_for_" + taskID), 0,
|
||||
task.getName(), xfb.createTarget(),
|
||||
xfb.createSodCondition(task, connectedTasks));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
/* 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.export.xacml.export;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import org.activiti.designer.eclipse.common.ActivitiBPMNDiagramConstants;
|
||||
import org.activiti.designer.eclipse.extension.export.AbstractExportMarshaller;
|
||||
import org.activiti.designer.eclipse.extension.export.ExportMarshaller;
|
||||
import org.eclipse.bpmn2.ExclusiveGateway;
|
||||
import org.eclipse.bpmn2.ParallelGateway;
|
||||
import org.eclipse.bpmn2.Process;
|
||||
import org.eclipse.bpmn2.StartEvent;
|
||||
import org.eclipse.bpmn2.Task;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.graphiti.mm.pictograms.Diagram;
|
||||
import org.eclipse.securebpmn2.BindingOfDuty;
|
||||
import org.eclipse.securebpmn2.SeparationOfDuty;
|
||||
|
||||
import com.sun.xacml.combine.FirstApplicablePolicyAlg;
|
||||
import com.sun.xacml.combine.PolicyCombiningAlgorithm;
|
||||
|
||||
/**
|
||||
* Exports an XACML representation of the diagram being saved to the workspace
|
||||
* as XML-File.
|
||||
*
|
||||
*/
|
||||
public class XacmlExportMarshaller extends AbstractExportMarshaller {
|
||||
|
||||
private static final String FILENAME_PATTERN = ExportMarshaller.PLACEHOLDER_ORIGINAL_FILENAME_WITHOUT_EXTENSION
|
||||
+ ".xacml";
|
||||
private IProgressMonitor monitor;
|
||||
private Diagram diagram;
|
||||
|
||||
public XacmlExportMarshaller() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.activiti.designer.eclipse.extension.export.ExportMarshaller#
|
||||
* getMarshallerName()
|
||||
*/
|
||||
@Override
|
||||
public String getMarshallerName() {
|
||||
return ActivitiBPMNDiagramConstants.XACML_MARSHALLER_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.activiti.designer.eclipse.extension.export.ExportMarshaller#getFormatName()
|
||||
*/
|
||||
@Override
|
||||
public String getFormatName() {
|
||||
return "SecureBPMN: XACML";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @see org.activiti.designer.eclipse.extension.export.ExportMarshaller#
|
||||
* marshallDiagram(org.eclipse.graphiti.mm.pictograms.Diagram,
|
||||
* org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void marshallDiagram(Diagram diagram, IProgressMonitor monitor) {
|
||||
|
||||
this.monitor = monitor;
|
||||
this.diagram = diagram;
|
||||
this.monitor.beginTask("Exporting to XACML", 100);
|
||||
clearMarkers(getResource(diagram.eResource().getURI()));
|
||||
this.monitor.worked(10);
|
||||
String validatorId = ActivitiBPMNDiagramConstants.XACML_VALIDATOR_ID;
|
||||
boolean validBpmn = invokeValidator(validatorId, diagram,
|
||||
new SubProgressMonitor(this.monitor, 10));
|
||||
|
||||
if (validBpmn) {
|
||||
marshallXacml();
|
||||
} else {
|
||||
addProblemToDiagram(
|
||||
diagram,
|
||||
"XACML Export skipped because SecureBPMN validation failed.",
|
||||
null);
|
||||
}
|
||||
this.monitor.worked(80);
|
||||
this.monitor.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls and executes the XACML file generation.
|
||||
*/
|
||||
public void marshallXacml() {
|
||||
|
||||
try {
|
||||
final List<EObject> contents = diagram.eResource().getContents();
|
||||
Process process = null;
|
||||
|
||||
for (final EObject eObject : contents) {
|
||||
if (eObject instanceof Process) {
|
||||
process = (Process) eObject;
|
||||
}
|
||||
}
|
||||
if (process == null) {
|
||||
addProblemToDiagram(diagram, "Process cannot be null", null);
|
||||
}
|
||||
final XacmlFileBuilder xfb = new XacmlFileBuilder();
|
||||
// element-specific content generation
|
||||
for (EObject object : contents) {
|
||||
if (object instanceof ParallelGateway) {
|
||||
/*
|
||||
* ParallelGatewayExport.createParallelGatewayElements(
|
||||
* (ParallelGateway) object, xfb);
|
||||
*/
|
||||
} else if (object instanceof ExclusiveGateway) {
|
||||
/*
|
||||
* ExclusiveGatewayExport.createExclusiveGatewayElements(
|
||||
* (ExclusiveGateway) object, xfb);
|
||||
*/
|
||||
} else if (object instanceof StartEvent) {
|
||||
/*
|
||||
* final String startEventFact = "start_event_" +
|
||||
* ((StartEvent) object).getId(); xfb.addType("fact",
|
||||
* startEventFact); xfb.addInit(startEventFact);
|
||||
*/
|
||||
} else if (object instanceof Task) {
|
||||
|
||||
TaskExport.gatherTaskInfo((Task) object, xfb);
|
||||
|
||||
} else if (object instanceof SeparationOfDuty) {
|
||||
/*
|
||||
* SeparationOfDutyExport.createSeparationOfDutyElements(
|
||||
* (SeparationOfDuty) object, xfb);
|
||||
*/
|
||||
} else if (object instanceof BindingOfDuty) {
|
||||
/*
|
||||
* BindingOfDutyExport.createBindingOfDutyElements(
|
||||
* (BindingOfDuty) object, xfb);
|
||||
*/
|
||||
}
|
||||
}
|
||||
// the policy
|
||||
//URI policyID = URI.create("testPolicy");
|
||||
// TODO insert options for the used CombiningAlg
|
||||
//RuleCombiningAlgorithm ruleCombiningAlg = new DenyOverridesRuleAlg();
|
||||
|
||||
//xfb.createPolicy(policyID, ruleCombiningAlg, xfb.createTarget(),
|
||||
// xfb.getRules());
|
||||
// the policy Set
|
||||
URI policySetID = URI.create("testPolicySet");
|
||||
// TODO insert options for the used CombiningAlg
|
||||
PolicyCombiningAlgorithm policyCombiningAlg = new FirstApplicablePolicyAlg();
|
||||
|
||||
// TODO maybe create deny rule for the PolicySet-Target if no inner
|
||||
// rules apply
|
||||
xfb.createPolicySet(policySetID, policyCombiningAlg,
|
||||
xfb.createTarget(), xfb.getPolicies());
|
||||
|
||||
// mapping the encoded PolicySet data
|
||||
final ByteArrayOutputStream baos = (ByteArrayOutputStream) xfb
|
||||
.encodePolicySet();
|
||||
|
||||
// write policy to file
|
||||
final byte[] bytes = baos.toByteArray();
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
saveResource(getRelativeURIForDiagram(diagram, FILENAME_PATTERN),
|
||||
bais, new NullProgressMonitor());
|
||||
|
||||
//xfb.testPDP();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
addProblemToDiagram(
|
||||
diagram,
|
||||
"An exception occurred while creating the XACML file: "
|
||||
+ e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,329 @@
|
|||
/* 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.export.xacml.export;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.xacml.*;
|
||||
|
||||
import com.sun.xacml.attr.AnyURIAttribute;
|
||||
import com.sun.xacml.attr.AttributeDesignator;
|
||||
import com.sun.xacml.attr.AttributeValue;
|
||||
import com.sun.xacml.attr.StringAttribute;
|
||||
import com.sun.xacml.attr.TypeIdentifierConstants;
|
||||
|
||||
import com.sun.xacml.combine.PolicyCombiningAlgorithm;
|
||||
import com.sun.xacml.combine.RuleCombiningAlgorithm;
|
||||
import com.sun.xacml.cond.Condition;
|
||||
import com.sun.xacml.cond.EqualFunction;
|
||||
import com.sun.xacml.cond.Evaluatable;
|
||||
import com.sun.xacml.cond.Function;
|
||||
|
||||
/**
|
||||
* Provides the methods to create a complete XACML policy.
|
||||
*
|
||||
*/
|
||||
public class XacmlFileBuilder {
|
||||
|
||||
/**
|
||||
* output is used in {@link #encodePolicySet()} to provide a source for the
|
||||
* XML encoded Data
|
||||
*/
|
||||
private OutputStream output;
|
||||
|
||||
private PolicySet policySet;
|
||||
|
||||
private List<Rule> rules;
|
||||
private List<PolicyTreeElement> policies;
|
||||
|
||||
private List<TargetMatch> matches;
|
||||
private List<TargetMatchGroup> matchGroups;
|
||||
private List<TargetSection> targetSections;
|
||||
|
||||
public XacmlFileBuilder() throws FileNotFoundException, ParsingException, UnknownIdentifierException {
|
||||
|
||||
// createSodCondition();
|
||||
output = new ByteArrayOutputStream();
|
||||
policies = new ArrayList<PolicyTreeElement>();
|
||||
rules = new ArrayList<Rule>();
|
||||
matches = new ArrayList<TargetMatch>();
|
||||
matchGroups = new ArrayList<TargetMatchGroup>();
|
||||
targetSections = new ArrayList<TargetSection>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the completed {@link PolicySet} and encodes it to XML-format.
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* if encoding fails
|
||||
* @return {@link XacmlFileBuilder#output} The encoded
|
||||
* <code>PolicySet</code> in its XML-formatted version.
|
||||
*/
|
||||
public OutputStream encodePolicySet() {
|
||||
|
||||
try {
|
||||
this.policySet.encode(output, "UTF-8");
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// e.printStackTrace();
|
||||
throw new RuntimeException("error during encoding process", e);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link PolicySet}. <br>
|
||||
* </br> And clears the {@link #policies}-list for the next
|
||||
* <code>PolicySet</code>
|
||||
*
|
||||
* @param policySetID
|
||||
* the <code>PolicySet</code> identifier
|
||||
* @param policyCombiningAlg
|
||||
* the <code>CombiningAlgorithm</code> used on the policies in
|
||||
* this set
|
||||
* @param target
|
||||
* the <code>Target</code> for this <code>PolicySet</code> (may
|
||||
* be null)
|
||||
* @param policies
|
||||
* a list of the policies in this set
|
||||
*/
|
||||
public void createPolicySet(URI policySetID,
|
||||
PolicyCombiningAlgorithm policyCombiningAlg, Target target,
|
||||
List<PolicyTreeElement> policies) {
|
||||
|
||||
policySet = new PolicySet(policySetID, policyCombiningAlg, target,
|
||||
policies);
|
||||
this.policies.clear();
|
||||
}
|
||||
//TODO finish sod check if needed after pdp impl
|
||||
/*
|
||||
public boolean evalSodCondition(Task currentTask, List<Task> connectedTasks) {
|
||||
// check if user of currentTask has claimed/completed any of the tasks
|
||||
// in the connectedTasks list
|
||||
Main_Test main_Test = new Main_Test();
|
||||
|
||||
TaskService ts = main_Test.getTaskService();
|
||||
HistoryService hs = main_Test.getHistoryService();
|
||||
|
||||
// get the current user of the given sod task
|
||||
org.activiti.engine.task.Task focusedTask = ts.createTaskQuery()
|
||||
.processDefinitionKey(currentTask.getId()).singleResult();
|
||||
String currentUser = focusedTask.getAssignee();
|
||||
|
||||
// check if this user has already performed an action on a connected sod
|
||||
// task
|
||||
for (Iterator<Task> iterator = connectedTasks.iterator(); iterator
|
||||
.hasNext();) {
|
||||
Task task = (Task) iterator.next();
|
||||
|
||||
String taskIdToCheck = task.getId();
|
||||
if (hs.createHistoricTaskInstanceQuery().taskAssignee(currentUser)
|
||||
.count() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
*/
|
||||
//TODO finish sod check if needed after pdp impl
|
||||
/*
|
||||
public Condition createSodCondition(Task currentTask,
|
||||
List<Task> connectedTasks) {
|
||||
|
||||
Expression expression = new EqualFunction(EqualFunction.NAME_BOOLEAN_EQUAL);
|
||||
|
||||
Condition condition = new Condition(expression);
|
||||
|
||||
return condition;
|
||||
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* Creates a new {@link Rule}.
|
||||
*
|
||||
* @param ruleID
|
||||
* the identifier of the <code>Rule</code>
|
||||
* @param effect
|
||||
* the result if the <code>Rule</code> applies as defined in
|
||||
* {@link Result}
|
||||
* @param ruleDescription
|
||||
* a textual description for the <code>Rule</code> (may be null)
|
||||
* @param target
|
||||
* the <code>Target</code> for the <code>Rule</code>, or null if
|
||||
* it should be inherited from the parent <code>Policy</code> or
|
||||
* <code>PolicySet</code>
|
||||
* @param condition
|
||||
* the <code>Condition</code> for this <code>Rule</code> (may be
|
||||
* null)
|
||||
*/
|
||||
public void createRule(URI ruleID, int effect, String ruleDescription,
|
||||
Target target, Condition condition) {
|
||||
|
||||
Rule rule = new Rule(ruleID, effect, ruleDescription, target, condition);
|
||||
|
||||
if (!rules.contains(rule)) {
|
||||
rules.add(rule);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Policy}.
|
||||
*
|
||||
* @param policyID
|
||||
* the identifier of the <code>Policy</code>
|
||||
* @param ruleCombiningAlg
|
||||
* the <code>CombiningAlgorithm</code> used on the rules in this
|
||||
* <code>Policy</code>
|
||||
* @param target
|
||||
* the <code>Target</code> for the <code>Policy</code>, or null
|
||||
* if it should be inherited
|
||||
* @param rules
|
||||
* a list of the rules in this <code>Policy</code>
|
||||
*/
|
||||
public void createPolicy(URI policyID,
|
||||
RuleCombiningAlgorithm ruleCombiningAlg, Target target,
|
||||
List<Rule> rules) {
|
||||
|
||||
Policy policy = new Policy(policyID, ruleCombiningAlg, target, rules);
|
||||
|
||||
if (!policies.contains(policy)) {
|
||||
policies.add(policy);
|
||||
}
|
||||
this.rules.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetMatch}.
|
||||
*
|
||||
* @param matchType
|
||||
* used to determine which match type will be used <li>
|
||||
* 1:Subject-Role</li> <li>2:Resource</li> <li>3:Action</li>
|
||||
* @param attrValueString
|
||||
* the name of the target to match
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
public void createTargetMatch(int matchType, String attrValueString) throws URISyntaxException {
|
||||
|
||||
URI category = null;
|
||||
URI attrType = null;
|
||||
URI attrId = null;
|
||||
Function function = null;
|
||||
AttributeValue attrValue = null;
|
||||
|
||||
switch (matchType) {
|
||||
|
||||
case 1:
|
||||
category = Constants.SUBJECT_CAT;
|
||||
attrType = TypeIdentifierConstants.STRING_URI;
|
||||
attrId = URI.create("urn:custom:subject:role");
|
||||
function = new EqualFunction(EqualFunction.NAME_STRING_EQUAL);
|
||||
attrValue = new StringAttribute(attrValueString);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
category = Constants.RESOURCE_CAT;
|
||||
attrType = TypeIdentifierConstants.ANYURI_URI;
|
||||
attrId = Constants.RESOURCE_ID;
|
||||
function = new EqualFunction(EqualFunction.NAME_ANYURI_EQUAL);
|
||||
attrValue = new AnyURIAttribute(new URI(attrValueString));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
category = Constants.ACTION_CAT;
|
||||
attrType = TypeIdentifierConstants.STRING_URI;
|
||||
attrId = Constants.ACTION_ID;
|
||||
function = new EqualFunction(EqualFunction.NAME_STRING_EQUAL);
|
||||
attrValue = new StringAttribute(attrValueString);
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("\ncategory error\n");
|
||||
break;
|
||||
|
||||
}
|
||||
Evaluatable eval = new AttributeDesignator(category, attrType, attrId,
|
||||
false, null);
|
||||
TargetMatch tm = new TargetMatch(function, eval, attrValue);
|
||||
matches.add(tm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetMatchGroup}. <br>
|
||||
* And adds it to the local {@link #matchGroups}-list</br>
|
||||
*/
|
||||
private void createTargetMatchGroup() {
|
||||
|
||||
TargetMatchGroup tmg = new TargetMatchGroup(matches);
|
||||
matchGroups.add(tmg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetSection}. <br>
|
||||
* And adds it to the local {@link #targetSections}-list</br>
|
||||
*/
|
||||
private void createTargetSection() {
|
||||
|
||||
TargetSection ts = new TargetSection(matchGroups);
|
||||
targetSections.add(ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Target}. <br>
|
||||
* </br> Uses {@link #createTargetMatchGroup()} and
|
||||
* {@link #createTargetSection()} to create a <code>Target</code>. <br>
|
||||
* It clears the {@link #matches}, {@link #matchGroups},
|
||||
* {@link #targetSections}-lists for the next <code>Target</code>.</br>
|
||||
*
|
||||
* @return <b>target</b> the created <code>Target</code>
|
||||
*/
|
||||
public Target createTarget() {
|
||||
|
||||
createTargetMatchGroup();
|
||||
createTargetSection();
|
||||
Target target = new Target(getTargetSections());
|
||||
matches.clear();
|
||||
matchGroups.clear();
|
||||
targetSections.clear();
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
/*
|
||||
* non-javadoc
|
||||
*
|
||||
* following are the needed getters for the XacmlExportMarshaller
|
||||
*/
|
||||
private List<TargetSection> getTargetSections() {
|
||||
return targetSections;
|
||||
}
|
||||
|
||||
public List<Rule> getRules() {
|
||||
return rules;
|
||||
}
|
||||
|
||||
public List<PolicyTreeElement> getPolicies() {
|
||||
return policies;
|
||||
}
|
||||
}
|
Reference in New Issue