Merge pull request #115 from sartography/feature/restricted-script-engine

change script engine to use RestrictedPython
This commit is contained in:
Kevin Burnett 2022-10-06 02:54:11 +00:00 committed by GitHub
commit 02b85f34cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 219 additions and 40 deletions

71
poetry.lock generated
View File

@ -81,10 +81,7 @@ python-versions = ">=3.7.2"
[package.dependencies]
lazy-object-proxy = ">=1.4.0"
typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""}
wrapt = [
{version = ">=1.11,<2", markers = "python_version < \"3.11\""},
{version = ">=1.14,<2", markers = "python_version >= \"3.11\""},
]
wrapt = {version = ">=1.11,<2", markers = "python_version < \"3.11\""}
[[package]]
name = "attrs"
@ -719,7 +716,7 @@ six = ">=1.3.0"
docs = ["sphinx"]
[[package]]
name = "Flask-SQLAlchemy"
name = "flask-sqlalchemy"
version = "2.5.1"
description = "Adds SQLAlchemy support to your Flask application."
category = "main"
@ -796,7 +793,7 @@ tornado = ["tornado (>=0.2)"]
[[package]]
name = "identify"
version = "2.5.5"
version = "2.5.6"
description = "File identification library for Python"
category = "dev"
optional = false
@ -1419,7 +1416,7 @@ pycryptodome = ["pyasn1", "pycryptodome (>=3.3.1,<4.0.0)"]
[[package]]
name = "python-keycloak"
version = "2.5.0"
version = "2.6.0"
description = "python-keycloak is a Python package providing access to the Keycloak API."
category = "main"
optional = false
@ -1455,14 +1452,14 @@ tzdata = {version = "*", markers = "python_version >= \"3.6\""}
[[package]]
name = "pyupgrade"
version = "2.38.2"
version = "2.38.4"
description = "A tool to automatically upgrade syntax for newer versions."
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
tokenize-rt = ">=3.2.0"
tokenize-rt = "<5"
[[package]]
name = "PyYAML"
@ -1520,6 +1517,18 @@ python-versions = "*"
[package.dependencies]
requests = ">=2.0.1,<3.0.0"
[[package]]
name = "RestrictedPython"
version = "5.2"
description = "RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.11"
[package.extras]
docs = ["Sphinx", "sphinx-rtd-theme"]
test = ["pytest", "pytest-mock"]
[[package]]
name = "restructuredtext-lint"
version = "1.4.0"
@ -1567,7 +1576,7 @@ python-versions = ">=3.5"
[[package]]
name = "safety"
version = "2.2.0"
version = "2.2.1"
description = "Checks installed dependencies for known vulnerabilities and licenses."
category = "dev"
optional = false
@ -1827,7 +1836,7 @@ test = ["pytest"]
[[package]]
name = "SpiffWorkflow"
version = "1.1.7"
description = ""
description = "A workflow framework and BPMN/DMN Processor"
category = "main"
optional = false
python-versions = "*"
@ -1845,7 +1854,7 @@ pytz = "*"
type = "git"
url = "https://github.com/sartography/SpiffWorkflow"
reference = "main"
resolved_reference = "76947aa98d81826b88b2eefd05ebae4427b00e02"
resolved_reference = "804889ce3b993c909ea795047dd18ea0ed6e5a99"
[[package]]
name = "SQLAlchemy"
@ -1959,7 +1968,7 @@ test = ["mypy", "pytest", "typing-extensions"]
[[package]]
name = "types-pytz"
version = "2022.2.1.0"
version = "2022.4.0.0"
description = "Typing stubs for pytz"
category = "main"
optional = false
@ -1967,7 +1976,7 @@ python-versions = "*"
[[package]]
name = "types-requests"
version = "2.28.11"
version = "2.28.11.1"
description = "Typing stubs for requests"
category = "main"
optional = false
@ -2156,8 +2165,8 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=
[metadata]
lock-version = "1.1"
python-versions = "^3.9"
content-hash = "7a3c07a2eef00685adbf44b6e26b740e20fc52bf85e916b6c171b13d4fcc6dc9"
python-versions = ">=3.9,<3.11"
content-hash = "f64a06b52db52800be7400b19d7ab7906a54d5b3ecc625dd2fc886e69ff775ac"
[metadata.files]
alabaster = [
@ -2433,7 +2442,7 @@ Flask-RESTful = [
{file = "Flask-RESTful-0.3.9.tar.gz", hash = "sha256:ccec650b835d48192138c85329ae03735e6ced58e9b2d9c2146d6c84c06fa53e"},
{file = "Flask_RESTful-0.3.9-py2.py3-none-any.whl", hash = "sha256:4970c49b6488e46c520b325f54833374dc2b98e211f1b272bd4b0c516232afe2"},
]
Flask-SQLAlchemy = [
flask-sqlalchemy = [
{file = "Flask-SQLAlchemy-2.5.1.tar.gz", hash = "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912"},
{file = "Flask_SQLAlchemy-2.5.1-py2.py3-none-any.whl", hash = "sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390"},
]
@ -2510,8 +2519,8 @@ gunicorn = [
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
]
identify = [
{file = "identify-2.5.5-py2.py3-none-any.whl", hash = "sha256:ef78c0d96098a3b5fe7720be4a97e73f439af7cf088ebf47b620aeaa10fadf97"},
{file = "identify-2.5.5.tar.gz", hash = "sha256:322a5699daecf7c6fd60e68852f36f2ecbb6a36ff6e6e973e0d2bb6fca203ee6"},
{file = "identify-2.5.6-py2.py3-none-any.whl", hash = "sha256:b276db7ec52d7e89f5bc4653380e33054ddc803d25875952ad90b0f012cbcdaa"},
{file = "identify-2.5.6.tar.gz", hash = "sha256:6c32dbd747aa4ceee1df33f25fed0b0f6e0d65721b15bd151307ff7056d50245"},
]
idna = [
{file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
@ -2978,8 +2987,8 @@ python-jose = [
{file = "python_jose-3.3.0-py2.py3-none-any.whl", hash = "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a"},
]
python-keycloak = [
{file = "python-keycloak-2.5.0.tar.gz", hash = "sha256:b401d2c67dc1b9e2dbb3309ef2012c2d178584925dc14bd07f6bd2416e5e3ff8"},
{file = "python_keycloak-2.5.0-py3-none-any.whl", hash = "sha256:ed1c1935ceaf5d7f928b1b3ab945130f7d54685e4b17da053dbc7bfee0c0271e"},
{file = "python-keycloak-2.6.0.tar.gz", hash = "sha256:08c530ff86f631faccb8033d9d9345cc3148cb2cf132ff7564f025292e4dbd96"},
{file = "python_keycloak-2.6.0-py3-none-any.whl", hash = "sha256:a1ce102b978beb56d385319b3ca20992b915c2c12d15a2d0c23f1104882f3fb6"},
]
pytz = [
{file = "pytz-2022.4-py2.py3-none-any.whl", hash = "sha256:2c0784747071402c6e99f0bafdb7da0fa22645f06554c7ae06bf6358897e9c91"},
@ -2990,8 +2999,8 @@ pytz-deprecation-shim = [
{file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"},
]
pyupgrade = [
{file = "pyupgrade-2.38.2-py2.py3-none-any.whl", hash = "sha256:41bb9a9fd48fe57163b0dacffff433d6d5a63a0f7c2402918917b5f1a533342b"},
{file = "pyupgrade-2.38.2.tar.gz", hash = "sha256:a5d778c9de0b53975c6a9eac2d0df5adfad244a9f7d7993d8a114223ebbda367"},
{file = "pyupgrade-2.38.4-py2.py3-none-any.whl", hash = "sha256:944ff993c396ddc2b9012eb3de4cda138eb4c149b22c6c560d4c8bfd0e180982"},
{file = "pyupgrade-2.38.4.tar.gz", hash = "sha256:1eb43a49f416752929741ba4d706bf3f33593d3cac9bdc217fc1ef55c047c1f4"},
]
PyYAML = [
{file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
@ -3123,6 +3132,10 @@ requests-toolbelt = [
{file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"},
{file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"},
]
RestrictedPython = [
{file = "RestrictedPython-5.2-py2.py3-none-any.whl", hash = "sha256:fdf8621034c5dcb990a2a198f232f66b2d48866dd16d848e00ac7d187ae452ba"},
{file = "RestrictedPython-5.2.tar.gz", hash = "sha256:634da1f6c5c122a262f433b083ee3d17a9a039f8f1b3778597efb47461cd361b"},
]
restructuredtext-lint = [
{file = "restructuredtext_lint-1.4.0.tar.gz", hash = "sha256:1b235c0c922341ab6c530390892eb9e92f90b9b75046063e047cacfb0f050c45"},
]
@ -3167,8 +3180,8 @@ rsa = [
{file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"},
]
safety = [
{file = "safety-2.2.0-py3-none-any.whl", hash = "sha256:b1a0f4c34fb41c502a7a5c54774c18376da382bc9d866ee26b39b2c747c0de40"},
{file = "safety-2.2.0.tar.gz", hash = "sha256:6745de12acbd60a58001fe66cb540355187d7b991b30104d9ef14ff4e4826073"},
{file = "safety-2.2.1-py3-none-any.whl", hash = "sha256:b0049b3f0af4128834f6bc5e6cd23a20ccc28303d6c92cbc019b71f1f06bc038"},
{file = "safety-2.2.1.tar.gz", hash = "sha256:d8b48c46ac6628bb83441b7dddc4756cfe2582abe13a112ee6e4ef1a34aad032"},
]
sentry-sdk = [
{file = "sentry-sdk-1.9.0.tar.gz", hash = "sha256:f185c53496d79b280fe5d9d21e6572aee1ab802d3354eb12314d216cfbaa8d30"},
@ -3324,12 +3337,12 @@ typeguard = [
{file = "typeguard-2.13.3.tar.gz", hash = "sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4"},
]
types-pytz = [
{file = "types-pytz-2022.2.1.0.tar.gz", hash = "sha256:47cfb19c52b9f75896440541db392fd312a35b279c6307a531db71152ea63e2b"},
{file = "types_pytz-2022.2.1.0-py3-none-any.whl", hash = "sha256:50ead2254b524a3d4153bc65d00289b66898060d2938e586170dce918dbaf3b3"},
{file = "types-pytz-2022.4.0.0.tar.gz", hash = "sha256:17d66e4b16e80ceae0787726f3a22288df7d3f9fdebeb091dc64b92c0e4ea09d"},
{file = "types_pytz-2022.4.0.0-py3-none-any.whl", hash = "sha256:950b0f3d64ed5b03a3e29c1e38fe2be8371c933c8e97922d0352345336eb8af4"},
]
types-requests = [
{file = "types-requests-2.28.11.tar.gz", hash = "sha256:7ee827eb8ce611b02b5117cfec5da6455365b6a575f5e3ff19f655ba603e6b4e"},
{file = "types_requests-2.28.11-py3-none-any.whl", hash = "sha256:af5f55e803cabcfb836dad752bd6d8a0fc8ef1cd84243061c0e27dee04ccf4fd"},
{file = "types-requests-2.28.11.1.tar.gz", hash = "sha256:02b1806c5b9904edcd87fa29236164aea0e6cdc4d93ea020cd615ef65cb43d65"},
{file = "types_requests-2.28.11.1-py3-none-any.whl", hash = "sha256:1ff2c1301f6fe58b5d1c66cdf631ca19734cb3b1a4bbadc878d75557d183291a"},
]
types-urllib3 = [
{file = "types-urllib3-1.26.25.tar.gz", hash = "sha256:5aef0e663724eef924afa8b320b62ffef2c1736c1fa6caecfc9bc6c8ae2c3def"},

View File

@ -16,9 +16,9 @@ classifiers = [
Changelog = "https://github.com/sartography/spiffworkflow-backend/releases"
[tool.poetry.dependencies]
python = "^3.9"
python = ">=3.9,<3.11"
click = "^8.0.1"
flask = "*"
flask = "2.1.3"
flask-admin = "*"
flask-bcrypt = "*"
flask-cors = "*"
@ -52,6 +52,8 @@ python-keycloak = "^2.5.0"
APScheduler = "^3.9.1"
types-requests = "^2.28.6"
Jinja2 = "^3.1.2"
RestrictedPython = "^5.2"
Flask-SQLAlchemy = "^2.5.1"
[tool.poetry.dev-dependencies]

View File

@ -1,8 +1,10 @@
"""Process_instance_processor."""
import decimal
import json
import logging
import os
import time
from datetime import datetime
from typing import Any
from typing import Callable
from typing import Dict
@ -16,9 +18,11 @@ from flask import current_app
from flask_bpmn.api.api_error import ApiError
from flask_bpmn.models.db import db
from lxml import etree # type: ignore
from RestrictedPython import safe_globals # type: ignore
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException # type: ignore
from SpiffWorkflow.bpmn.parser.ValidationException import ValidationException # type: ignore
from SpiffWorkflow.bpmn.PythonScriptEngine import Box # type: ignore
from SpiffWorkflow.bpmn.PythonScriptEngine import DEFAULT_GLOBALS
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
from SpiffWorkflow.bpmn.serializer import BpmnWorkflowSerializer # type: ignore
from SpiffWorkflow.bpmn.specs.BpmnProcessSpec import BpmnProcessSpec # type: ignore
@ -76,9 +80,18 @@ from spiffworkflow_backend.services.service_task_service import ServiceTaskServi
from spiffworkflow_backend.services.spec_file_service import SpecFileService
from spiffworkflow_backend.services.user_service import UserService
# Sorry about all this crap. I wanted to move this thing to another file, but
# importing a bunch of types causes circular imports.
class ProcessInstanceProcessorError(Exception):
"""ProcessInstanceProcessorError."""
DEFAULT_GLOBALS.update(
{
"datetime": datetime,
"time": time,
"decimal": decimal,
}
)
# This will overwrite the standard builtins
DEFAULT_GLOBALS.update(safe_globals)
class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
@ -88,6 +101,10 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
scripts directory available for execution.
"""
def __init__(self) -> None:
"""__init__."""
super().__init__(default_globals=DEFAULT_GLOBALS)
def __get_augment_methods(self, task: SpiffTask) -> Dict[str, Callable]:
"""__get_augment_methods."""
return Script.generate_augmented_list(task, current_app.env)
@ -143,6 +160,10 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
return ServiceTaskService.scripting_additions()
class ProcessInstanceProcessorError(Exception):
"""ProcessInstanceProcessorError."""
class MyCustomParser(BpmnDmnParser): # type: ignore
"""A BPMN and DMN parser that can also parse spiffworkflow-specific extensions."""

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1wr5g8a" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.11.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
<bpmn:process id="dangerous" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1oq5kne</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1oq5kne" sourceRef="StartEvent_1" targetRef="import_os" />
<bpmn:endEvent id="Event_05ctc03">
<bpmn:incoming>Flow_1r45j8e</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_1r45j8e" sourceRef="import_os" targetRef="Event_05ctc03" />
<bpmn:scriptTask id="import_os" name="Import os">
<bpmn:incoming>Flow_1oq5kne</bpmn:incoming>
<bpmn:outgoing>Flow_1r45j8e</bpmn:outgoing>
<bpmn:script>import os
env = os.environ
</bpmn:script>
</bpmn:scriptTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="dangerous">
<bpmndi:BPMNEdge id="Flow_1oq5kne_di" bpmnElement="Flow_1oq5kne">
<di:waypoint x="215" y="117" />
<di:waypoint x="270" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1r45j8e_di" bpmnElement="Flow_1r45j8e">
<di:waypoint x="370" y="117" />
<di:waypoint x="432" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_05ctc03_di" bpmnElement="Event_05ctc03">
<dc:Bounds x="432" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1seqmoq_di" bpmnElement="import_os">
<dc:Bounds x="270" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1wr5g8a" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.11.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
<bpmn:process id="dangerous" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1oq5kne</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1oq5kne" sourceRef="StartEvent_1" targetRef="read_etc_passwd" />
<bpmn:endEvent id="Event_05ctc03">
<bpmn:incoming>Flow_1r45j8e</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_1r45j8e" sourceRef="read_etc_passwd" targetRef="Event_05ctc03" />
<bpmn:scriptTask id="read_etc_passwd" name="Read /etc/passwd">
<bpmn:incoming>Flow_1oq5kne</bpmn:incoming>
<bpmn:outgoing>Flow_1r45j8e</bpmn:outgoing>
<bpmn:script>user_list = open('/etc/passwd').read()
env = os.environ
</bpmn:script>
</bpmn:scriptTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="dangerous">
<bpmndi:BPMNEdge id="Flow_1r45j8e_di" bpmnElement="Flow_1r45j8e">
<di:waypoint x="370" y="117" />
<di:waypoint x="432" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1oq5kne_di" bpmnElement="Flow_1oq5kne">
<di:waypoint x="215" y="117" />
<di:waypoint x="270" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_05ctc03_di" bpmnElement="Event_05ctc03">
<dc:Bounds x="432" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1seqmoq_di" bpmnElement="read_etc_passwd">
<dc:Bounds x="270" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -52,7 +52,7 @@
<bpmn:scriptTask id="set_topic" name="Set Topic" scriptFormat="python">
<bpmn:incoming>Flow_10conab</bpmn:incoming>
<bpmn:outgoing>Flow_1ihr88m</bpmn:outgoing>
<bpmn:script>import time
<bpmn:script>
timestamp = time.time()
the_topica = f"first_conversation_a_{timestamp}"
the_topicb = f"first_conversation_b_{timestamp}"

View File

@ -58,7 +58,7 @@
<bpmn:scriptTask id="set_topic_one" name="Set Topic One" scriptFormat="python">
<bpmn:incoming>Flow_10conab</bpmn:incoming>
<bpmn:outgoing>Flow_1ihr88m</bpmn:outgoing>
<bpmn:script>import time
<bpmn:script>
timestamp = time.time()
topic_one_a = f"topic_one_a_conversation_{timestamp}"
topic_one_b = f"topic_one_b_conversation_{timestamp}"
@ -80,7 +80,7 @@ del time</bpmn:script>
<bpmn:scriptTask id="set_topic_two" name="Set Topic Two">
<bpmn:incoming>Flow_0n4m9ti</bpmn:incoming>
<bpmn:outgoing>Flow_0q3clix</bpmn:outgoing>
<bpmn:script>import time
<bpmn:script>
timestamp = time.time()
topic_two_a = f"topic_two_a_conversation_{timestamp}"
topic_two_b = f"topic_two_b_conversation_{timestamp}"

View File

@ -24,10 +24,11 @@
</bpmn:extensionElements>
<bpmn:incoming>Flow_0niwe1y</bpmn:incoming>
<bpmn:outgoing>Flow_0htxke7</bpmn:outgoing>
<bpmn:script>if 'hey' in locals():
hey = True
else:
something_else = True</bpmn:script>
<bpmn:script>try:
if not hey:
hey = True
except:
something_else = True</bpmn:script>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_0niwe1y" sourceRef="Activity_03fldr6" targetRef="script_with_unit_test_id" />
<bpmn:scriptTask id="Activity_03fldr6" name="Set var">

View File

@ -0,0 +1,58 @@
"""Test_various_bpmn_constructs."""
import pytest
from flask.app import Flask
from flask_bpmn.api.api_error import ApiError
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
from spiffworkflow_backend.services.process_instance_processor import (
ProcessInstanceProcessor,
)
class TestOpenFile(BaseTest):
"""TestVariousBpmnConstructs."""
def test_dot_notation(
self, app: Flask, with_db_and_bpmn_file_cleanup: None
) -> None:
"""Test_form_data_conversion_to_dot_dict."""
process_model = load_test_spec(
"dangerous",
bpmn_file_name="read_etc_passwd.bpmn",
process_model_source_directory="dangerous-scripts",
)
self.find_or_create_user()
process_instance = self.create_process_instance_from_process_model(
process_model
)
processor = ProcessInstanceProcessor(process_instance)
with pytest.raises(ApiError) as exception:
processor.do_engine_steps(save=True)
assert "name 'open' is not defined" in str(exception.value)
class TestImportModule(BaseTest):
"""TestVariousBpmnConstructs."""
def test_dot_notation(
self, app: Flask, with_db_and_bpmn_file_cleanup: None
) -> None:
"""Test_form_data_conversion_to_dot_dict."""
process_model = load_test_spec(
"dangerous",
bpmn_file_name="read_env.bpmn",
process_model_source_directory="dangerous-scripts",
)
self.find_or_create_user()
process_instance = self.create_process_instance_from_process_model(
process_model
)
processor = ProcessInstanceProcessor(process_instance)
with pytest.raises(ApiError) as exception:
processor.do_engine_steps(save=True)
assert "ImportError:__import__ not found" in str(exception.value)