Skip to content

Commit

Permalink
Merge branch 'master' into github
Browse files Browse the repository at this point in the history
  • Loading branch information
dofs197 committed Aug 23, 2020
2 parents a0924a2 + 02f5614 commit 60b3d9a
Show file tree
Hide file tree
Showing 70 changed files with 1,450 additions and 393 deletions.
10 changes: 10 additions & 0 deletions wfe-core/src/main/java/ru/runa/wfe/commons/IoCommons.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ public static String getExtensionDirPath() {
return path + "wfe.custom";
}

public static String getExcelStorageDirPath() {
String path = IoCommons.getAppServerDirPath();
if (path != null) {
path += "/";
} else {
path = "";
}
return path + "wfe.excelstorage";
}

public static File[] getJarFiles(File directory) {
return directory.listFiles(new PatternFilenameFilter(".*\\.jar"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public class SystemProperties {
public static PropertyResources getResources() {
return RESOURCES;
}

public static boolean isTaskDelegationEnabled() {
return RESOURCES.getBooleanProperty("task.delegation.enabled", true);
}

/**
* Production or development mode?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.common.collect.Sets;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
Expand All @@ -26,6 +27,7 @@
import ru.runa.wfe.InternalApplicationException;
import ru.runa.wfe.commons.IoCommons;
import ru.runa.wfe.commons.xml.XmlUtils;
import ru.runa.wfe.var.VariableProvider;

public class DataSourceStorage implements DataSourceStuff {

Expand Down Expand Up @@ -60,7 +62,7 @@ private static synchronized void registerDrivers() {
if (urls.isEmpty()) {
return;
}
URLClassLoader urlClassLoader = new URLClassLoader(urls.toArray(new URL[] {}));
URLClassLoader urlClassLoader = new URLClassLoader(urls.toArray(new URL[]{}));
JdbcDataSourceType[] dsTypes = JdbcDataSourceType.values();
for (JdbcDataSourceType dsType : dsTypes) {
if (!registeredDsTypes.contains(dsType)) {
Expand Down Expand Up @@ -137,6 +139,16 @@ public static DataSource getDataSource(String dsName) {
return dataSource;
}

public static DataSource parseDataSource(String s, VariableProvider variableProvider) {
if (!s.startsWith(DataSourceStuff.PATH_PREFIX_DATA_SOURCE) && !s.startsWith(DataSourceStuff.PATH_PREFIX_DATA_SOURCE_VARIABLE)) {
return null;
}
final String dsName = s.startsWith(DataSourceStuff.PATH_PREFIX_DATA_SOURCE) ?
s.substring(s.indexOf(':') + 1) :
(String) variableProvider.getValue(s.substring(s.indexOf(':') + 1));
return DataSourceStorage.getDataSource(dsName);
}

public static List<DataSource> getAllDataSources() {
List<DataSource> all = Lists.newArrayList();
for (String dsName : getNames()) {
Expand Down Expand Up @@ -166,13 +178,10 @@ public static void save(byte[] content) {

/**
* Saves the data source properties to the local storage.
*
* @param content
* - the data source properties content.
* @param force
* - force to overwrite if the data source already exists.
* @param preservePassword
* - if true is passed then the old data source password won't be changed.
*
* @param content - the data source properties content.
* @param force - force to overwrite if the data source already exists.
* @param preservePassword - if true is passed then the old data source password won't be changed.
* @return true if the method succeed, false if the data source with the given name has existed and the force argument is false.
*/
public static boolean save(byte[] content, boolean force, boolean preservePassword) {
Expand Down Expand Up @@ -217,6 +226,12 @@ public static boolean save(byte[] content, boolean force, boolean preservePasswo
public static byte[] restore(String dsName) {
try {
return FileCopyUtils.copyToByteArray(new File(getStorageDir(), dsName + DATA_SOURCE_FILE_SUFFIX));
} catch (FileNotFoundException e) {
if (DataSourceStuff.INTERNAL_STORAGE_DATA_SOURCE_NAME.equals(dsName)) {
log.warn(DataSourceStuff.INTERNAL_STORAGE_DATA_SOURCE_NAME + " does not exist. Creating one", e);
return ExcelStorageInitiator.init();
}
throw new InternalApplicationException(e);
} catch (IOException e) {
throw new InternalApplicationException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public interface DataSourceStuff {

String JNDI_NAME_SAMPLE = "jboss/datasources/<DS>";

String INTERNAL_STORAGE_DATA_SOURCE_NAME = "InternalStorage";

static String adjustUrl(JdbcDataSource jds) {
String url = jds.getUrl();
String dbName = Strings.isNullOrEmpty(jds.getDbName()) ? "__DB_UNDEFINED__" : jds.getDbName();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ru.runa.wfe.datasource;

import java.io.File;
import lombok.extern.apachecommons.CommonsLog;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import ru.runa.wfe.commons.IoCommons;
import ru.runa.wfe.commons.xml.XmlUtils;

/**
* @author Alekseev Mikhail
* @since #1766
*/
@CommonsLog
public class ExcelStorageInitiator {
@SuppressWarnings("ResultOfMethodCallIgnored")
public static synchronized byte[] init() {
if (DataSourceStorage.getNames().contains(DataSourceStuff.INTERNAL_STORAGE_DATA_SOURCE_NAME)) {
return DataSourceStorage.restore(DataSourceStuff.INTERNAL_STORAGE_DATA_SOURCE_NAME);
}

final String excelStorageDirPath = IoCommons.getExcelStorageDirPath();
new File(excelStorageDirPath).mkdir();
log.info("Created " + excelStorageDirPath);

final Document document = DocumentHelper.createDocument();
document.addElement(DataSourceStuff.ELEMENT_DATA_SOURCE)
.addAttribute(DataSourceStuff.ATTR_NAME, DataSourceStuff.INTERNAL_STORAGE_DATA_SOURCE_NAME)
.addAttribute(DataSourceStuff.ATTR_TYPE, DataSourceType.Excel.name())
.addElement(DataSourceStuff.ELEMENT_FILE_PATH).addText(excelStorageDirPath);
final byte[] internalStorageDs = XmlUtils.save(document, OutputFormat.createPrettyPrint());
DataSourceStorage.save(internalStorageDs, true, false);
log.info(DataSourceStuff.INTERNAL_STORAGE_DATA_SOURCE_NAME + " is saved");

return internalStorageDs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
Expand Down Expand Up @@ -45,6 +46,7 @@
import ru.runa.wfe.lang.Transition;
import ru.runa.wfe.lang.VariableContainerNode;
import ru.runa.wfe.lang.bpmn2.CatchEventNode;
import ru.runa.wfe.lang.bpmn2.DataStore;
import ru.runa.wfe.lang.bpmn2.EndToken;
import ru.runa.wfe.lang.bpmn2.ExclusiveGateway;
import ru.runa.wfe.lang.bpmn2.MessageEventType;
Expand All @@ -56,6 +58,7 @@
public class BpmnXmlReader {
private static final String RUNA_NAMESPACE = "http://runa.ru/wfe/xml";
private static final String PROCESS = "process";
private static final String DATA_STORE = "dataStore";
private static final String EXTENSION_ELEMENTS = "extensionElements";
private static final String IS_EXECUTABLE = "isExecutable";
private static final String PROPERTY = "property";
Expand Down Expand Up @@ -130,6 +133,7 @@ public class BpmnXmlReader {
private final Document document;

private static Map<String, Class<? extends Node>> nodeTypes = Maps.newHashMap();

static {
nodeTypes.put(USER_TASK, TaskNode.class);
nodeTypes.put(MULTI_TASK, MultiTaskNode.class);
Expand All @@ -138,6 +142,7 @@ public class BpmnXmlReader {
nodeTypes.put(EXCLUSIVE_GATEWAY, ExclusiveGateway.class);
nodeTypes.put(PARALLEL_GATEWAY, ParallelGateway.class);
nodeTypes.put(TEXT_ANNOTATION, TextAnnotation.class);
nodeTypes.put(DATA_STORE, DataStore.class);
// back compatibility v < 4.3.0
nodeTypes.put(SEND_TASK, SendMessageNode.class);
nodeTypes.put(RECEIVE_TASK, CatchEventNode.class);
Expand All @@ -154,6 +159,7 @@ public BpmnXmlReader(Document document) {
public ProcessDefinition readProcessDefinition(ProcessDefinition processDefinition) {
try {
Element definitionsElement = document.getRootElement();
readDataStores(processDefinition, definitionsElement.elements(DATA_STORE));
Element process = definitionsElement.element(PROCESS);
processDefinition.setName(process.attributeValue(NAME));
Map<String, String> processProperties = parseExtensionProperties(process);
Expand Down Expand Up @@ -521,4 +527,11 @@ private void readActionHandlers(ProcessDefinition processDefinition, GraphElemen
}
}

private void readDataStores(ProcessDefinition processDefinition, List<Element> dataStoreElements) {
for (Element dataStoreElement : dataStoreElements) {
final Node node = ApplicationContextFactory.createAutowiredBean(nodeTypes.get(DATA_STORE));
node.setProcessDefinition(processDefinition);
readNode(processDefinition, dataStoreElement, Collections.emptyMap(), node);
}
}
}
17 changes: 17 additions & 0 deletions wfe-core/src/main/java/ru/runa/wfe/lang/bpmn2/DataStore.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ru.runa.wfe.lang.bpmn2;

import ru.runa.wfe.execution.ExecutionContext;
import ru.runa.wfe.lang.Node;
import ru.runa.wfe.lang.NodeType;

public class DataStore extends Node {
@Override
public NodeType getNodeType() {
return NodeType.TEXT_ANNOTATION;
}

@Override
protected void execute(ExecutionContext executionContext) throws Exception {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ private List<String> addFilters() {
// TODO Largely duplicates PermissionDAO logic. After (if ever) BatchPresentation uses QueryDSL, try to merge duplicates.
private List<String> addSecureCheck() {
List<String> result = new LinkedList<>();
RestrictionsToPermissions pp = parameters.getPermissionRestrictions();
RestrictionsToPermissions pp = (parameters.getPermissionRestrictions()==null)?null:parameters.getPermissionRestrictions().cloneCheckRequired();
if (pp == null) {
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package ru.runa.wfe.presentation.hibernate;

import java.util.Arrays;
import org.springframework.util.Assert;
import ru.runa.wfe.security.Permission;
import ru.runa.wfe.security.SecuredObjectType;
import ru.runa.wfe.security.SecurityCheckProperties;
import ru.runa.wfe.user.User;

/**
* Restrictions to load only objects with specified permission granted for user.
*/
public class RestrictionsToPermissions {

/**
* User which must has permission on queried objects. Queries only objects with condition: at least one executor from (user + its groups)
* must have 'permission' with 'securedObjectTypes'. Can be null.
Expand All @@ -35,4 +38,23 @@ public RestrictionsToPermissions(User user, Permission permission, SecuredObject
this.permission = permission;
this.types = types;
}

protected RestrictionsToPermissions cloneCheckRequired() {
SecuredObjectType[] resTypes = new SecuredObjectType[types.length];
int n = 0;
for (int i = 0; i < types.length; i++) {
if (types[i] != null && SecurityCheckProperties.isPermissionCheckRequired(types[i])) {
resTypes[n] = types[i];
n++;
}
}
if (n == 0) {
return null;
} else {
resTypes = Arrays.copyOf(resTypes, n);
}
RestrictionsToPermissions res = new RestrictionsToPermissions(this.user, this.permission, resTypes);
return res;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import static ru.runa.wfe.security.Permission.UPDATE_ACTOR_STATUS;
import static ru.runa.wfe.security.Permission.VIEW_LOGS;
import static ru.runa.wfe.security.Permission.VIEW_TASKS;
import static ru.runa.wfe.security.Permission.DELEGATE_TASKS;

/**
* Extracted from class Permission because permission-to-securedObjectType applicability is separate piece of logic,
Expand Down Expand Up @@ -216,15 +217,15 @@ public static void check(SecuredObject obj, Collection<Permission> permissions)
.defaults(READ)
.hidden(READ_PERMISSIONS);

add(SecuredObjectType.EXECUTOR, READ, UPDATE_PERMISSIONS, UPDATE, UPDATE_ACTOR_STATUS, VIEW_TASKS)
add(SecuredObjectType.EXECUTOR, READ, UPDATE_PERMISSIONS, UPDATE, UPDATE_ACTOR_STATUS, VIEW_TASKS, DELEGATE_TASKS)
.defaults(READ)
.hidden(READ_PERMISSIONS);

add(SecuredObjectType.PROCESS, READ, UPDATE_PERMISSIONS, CANCEL)
add(SecuredObjectType.PROCESS, READ, UPDATE_PERMISSIONS, CANCEL, UPDATE, DELETE, START_PROCESS, CANCEL_PROCESS)
.defaults(READ)
.hidden(READ_PERMISSIONS);

add(SecuredObjectType.RELATION, READ, UPDATE_PERMISSIONS, UPDATE)
add(SecuredObjectType.RELATION, READ, UPDATE_PERMISSIONS, UPDATE, DELETE)
.defaults(READ)
.hidden(READ_PERMISSIONS);

Expand All @@ -243,5 +244,9 @@ public static void check(SecuredObject obj, Collection<Permission> permissions)
add(SecuredObjectType.SYSTEM, READ, UPDATE_PERMISSIONS, LOGIN, CHANGE_SELF_PASSWORD, CREATE_EXECUTOR, CREATE_DEFINITION, VIEW_LOGS)
.defaults(LOGIN)
.hidden(READ_PERMISSIONS);

add(SecuredObjectType.DATASOURCES, READ, UPDATE_PERMISSIONS, UPDATE)
.defaults(READ)
.hidden(READ_PERMISSIONS);
}
}
4 changes: 4 additions & 0 deletions wfe-core/src/main/java/ru/runa/wfe/security/Permission.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,8 @@ public boolean equals(Object obj) {
public static final Permission UPDATE_PERMISSIONS = new Permission("UPDATE_PERMISSIONS");

public static final Permission VIEW_TASKS = new Permission("VIEW_TASKS");

public static final Permission DELEGATE_TASKS = new Permission("DELEGATE_TASKS");

public static final Permission ADD_ACTOR_TO_GROUP = new Permission("ADD_ACTOR_TO_GROUP");
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,11 @@ public List<Long> getIdsByNames(SecuredObjectType type, Set<String> names) {
Set<String> missingNames = new HashSet<>(names);
boolean isDef = type.equals(SecuredObjectType.DEFINITION);
for (Tuple t : tt) {
if(isDef)
if(isDef) {
foundIds.add(ApplicationContextFactory.getDeploymentDAO().getNotNull(t.get(0, Long.class)).getIdentifiableId());
else
} else {
foundIds.add(t.get(0, Long.class));
}
missingNames.remove(t.get(1, String.class));
}
if (!missingNames.isEmpty()) {
Expand Down Expand Up @@ -235,5 +236,7 @@ public SecuredObject findById(Long id) {
});

add(SecuredSingleton.SYSTEM);

add(SecuredSingleton.DATASOURCES);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ public boolean equals(Object obj) {

public static final SecuredObjectType REPORTS = new SecuredObjectType("REPORTS", true);
public static final SecuredObjectType REPORT = new SecuredObjectType("REPORT", REPORTS);

public static final SecuredObjectType SYSTEM = new SecuredObjectType("SYSTEM", true);

public static final SecuredObjectType DATASOURCES = new SecuredObjectType("DATASOURCES", true);

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,5 @@ public final SecuredObjectType getSecuredObjectType() {
public static final SecuredSingleton RELATIONS = new SecuredSingleton(SecuredObjectType.RELATIONS);
public static final SecuredSingleton REPORTS = new SecuredSingleton(SecuredObjectType.REPORTS);
public static final SecuredSingleton SYSTEM = new SecuredSingleton(SecuredObjectType.SYSTEM);
public static final SecuredSingleton DATASOURCES = new SecuredSingleton(SecuredObjectType.DATASOURCES);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ru.runa.wfe.security;

import ru.runa.wfe.commons.PropertyResources;

public class SecurityCheckProperties {
public static final String CONFIG_FILE_NAME = "securitycheck.properties";
private static final PropertyResources RESOURCES = new PropertyResources(CONFIG_FILE_NAME);

public static boolean isPermissionCheckRequired(SecuredObjectType securedObjectType) {
return RESOURCES.getBooleanProperty("permission.check.required." + securedObjectType.getName(), false);
}
}
Loading

0 comments on commit 60b3d9a

Please sign in to comment.