Formio Plugin for Camunda Tasklist

I’m currently having an issue where end-users are required to have authorization to the deployment that contains the FormIO JSON so the form actually renders. I suspect having the schema embedded within the XML may help with this but I’m not too sure how you’d support subforms with this approach.

@KenCMC Do you have this issue with embedded forms / angular forms?

What are the concerns with providing read-only access to the deployment?

When you disable access to the deployment, are your end-users able to use the “Diagram” tab in the Tasklist when viewing a task?

@StephenOTT The issue is not present with embedded forms; for a start form all a user needs authorizations for is the App (Tasklist), Process Definition, and Process Instance.

With disabled access to the deployment, end-users are able to leverage the “Diagram” tab when viewing a task. This is true for both embedded form tasks and these FormIO form tasks.

The concern with read-only access to deployment is a generic one related to access levels overall. While the FormIO JSON isn’t really “privileged” information…the various external Javascripts and full BPMN XMLs within a deployment may be. These might have some interesting control flow logic that could be considered company IP, or might have some interesting insights into our IT topology (e.g. URL prefixes, etc.).

It’s really a risk-mitigation thing. It’s not that I don’t trust my end users; but should an attacker compromise their credentials and gain access this IP would be exposed when the end-user themselves didn’t really need access to it in the first place.

I agree with your points. I am just looking for which specific aspects to override to match the expected behaviour.

When you use the Diagram Tab, The BPMN diagram is returned as a BPMN.io render and the entire BPMN is exposed:

The endpoint is something like:

http://localhost:8080/camunda/api/engine/engine/default/process-definition/BlazorProcess1:1:1a1e3c23-2512-11eb-a741-5e1a8da9f1ad/xml

we can also optionally override the “Get Form” service method if you cannot expose the deployment.

Note that the Tasklist was never really designed for “high security”. There are lots of ways for a end user to “break stuff” if they want (such as a user’s ability to read/create/modify any variables they want in the process instance)

Anything you put in your BPMN XML is “exposed” in the Tasklist in that diagram tab:

If your scripts are being stored as .js files you ~may have slightly better protection, but would need more investigation to confirm.

I appreciate the detailed feedback!

This is interesting. I never really dug into the diagram; I assumed it was encapsulated into a Base64 or something by the backend and not simply parsed in the client browser. It’s actually a little disappointing to hear as it gives me cause to more deeply dive into other possible attack vectors. :frowning:

Regardless, while it’s not desirable to provide READ * for Deployments, for now, my risk can be controlled by gating what gets deployed (e.g. code reviews, CI/CD approval pipelines) and simply knowing the limitations of the platform’s security itself. So thanks again for the heads up on some of this!

Back to the point (I’d hate to derail this thread); if we could find an elegant way to leverage subforms within an XML-embedded FormIO JSON approach then it’s definitely got my +1. I may not use it all the time for my own processes, but for mission critical/sensitive stuff it may provide an option for me to work around the security limitation.

Additionally, until Modeler gets a UX upgrade to add multiple-files in a single deployment; the XML-embedded approach would really enable more “citizen developer” adoption of this FormIO solution. (though I don’t know how big that crowd might be :slight_smile: )

Additionally, until Modeler gets a UX upgrade to add multiple-files in a single deployment; the XML-embedded approach would really enable more “citizen developer” adoption of this FormIO solution. (though I don’t know how big that crowd might be :slight_smile: )

Yes i have been asking for this for a LOOONGGGGG time: Deploy all files within a folder or same folder as BPMN - REST API Deployment · Issue #880 · camunda/camunda-modeler · GitHub


If you are a heavy user of subforms (and if yes, It would be great to get feedback/usage details on that), I was thinking about adding two layers of support (exact details not worked out, but something like:)

  1. On the extension props of the collaboration (multiple pools in a BPMN xml file)/ or on the Pool/ProcessDef you could add Name: formio_form_[formName] value: {...}. You can add as many as you want/need.
  2. Then on the StartEvent/UserTask you would write: Name: formio_xml value: [formName].

You would still have to expose the BPMN XML, and you would have to ensure all of your forms are within your BPMN file (duplicating the json if you have more than one .xml file), but you should be able to use them.

Thoughts @KenCMC?


@KenCMC here is some code that can “clean” a BPMN: Workflow-Linter/src/main/kotlin/com/github/stephenott/workflowlinter/cleaner/Cleaner.kt at master · StephenOTT/Workflow-Linter · GitHub

Allows you to define custom rules for removing potentially “sensitive” aspects of a BPMN like you described. The default code has some common scenarios (listeners, scripts in script tasks, timer configs, etc).

@StephenOTT I wouldn’t say I’m a “heavy user” of subforms; truthfully I’m still in my infancy with the Camunda ecosystem.

That said, the key use case with subforms for me is reuse. Not so much a code reuse standpoint but from a UX consistency standpoint. My end-users may not be strong technically and forced commonality on how we design forms, rather than an implied standards and hoping to catch deviations in a peer review, helps adoption.

Regarding the proposed approach, it makes sense to me. The duplication of JSON is rough (especially when considering Call Activities) but easily solvable with some deployment automation similar to your linter.

Again, for me specifically, it’s probably a corner case where I’d leverage this XML-embedded FormIO definition (e.g. working around the deployment permission issue for sensitive processes). I don’t really have any of those on deck and my default approach will always be to do as much as I can outside Modeler since it streamlines development.

Any others reading this thread; please speak up if it’d be useful!

@KenCMC would you be interested in storing form schemas as variables? Could event have a listener at the end of the process execution that deletes the variable. This would allow you to pass around schemas to sub processes, etc.

@KenCMC I have done some more review, and I think the best option to is provide a plugin that injects a custom Endpoint into the Camunda Rest API.

The endpoint respects the same permissions as the current “get deployment form” endpoints:

User Task: https://docs.camunda.org/manual/latest/reference/rest/task/get-deployed-form/
Start Form: https://docs.camunda.org/manual/latest/reference/rest/process-definition/get-deployed-start-form/

You would set the permission as you would expect with providing access to the process def.

We could very likely use the same patterns to provide variables as well so can lock down access to variables. But one thing at a time. :slight_smile:

we can use something like /forms

which would return something like:

{
    "parent": {
        "components": [
            {
                "type": "textfield",
                "key": "firstName",
                "label": "First Name - Loaded from Deployment",
                "placeholder": "Enter your first name.",
                "input": true,
                "validate": {
                    "required": true
                }
            },
            ...
        ]
    },
    "subForms": []
}

and we can add in the future “variables” as well.

Working example against the Rest API: https://github.com/StephenOTT/camunda-formio-plugin/tree/custom-forms-endpoint/formfieldvalidator/src/main/kotlin/com/github/stephenott/camunda/rest/formio/forms

Will need to determine how to add it into the WebApps API…

dev tracking as part of: https://github.com/StephenOTT/camunda-formio-plugin/issues/49

Thoughts?

Took a quick glance at your mockup and this approach certainly makes sense to me. It has the added benefit of being more natively integrated with the Camunda stack and therefore available to alternative paradigms (rather than forcing things via model definitions only).

While I’ll certainly be keeping an eye on this; I may be the only one currently with this unique constraint and I have a workaround that’s not too painless. So this really should be treated with lower priority compared to other items, especially because getting into the weeds of WebApps modifications might be somewhat difficult.

@KenCMC, I have created a Tasklist Plugin: https://github.com/StephenOTT/camunda-formio-plugin/tree/custom-forms-endpoint/tasklistplugin

This uses the SPI in the WebApps to inject the server side plugin and provide a custom endpoint(s). It even supports authorization! (authz is currently set to: StartForm: Read ProcessDef, and UserTask: Read UserTask and Read ProcessDef.

You can run the springboot module in the project to see it in action.

I will set it up soon as a standalone jar that can be brought into a web apps deployment.

The plugin exposes through the plugin api routes:

https://localhost:8080/camunda/api/tasklist/plugin/forms-plugin/default/process-definition/myProcId/forms

and https://localhost:8080/camunda/api/tasklist/plugin/forms-plugin/default/task/myTaskId/forms

where default is the engine name.

The Formio.html file will be updated to read from these URLs rather than the deployment URLs.

@StephenOTT, Apologies for the large delay here; I was pulled off to other activities and haven’t been able to touch Camunda for the last quarter. :frowning:

I think I understand the approach you’re taking here; however I’ll have to wait for a standalone JAR since I’ve not sufficiently spooled up on the spring boot approach. #NotAJavaDeveloper

On that topic, I was wondering if there is still an intent to package this plugin into a JAR we can drop into Camunda Run’s userlib as Issue #51 indicates. I’m looking to shift my production environment over to start bridging the gap between native Tomcat and spring boot; I’d love to bring along your plugin with the migration!

@StephenOTT Hello! I would like to ask you about license of this plugin. I am coding my bachelor thesis at the moment and I would like to use this plugin for it. Is it open-source? Thank you for your reply.

@StephenOTT My name is Raimundo Júnior and I would like to talk with you more about this plugin. Can you send me your e-mail? I would like to explain better to you my idea.

If you prefer, you can ping me on raimundo@institutobrasileirodebpm.com.br

By the way…it is a fantastic plugin.

I appreciate your time and your attention.

@StephenOTT I am using java spring boot embedded container and trying to use form io in tasklist. I am getting a Form Failure: No Message available error. I am using Camunda modeler to deploy both process and form json.

Here is my POM file.

<?xml version="1.0" encoding="UTF-8"?>

<modelVersion>4.0.0</modelVersion>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath/>
</parent>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${project.parent.version}</version>
            <configuration>
                <mainClass>com.bpm.workflow.Application</mainClass>
            </configuration>

            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>

        </plugin>
    </plugins>
</build>
<properties>
    <java.version>8</java.version>
</properties>

<groupId>com.example.workflow</groupId>
<artifactId>camundapostgres</artifactId>
<version>1.0.0-SNAPSHOT</version>

<packaging>jar</packaging>

<dependencies>

    <dependency>
        <groupId>org.camunda.bpm.springboot</groupId>
        <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
        <version>7.15.0</version>
    </dependency>
    <dependency>
        <groupId>org.camunda.bpm.springboot</groupId>
        <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
        <version>7.15.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>org.camunda.bpm</groupId>
        <artifactId>camunda-engine-plugin-spin</artifactId>
        <version>7.15.0</version>
    </dependency>

    <dependency>
        <groupId>org.camunda.bpm</groupId>
        <artifactId>camunda-engine-rest-openapi</artifactId>
        <version>7.13.0</version>
    </dependency>

    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>swagger-ui</artifactId>
        <version>3.30.0</version>
    </dependency>

    <!-- Lombok dependency for source code generation -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- Apache commons-collections4 for hanlding collections data -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-collections4</artifactId>
        <version>4.4</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.camunda.spin/camunda-spin-dataformat-json-jackson -->
    <dependency>
        <groupId>org.camunda.spin</groupId>
        <artifactId>camunda-spin-dataformat-json-jackson</artifactId>
        <version>1.13.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>fluent-hc</artifactId>
        <version>4.5.12</version>
    </dependency>
</dependencies>

Please help me to resolve this

HI @StephenOTT ,

Can I use this plugin with springboot java project?
looking at description it seems sample is provided using kotlin project only.

Yes. You just need to have the kotlin lib dups. If you are building the project manually, then you just need to add the code to a scr>main>kotlin folder

Hi @StephenOTT

It would be great if we can have a video tutorial about this subject (Intergaring Formio with Camunda). Its really a difficult project. I would be appreciated If you make it.

Thanks

2 Likes

I also had trouble and never managed to get the plugin installed. For me, instead of, or in addition to, a video, I would get benefit out of a sample vanilla spring-boot and/or war file project written in Java.


@StephenOTT version 7.13 can be used, but version 7.16 cannot be used