This repository has been archived on 2018-08-08. You can view files and clone it, but cannot push or open issues or pull requests.
SecureBPMN/designer/src/eu.aniketos.securebpmn/src/main/java/eu/aniketos/securebpmn/util/SecurityUtil.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);
}
}