361 lines
13 KiB
Java
361 lines
13 KiB
Java
/* 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.util;
|
|
|
|
import java.io.BufferedInputStream;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
import org.activiti.designer.util.eclipse.ActivitiUiUtil;
|
|
import org.antlr.roledef.RoleDefLexer;
|
|
import org.antlr.roledef.RoleDefParser;
|
|
import org.antlr.runtime.ANTLRStringStream;
|
|
import org.antlr.runtime.CommonTokenStream;
|
|
import org.antlr.runtime.RecognitionException;
|
|
import org.eclipse.core.resources.IResource;
|
|
import org.eclipse.core.resources.ResourcesPlugin;
|
|
import org.eclipse.emf.common.util.URI;
|
|
import org.eclipse.emf.ecore.EObject;
|
|
import org.eclipse.emf.transaction.TransactionalEditingDomain;
|
|
import org.eclipse.emf.transaction.util.TransactionUtil;
|
|
import org.eclipse.graphiti.mm.pictograms.Diagram;
|
|
import org.eclipse.securebpmn2.Action;
|
|
import org.eclipse.securebpmn2.Role;
|
|
import org.eclipse.securebpmn2.Securebpmn2Factory;
|
|
import org.eclipse.securebpmn2.Subject;
|
|
import org.eclipse.securebpmn2.User;
|
|
|
|
import eu.aniketos.securebpmn.roles.RoleDef;
|
|
import eu.aniketos.securebpmn.roles.RoleDefLine;
|
|
import eu.aniketos.securebpmn.roles.RoleRel;
|
|
|
|
/**
|
|
* This Class contains utility methods for retrieving Users, Roles and
|
|
* ActivityActions.
|
|
*
|
|
*
|
|
*/
|
|
public class SecurityUtil {
|
|
|
|
private static List<Role> roles;
|
|
private static List<User> users;
|
|
private static List<Action> activityActions;
|
|
private static String diagramName;
|
|
|
|
/**
|
|
* Retrieve the roles for a given Diagram.
|
|
*
|
|
* @param diagram
|
|
* The diagram for which the roles should be retrieved.
|
|
* @return A List of Roles that are specified for the Diagram.
|
|
*/
|
|
public static List<Role> getRoles(Diagram diagram) {
|
|
if (diagram == null || diagram.getName() == null)
|
|
return new ArrayList<Role>();
|
|
|
|
if (diagramName == null) {
|
|
diagramName = diagram.getName();
|
|
}
|
|
|
|
if (roles == null || !diagram.getName().equals(diagramName)) {
|
|
loadRolesAndUsers(diagram);
|
|
}
|
|
return roles;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the users for a given Diagram.
|
|
*
|
|
* @param diagram
|
|
* The diagram for which the users should be retrieved.
|
|
* @return A List of Users that are specified for the Diagram.
|
|
*/
|
|
public static List<User> getUsers(Diagram diagram) {
|
|
if (diagramName == null) {
|
|
diagramName = diagram.getName();
|
|
}
|
|
|
|
if (users == null || !diagram.getName().equals(diagramName)) {
|
|
loadRolesAndUsers(diagram);
|
|
}
|
|
return users;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the ActivityActions that are currently available.
|
|
*
|
|
* @return A List of ActivityActions that are available.
|
|
*/
|
|
public static List<Action> getActivityActions() {
|
|
if (activityActions == null) {
|
|
activityActions = new ArrayList<Action>();
|
|
|
|
Action claimActivityAction = Securebpmn2Factory.eINSTANCE
|
|
.createAtomicActivityAction();
|
|
claimActivityAction.setId(UUID.randomUUID().toString());
|
|
claimActivityAction.setActionName("Claim");
|
|
Action assignActivityAction = Securebpmn2Factory.eINSTANCE
|
|
.createAtomicActivityAction();
|
|
assignActivityAction.setId(UUID.randomUUID().toString());
|
|
assignActivityAction.setActionName("Assign");
|
|
Action completeActivityAction = Securebpmn2Factory.eINSTANCE
|
|
.createAtomicActivityAction();
|
|
completeActivityAction.setActionName("Complete");
|
|
completeActivityAction.setId(UUID.randomUUID().toString());
|
|
Action fullAccess = Securebpmn2Factory.eINSTANCE
|
|
.createCompositeActivityAction();
|
|
fullAccess.setActionName("Full Access");
|
|
|
|
activityActions.add(fullAccess);
|
|
activityActions.add(claimActivityAction);
|
|
activityActions.add(assignActivityAction);
|
|
activityActions.add(completeActivityAction);
|
|
|
|
}
|
|
return activityActions;
|
|
}
|
|
|
|
/**
|
|
* Loads the roles and users from the configuration file. The file must be
|
|
* located in the same folder as the Diagram and the filename must be the
|
|
* same name as the Diagram file with the extension .roles.
|
|
*
|
|
* @param diagram
|
|
* The Diagram for which the roles and users should be loaded.
|
|
*/
|
|
private static void loadRolesAndUsers(final Diagram diagram) {
|
|
|
|
// clear roles and users that may exist
|
|
if (roles == null) {
|
|
roles = new ArrayList<Role>();
|
|
} else {
|
|
roles.clear();
|
|
}
|
|
|
|
if (users == null) {
|
|
users = new ArrayList<User>();
|
|
} else {
|
|
users.clear();
|
|
}
|
|
|
|
// parse role file and fill lists
|
|
if (diagram != null) {
|
|
|
|
// role hierarchy
|
|
List<RoleRel> hierarchy = new ArrayList<RoleRel>();
|
|
|
|
String in = "";
|
|
|
|
// get file location
|
|
URI uri = diagram.eResource().getURI();
|
|
URI platformUri = uri.trimFragment();
|
|
platformUri = platformUri.trimFileExtension();
|
|
platformUri = platformUri.appendFileExtension("roles");
|
|
|
|
final IResource fileResource = ResourcesPlugin.getWorkspace()
|
|
.getRoot().findMember(platformUri.toPlatformString(true));
|
|
if (fileResource != null && fileResource.exists()) {
|
|
final String fileUri = fileResource.getLocation().toString();
|
|
|
|
// read file
|
|
try {
|
|
in = readFileAsString(fileUri);
|
|
} catch (IOException e) {
|
|
System.err.println("[SCVM-RBAC] Error while reading file: "
|
|
+ fileUri.toString());
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
if (in.length() > 0) {
|
|
List<RoleDefLine> lines = null;
|
|
|
|
try {
|
|
RoleDefLexer lex = new RoleDefLexer(new ANTLRStringStream(
|
|
in));
|
|
CommonTokenStream tokens = new CommonTokenStream(lex);
|
|
|
|
RoleDefParser parser = new RoleDefParser(tokens);
|
|
lines = parser.file();
|
|
|
|
} catch (RecognitionException e) {
|
|
System.err
|
|
.println("[SCVM-RBAC] Error while parsing role/user file.");
|
|
e.printStackTrace();
|
|
}
|
|
|
|
// generate roles for result
|
|
if (lines != null) {
|
|
for (RoleDefLine line : lines) {
|
|
if (line instanceof RoleDef) {
|
|
final RoleDef def = (RoleDef) line;
|
|
|
|
// create (if necessary) and add role
|
|
Role role = Securebpmn2Factory.eINSTANCE
|
|
.createRole();
|
|
role.setName(def.getRoleName());
|
|
role.setId(UUID.randomUUID().toString());
|
|
roles.add(role);
|
|
|
|
// create and add users to role
|
|
for (String userName : def.getMembers()) {
|
|
User user = Securebpmn2Factory.eINSTANCE
|
|
.createUser();
|
|
user.setUserName(userName);
|
|
user.setId(userName.toLowerCase());
|
|
users.add(user);
|
|
|
|
user.getRoles().add(role);
|
|
role.getSubjects().add(user);
|
|
|
|
}
|
|
|
|
} else if (line instanceof RoleRel) {
|
|
hierarchy.add((RoleRel) line);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO order hierarchy list
|
|
|
|
// assign new roles to users
|
|
for (RoleRel rel : hierarchy) {
|
|
|
|
// find roles
|
|
Role supRole = null;
|
|
Role subRole = null;
|
|
for (Role r : roles) {
|
|
if (r.getName().equals(rel.getSuperRole())
|
|
&& supRole == null)
|
|
supRole = r;
|
|
if (r.getName().equals(rel.getSubRole()) && subRole == null)
|
|
subRole = r;
|
|
}
|
|
|
|
// assign users to subroles
|
|
for (Subject s : supRole.getSubjects()) {
|
|
if (s instanceof User) {
|
|
User u = (User) s;
|
|
if (!u.getRoles().contains(subRole)) {
|
|
u.getRoles().add(subRole);
|
|
subRole.getSubjects().add(u);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (roles.size() == 0) {
|
|
System.out
|
|
.println("[SCVM-RBAC] No roles or users provided, generating dummy roles and users.");
|
|
Role manager = Securebpmn2Factory.eINSTANCE.createRole();
|
|
manager.setName("Manager");
|
|
manager.setId(UUID.randomUUID().toString());
|
|
Role supervisor = Securebpmn2Factory.eINSTANCE.createRole();
|
|
supervisor.setName("Supervisor");
|
|
supervisor.setId(UUID.randomUUID().toString());
|
|
Role clerk = Securebpmn2Factory.eINSTANCE.createRole();
|
|
clerk.setId(UUID.randomUUID().toString());
|
|
clerk.setName("Clerk");
|
|
roles.add(manager);
|
|
roles.add(supervisor);
|
|
roles.add(clerk);
|
|
}
|
|
|
|
if (users.size() == 0) {
|
|
for (Role role : roles) {
|
|
User user1 = Securebpmn2Factory.eINSTANCE.createUser();
|
|
user1.setUserName("user1_" + role.getName());
|
|
user1.setId("user1_" + role.getName().toLowerCase());
|
|
user1.getRoles().add(role);
|
|
User user2 = Securebpmn2Factory.eINSTANCE.createUser();
|
|
user2.setUserName("user2_" + role.getName());
|
|
user2.setId("user2_" + role.getName().toLowerCase());
|
|
user2.getRoles().add(role);
|
|
}
|
|
}
|
|
|
|
|
|
// save users to diagram so that the editor won't crash loading a
|
|
// diagram with roles that reference to the users.
|
|
// unfortunately, the attributes of roles and users do not get loaded
|
|
// correctly when opening a .activiti file.
|
|
final List<User> usersToAdd = new ArrayList<User>();
|
|
for (User u : users) {
|
|
boolean isInDiagram = false;
|
|
for (EObject o : diagram.eResource().getContents()) {
|
|
if (o instanceof User) {
|
|
User my_user = (User) o;
|
|
if (my_user.getId() != null
|
|
&& my_user.getId().equals(u.getId())) {
|
|
isInDiagram = true;
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
if (!isInDiagram) {
|
|
usersToAdd.add(u);
|
|
}
|
|
|
|
}
|
|
TransactionalEditingDomain editingDomain = TransactionUtil
|
|
.getEditingDomain(diagram);
|
|
|
|
if (!usersToAdd.isEmpty()) { // should fix aslan generation bug with automated role generation
|
|
ActivitiUiUtil.runModelChange(new Runnable() {
|
|
public void run() {
|
|
for (User u : usersToAdd) {
|
|
diagram.eResource().getContents().add(u);
|
|
}
|
|
}
|
|
}, editingDomain, "User management");
|
|
}
|
|
|
|
}
|
|
/**
|
|
* Reads a file from disk and writes its contents to a String.
|
|
*
|
|
* @param filePath
|
|
* The path to the file.
|
|
* @return The contents of the file.
|
|
* @throws IOException
|
|
* Errors that occur accessing the file.
|
|
*/
|
|
public static String readFileAsString(String filePath) throws IOException {
|
|
byte[] buffer = new byte[(int) new File(filePath).length()];
|
|
BufferedInputStream f = null;
|
|
try {
|
|
f = new BufferedInputStream(new FileInputStream(filePath));
|
|
f.read(buffer);
|
|
} finally {
|
|
if (f != null)
|
|
try {
|
|
f.close();
|
|
} catch (IOException ignored) {
|
|
}
|
|
}
|
|
return new String(buffer);
|
|
}
|
|
|
|
}
|