Skip to main content
Version: 1.13.x.x LTS

nevisWorkflow

Concept Description and Technical Architecture

Architecture overview

This chapter provides a high-level feature-oriented view of the nevisWorkflow architecture and the context in which it is used.

Features

nevisWorkflow is a Java-based workflow and process automation component of the Nevis security integration framework. As a process automation solution, it offers the functionality required to run, manage and analyze processes. It is usually deployed with the following Nevis components:

  • nevisProxy
  • nevisAuth
  • nevisIDM
  • nevisAdmin
nevisWorkflow deployment overview

Some major advantages of nevisWorkflow:

  • Embedded process engine to handle any type of BPMN 2.0 workflows
  • Easy deployment and management of processes
  • Allows process participants to quickly identify the tasks that must be handled
  • Flexible search mechanism to find relevant processes and its tasks

Web GUI

The WEB GUI of nevisWorkflow offers an easy-to-use task and process management. Also the administration of the processes can be handled by the GUI, i.e., starting and cancelling processes. Started processes and their tasks are organized into lists. Logged-in users only see tasks and started process instances that are in some way related to the users, e.g., tasks that are assigned to the logged-in user.

For an overview of all supported web browsers, see the chapter Browser Support Policy in NEVIS in the Nevis Product Lifetime and Platform Support Matrix guide.

REST interface

nevisWorkflow exposes a REST API that allows interacting with the different processes and their tasks. A more detailed description of the REST interface can be found in the chapter REST interface.

Technical architecture

System overview

Client tier

Interface for user interaction, either via the web application or via SOAP calls from a third-party component.

Access tier

Secure reverse proxy (nevisProxy), single point of entry for applications that enables a physical separation of networks. Manages user authentication and authorization in cooperation with the authentication service.

Presentation tier

Visualization of data from business tier.

Business tier

Implementation of the business logic as a set of services and modules.

Resource tier

Persistency management via a directory service (LDAP) or a database (for example MySQL or Oracle).

Installation and Integration

Installation

Database customization

This guide describes how to customize the database that nevisWorkflow uses. The customization is based on properties that are provided, and on the sql scripts that are needed for the database setup.

If no customization is required, the default database parameters of nevisWorkflow can be used and this section can be skipped.

The following steps need to be taken for the customization of the database:

  1. Edit the database property file (db.properties)
  • This property file can be found under the directory /opt/neviswf/templates/conf/
  • The following properties can be specified there:
Database property nameDescription
db.oracle.tablespace.dataThe tablespace data of the oracle database
db.oracle.tablespace.indexThe tablespace index of the oracle database
db.role.adm.usernameThe role of the admin user
db.role.app.usernameThe role of the application user
db.user.adm_usernameThe admin user's username
db.user.app_usernameThe application user's username
  1. Run the customization script
  • The customization script can be run by the nevisWorkflow package, with the command:
neviswf create-custom-db-scripts

This command generates a folder with the name custom in the directory the command is called from. This folder contains the modified sql scripts which is needed for the database setup (see the chapter "Database setup"), and the modified jars which can be used for convenient database upgrade (see the chapter "Upgrade").

Database setup

This guide describes how to setup the database used by nevisWorkflow. The setup is based on SQL scripts delivered with the application under the directory /opt/neviswf/resources/database/sql

Prior to nevisWorkflow 1.4.1.0, the database scripts reside in neviswf-db-<version>.tar.gz

MySQL
Prerequisites

The following requirements need to be fulfilled to setup the MySQL database:

  • MySQL 5.6 (or higher)

From nevisWorkflow version 1.4.0.0, using MySQL version <5.6, use the create55.sql DDL script to create the database.

Between nevisWorkflow version 1.3.0.0 and 1.4.0.0 using MySQL version <5.6, it's necessary to change the timestamp(3) types to timestamp within the following files.

  • sql/mysql/create/activiti.mysql.create.engine.sql
  • sql/mysql/create/activiti.mysql.create.history.sql
  • sql/mysql/create/activiti.mysql.create.identity.sql

To upgrade nevisWorkflow using MySQL version <5.6, see the Upgrading MySQL below version 5.6 section.

Installation

Proceed as follows to setup the MySQL database:

  • The database scripts are found under /opt/neviswf/resources/database/sql
  • Enter the directory to the corresponding database type, e.g.,
cd /opt/neviswf/resources/database/sql/oracle
  • Run the following command to create the database, tables and users:
mysql -u <root user> < create.sql
Removal

Proceed as follows to remove the MySQL database (caution, all data will be lost):

  • Drop the database tables:
mysql -u <root user> DCHNEVWF < drop.sql
  • Delete the users:
mysql -u <root user> < drop_user.sql
  • Drop the database:
mysqladmin -u <root user> drop DCHNEVWF
Oracle
Prerequisites

The following requirements need to be fulfilled to setup the Oracle database:

  • Oracle 11.2 (or higher)
  • Pre-configured data tablespace called data_nwf
  • Pre-configured index tablespace called index_nwf
Installation

Proceed as follows to setup the Oracle database:

  • Create the users by running the create_user.sql script as system user. This script will create a db admin user called unwf01 and an application user called unwf02 (unless something else was specified during the customization of the database, see the chapter Package installation).
SQL> @create_user.sql
  • To create the database tables, connect to the database with sqlplus using the db admin user (unwf01, unless something else was specified during the customization of the database, see the chapter Package installation) and run the create.sql script
SQL> @create.sql
Removal

Proceed as follows to remove the Oracle database (caution, all data will be lost):

  • First drop the tables by running the drop.sql script with the db admin user (unwf01, unless something else was specified during the customization of the database, see the chapter Package installation)
 SQL> @drop.sql
  • To delete the user created before run the drop_user.sql with the system user
SQL> @drop_user.sql

Instance creation

Creating an instance

Proceed as follows to create an instance and start the server:

  • Copy the /opt/neviswf/templates/conf/setup-default.properties to a save place to customize application settings. For example to /root/neviswf-setup.properties.
  • The setup-default.properties file contains default values. Change the copied neviswf-setup.properties file in such a way that every property that remains unchanged is deleted from the file. This helps identifying the changed values.
  • Prepare the default instance with the handover command
neviswf handover <setup file> [WF_DEPLOY_TYPE]

Via the setup file it is possible to specify properties such as the DB connection settings in advance . This makes it unnecessary to manually configure the properties afterwards. The list of available parameters can be retrieved using the following command:

neviswf inst create help 

The instance will be created with an adnglassfish container by default.

  • To create an adnwildfly instance, use the WF_DEPLOY_TYPE=adnwildfly setting.
  • To create a standalone instance, use the WF_DEPLOY_TYPE=standalone setting.

From version 1.11.0.0 on, nevisWorkflow can be deployed as a standalone application. See chapter Standalone Deployment Mode for more details.

Properties defined in any file within the /opt/neviswf/templates directory are going to be substituted with the values from the setup file on handover.

Optionally, when the default file templates are not satisfactory, it is possible to define another, customized template directory with the following command:

neviswf handover <setup file> [WF_DEPLOY_TYPE] INST_CUSTOM_TEMPLATE=/path/to/other/template

The INST_CUSTOM_TEMPLATE property is used by the adnglassfish command. On instance creation, some adnglassfish properties are read from the env.conf file, for example the server port range. Options for adnglassfish command are also applicable for handover. Properties defined in the setup-default.properties can be overwritten on handover with the following command:

neviswf handover /root/neviswf-setup.properties nevisidm_cache_maxentries=1000
Ninja configuration

nevisWorkflow is intended to be used from behind nevisProxy where a Security token is provided. Therefore, the Ninja login module is set up by default.

The login module configuration is different for the supported containers.

adnglassfish

The login.conf file describes the JAAS login module, and it is found in /var/opt/neviswf/neviswf/conf/login.conf after installation.

By default the login.conf file contains the following:

ninjaRealm {
ch.nevis.ninja.glassfish.auth.NinjaGlassfishLoginModuleImpl required
NevisSignerCertificate="/var/opt/neviskeybox/default/nevis/truststore.jks"
UserGetter="AttributeUserGetter(source=loginId)"
RoleGetters="StaticRoleGetter(roles='auth.weak')"
SecRoleMapping="group"
LogDebug="false"
;
};

adnwildfly

The standalone.xml file describes the JAAS login module, and it can be found in /var/opt/adnwildfly/instances/<instance>/standalone/configuration/standalone.xml after the installation.

<security-domain name="NevisSecTokenDomain" cache-type="default">
<authentication>
<login-module code="ch.nevis.ninja.jboss.auth.NinjaJbossLoginModuleImpl"
flag="required" module="ch.nevis.ninja">
<module-option name="NevisSignerCertificate"
value="/var/opt/neviskeybox/default/nevis/truststore.jks"/>
<module-option name="UserGetter" value="AttributeUserGetter(source=loginId)"/>
<module-option name="AdjustIdentity" value="true"/>
<module-option name="LogDebug" value="false"/>
<module-option name="RoleGetters"
value="ch.nevis.ninja.commons.mapping.StaticRoleGetter,
ch.nevis.ninja.commons.mapping.TokenRoleGetter"/>
</login-module>
</authentication>
</security-domain>
standalone

The neviswf.properties file contains the JAAS login module setting. It can be found in /var/opt/neviswf/<instance>/conf/neviswf.properties after the installation.

# the following section defines the ninja token settings to be used
# the truststore must contains the token signer (NevisAuth)
server.auth.ninja.truststore=/var/opt/neviskeybox/default/nevis/truststore.jks
server.auth.ninja.user-getter=AttributeUserGetter(source=userid)
server.auth.ninja.role-getters=StaticRoleGetter(roles='auth.weak')
server.auth.ninja.sec-role-mapping=group
server.auth.ninja.adjust-identity=false
server.auth.ninja.log-debug=false
For both container and standalone deployment modes

The NevisSignerCertificate option can be modified on handover with the nevis_ninja_truststore attribute in the setup-default.properties file.

Restart the application after modifying the login configuration.

Ninja configuration in development mode

In development or testing environments, a SecToken is not always available. In that case Ninja can be set up in development mode. Before handover, in the setup-default.properties, change the nevis_ninja_dev_mode property to true. You might also want to change the dev directory and signer certificate related settings to suit your needs. See the Ninja reference guide for further explanation of development mode.

Package installation

Prerequisites

The following requirements need to be fulfilled to install nevisWorkflow:

  • SLES 11/12 or Red Hat 7.x operating system
  • AdnJDK 1.8 or OpenJDK 1.8 runtime environment

Also the following Nevis components will be needed (see the contents of the latest nevisAppliance cluster for the version number):

  • (Optional) adnwildfly or adnglassfish for container deployment mode.
  • nevisKeybox – containing the Nevis Signer Certificate.
Installation

Install the package:

rpm -i <nevisWorkflow-RPM> 

Once the package is installed, further details can be specified about the database of nevisWorkflow.

Integration

nevisProxy integration

nevisWorkflow is just a regular back-end application from nevisProxy's point of view. To access nevisWorkflow via nevisProxy, the proper filter and filter-mapping have to be set in the proxy configuration for delegating the SecTokens through Ninja.

GUI integration

Content-only view

The nevisWorkflow GUI is designed to be embedded into other web applications on the browser-side within either an iframe or a pop-up window. For proper embedding, it's usually desired to show only the task form or process starting form without the surrounding menu items and page header. This can be achieved by inserting the "contentonly" part within the URL.

/neviswf/contentonly/showTask.xhtml?taskId=1652 
Custom CSS style sheet

The property neviswf.external.css defines a css file path relative to neviswf.external.resource.folder. The css file and the resource folder must be readable to the web server. When the neviswf.external.css property is set, the specified style sheet will be served to the web browsers rather than the default one.

Remote web service integration

A detailed list of configuration properties can be found in the chapterneviswf.properties.

Failover/Load balancing

Web service endpoint properties (e.g., ws.adminservice.endpoint, ws.adminservice.clientcert.endpoint) take a comma-separated list of URLs. If load balancing is true, then requests to web services are issued to different endpoints, chosen by a round-robin algorithm. However, after a logged-in user made his/her first request to one of the endpoints, subsequent requests go to the same endpoint afterwards (sticky session).

When a web service call fails due to connection error, the next web service endpoint is taken from the list. Connection to the failed endpoint is retried after a defined retry timeout interval.

Connect to nevisIDM with technical user

nevisIDM service calls issued from timer tasks or by technical users don't have a valid SecToken. In that case, a technical user must be set up in nevisIDM for nevisWorkflow.

Use the ws.adminservice.clientcert.* properties to set up a technical user with two-way ssl setup.

The following instruction describes how to create an X.509 certificate for the technical user using neviskeybox and local CA.

  1. Generate a certificate signing request for the technical user.
neviskeybox certreq -label "technicaladmin" -subject "cn=admin, o=NEVIS Security AG,
c=ch" -cn "admin" -certtype user
  1. On the nevisIDM server, create a CA and import its certificate.
neviskeybox cacreate
neviskeybox import -slot default -label myca -file
/var/opt/neviskeybox/default/myCA/ca_cert.pem
  1. Copy the technicalAdmin CSR to the nevisIDM server.

  2. Sign the CSR for the technicalAdmin.

neviskeybox sign -ca myCA -out /tmp/technicalAdmin_signed.pem -file
/tmp/technicalAdmin_request.pem -certtype user
  1. Import the CA certificate used in step 2 into nevisIDM truststore.
neviskeybox import -slot client -label myca -trust -file
/var/opt/neviskeybox/default/myCA/ca_cert.pem
  1. Copy the signed certificate back to the nevisWorkflow server.

  2. Import signed cert into the nevisWorkflow keystore.

neviskeybox import -slot default -label technicaladmin -file
/tmp/technicalAdmin_signed.pem
  1. Import the nevisIDM node certificate or the certificate of the CA that signed the nevisIDM node certificate to the nevisWorkflow truststore.

  2. Import the CA that signed the technicalAdmin CSR (nevisIDM local CA in this case, see point 4) into nevisWorkflow truststore.

Also read the nevisIDM reference guide for further information about client certificate authentication.

The keystore and the truststore in which the nevisWF private key and the nevisIDM certificates are stored must be defined as standard JVM properties:

  • javax.net.ss.keyStore
  • javax.net.ssl.trustStore

The ws.adminservice.clientcert.alias property defines the alias of the nevisWorkflow technical user private key in javax.net.ssl.KeyStore.

nevisIDM integration

To log on to nevisWorkflow, make sure

  • that there is an application with the necessary roles, and
  • that there is a user with the necessary permissions to log on to nevisWorkflow.

For further information about the nevisWorkflow roles, refer to chapter nevisWorkflow application roles.

Upgrade

Upgrading of nevisWorkflow consists of four main components:

  • Activiti libraries come with nevisWorkflow installation
  • nevisWorkflow application libraries
  • Activiti Database upgrade
  • nevisWorkflow Database upgrade

Upgrading the application happens on the first restart/redeployment of nevisWorkflow after the new version is installed.

Upgrading MySQL below version 5.6

nevisWorkflow 1.3.0.0 introduced Activiti 5.15.1 version. Upgrading nevisWorkflow to 1.3.0.0 or higher requires manually upgrading the database by executing the activity.mysql55.upgradestep*.sql scripts found in the neviswf-db tarball. More information can be found at:

nevisWorkflow's own database table upgrades are compatible with MySQL below and above version 5.6.

With automatic DB upgrade

Recommended way of upgrade.

Install new RPM package of nevisWorkflow

As in the chapter Install new RPM package of nevisWorkflow.

Restart nevisWorkflow and provide the DB patch jar in environment variable

Within the /opt/neviswf/resources/database folder, a neviswf-db-upgrade-<type>-version.jar file can be found that contains the upgrade sql scripts for both Activiti and nevisWorkflow. To let nevisWorkflow automatically upgrade its database and the database of Activiti, define the DB_UPGRADE_JAR environment variable and restart nevisWorkflow:

export DB_UPGRADE_JAR=/absolute/path/to/neviswf-db-upgrade-oracle-version.jar
neviswf restart

With manual DB upgrade

Not recommended due to both Activiti as well as nevisWorkflow DB upgrades might require running a piece of java code packed with the new version of nevisWorkflow. This Java code can handle tasks that cannot be done with pure SQL scripts. For example prefilling a new column with some user information where the information comes from NevisIDM. For Activiti, nevisWorkflow have no control over this requirement. Upgrading the DB manually might cause an inconsistent DB.

Install new RPM package of nevisWorkflow
Install RPM of new version
rpm -i neviswf-newversion.rpm
Stop nevisWorkflow
neviswf stop
Upgrade database by running the DB upgrade scripts manually

Find the upgrade scripts in the folder /opt/neviswf/resources/database/sql/<database-type>/upgrade

Prior to nevisWF 1.4.1.0, the database upgrade files are shipped in the neviswf-db-version.tar.gz file*

Find the current version of Activiti and nevisWorkflow database in the ACT_GE_PROPERTY table:

  • schema.version – for Activiti
  • neviswf.schema.version – for nevisWorkflow

Upgrade the Activiti tables by gradually executing the upgrade scripts starting from the version number in the database to the new Activiti version number. The Activiti DB upgrade scripts can be found in /sql/<db-type>/upgrade/org/activiti/db/upgrade folder.

Execute the different components in the following order:

  1. upgradestep.513.to.515.engine.sql
  2. upgradestep.513.to.515.history.sql
  3. upgradestep.513.to.515.identity.sql

Upgrade the nevisWorkflow tables by gradually executing the upgrade scripts found in /sql/oracle/upgrade/ch/adnovum/neviswf/datamodel/upgrade in a similar manner.

To keep track of the current database version and for the sake of a later automatic upgrade to work, the neviswf.schema.version property is stored in ACT_GE_PROPERTY table. For versions prior to 1.2.1.0 this property does not exist, so it first needs to be inserted.

INSERT INTO ACT_GE_PROPERTY(NAME_,VALUE_,REV_)
VALUES('neviswf.schema.version','1.2.1.0', 1);

The neviswf.schema.version property is automatically updated, when the nevisWorkflow database upgrade script is executed.

The neviswf.schema.version does always correspond to the newest nevisWorkflow version number. The property indicates the last nevisWorkflow version number, where the database has changed (not including Activiti tables).

Start nevisWorkflow

Start nevisWorkflow with the start command. After the new RPM install, the new version of the web application will be deployed.

neviswf start

Configuration

Workflows

Workflows are standard Activiti workflows. Documentation can be found on the homepage of Activiti.org [1].

Defining workflow deployments

Workflow deployments are basically standard jar files. They contain classes and resources. To be able to deploy workflows from jars, the META-INF/processes.xml file has to exist.

META-INF/processes.xml

The processes.xml file has to contain one <processes> XML element. If this file is present, workflows are automatically deployed after placing the containing jar on the classpath with the addLib command. Then it is possible to restart nevisWorkflow.

Additional attributes can be defined optionally in the processes element:

  • deploymentName
    The name to be shown on the Deployments screen. If not defined, the jar name will be used.

Example:

<processes deploymentName="neviswf-test-workflow"
</processes>
Diagrams

Diagrams are placed in the /diagrams/workflowName folder within the Jar. Defining the subdirectory "workflowName" is recommended to avoid workflow name collisions, and to follow a good naming convention.

Example:

 diagrams/simpleworkflow/SimpleProcess.bpmn
JSF resources

Views and other resources for JSF have to be placed according to the JSF specification. First, a standard faces-config.xml has to be defined in the META-INF directory. Then, every JSF resource must be placed in the META-INF/resources directory. When referencing resources, e.g., an XHTML page, their absolute path starts from this directory.

Example:

META-INF/
faces-config.xml
resources/
simpleworkflow/
js/
simpleWorkflow.js
views/
simpleworkflow/
simpleProcessStartForm.xhtml
simpleProcessApproveForm.xhtml

<ui:include src="/simpleworkflow/views/simpleProcessStartForm.xhtml"/>
Classes/CDI beans

Classes have to be put into the directory as they usually go in a jar file:

com/package/name/SomeClass.class

When using CDI, do not forget to put a beans.xml file in the META-INF/ directory.

Deploying workflows

Deploying workflow/adding library

Deployment and undeployment of workflows are done with the addLib command

neviswf addLib path/to/workflow.jar 

For workflows, the jar has to contain a META-INF/processes.xml file, so nevisWorkflow can automatically deploy the contained workflow files.

If your workflow requires additional library jars, they have to be added to the classpath with the same command.

When you are done adding libraries, restart the application.

Information and exceptions on deployment are logged in the neviswf.log file

Listing deployments and libraries

Listing previously added libraries and workflow jars are done with the lsLib command

neviswf lsLib
Removing workflow deployments/libraries

Workflows can be undeployed by administrators on the Deployments page, by clicking on the trash icon. This will deactivate the deployment and no processes can be started from that deployment. Clicking again on the trash icon permanently removes the deployment and the process definitions from the database. Permanently deleting the deployment results in losing information from the history, therefore it is not recommended.

The jars containing the workflows and additional resources such as classes, xhtml pages, javascript files will be removed automatically after undeploying the GUI.

Removing the workflow jars does not automatically undeploy the contained process definitions.

Deployment versioning

Deployments use static versioning. With a new version of the same workflow deployment, the version number has to be appended to the package names, bean names, and resource paths. The references to the classes, beans and resource paths must also be upgraded within .bpmn, .xhtml, .java files.

Taking the example from the chapter JSF resources, a versioned deployment looks as follows:

META-INF/
ch/
nevis/
simpleworkflow/
v2/
SomeClass.class
faces-config.xml
resources/
simpleworkflow/
js/
v2/
simpleWorkflow.js
views/
simpleworkflow/
v2/
simpleProcessStartForm.xhtml
simpleProcessApproveForm.xhtml

For CDI beans, the @Named annotation has to be used to create a new bean name, and every reference to this bean has to be changed to the new bean name.

@javax.inject.Named("someBeanv2") 

References to resources in .xhtml, .bpmn files also have to reflect the changed paths.

Testing workflows

The neviswf-test-base.jar package contains the NevisWfTestCase.java class that should be used as a base class for JUnit tests. Extend this class when creating JUnit tests.

NevisWfTestCase.java does the following:

  • Initialize H2 database
  • Initialize process engine
  • Start CDI container

After every test, the H2 database and CDI scopes are cleared.

It is not necessary to create a custom activiti.cfg.xml file, configuration is done programmatically entirely within the mentioned base class. It is recommended using the @Deployment annotation to deploy processes for tests in Activiti manner.

@Test
@Deployment(resources =
{"org/activiti/examples/variables/VariablesTest.testChangeTypeSerializable.bpmn20.xml"})
public void testChangeTypeSerializable() {
// ...
}

Refer to Unit testing [1] and Activiti Engine examples [2] (activiti-engine/src/test/java/org/activiti/examples).

Operation and Administration

Configuration files

The default configuration file can be found at

/opt/neviswf/template/conf/setup-default.properties

neviswf.properties

Activiti

The following table lists the parameters related to Activiti.

Parameter nameMandatoryDescription
group.entity.factory.classyesDefines the class to be used for Activiti group management. To use nevisIDM as group management system, the value should be defined to "ch.adnovum.neviswf.nevisidm.sessionfactories.NevisIdmGroupEntityFactory".
membership.entity.factory.classyesDefines the class to be used for Activiti membership (roles) management. To use nevisIDM as membership management system, the value should be defined to "ch.adnovum.neviswf.nevisidm.sessionfactories.NevisIdmMembershipEntityFactory"
user.entity.factory.classyesDefines the class to be used for Activiti user management. To use nevisIDM as user management system, the value should be defined to "ch.adnovum.neviswf.nevisidm.sessionfactories.NevisIdmUserEntityFactory".
neviswf.process.engine.configuratorsnoA comma separated list of classes that implement the org.activiti.engine.cfg.ProcessEngineConfigurator interface.It provides a pluggable mechanism to change the process engine configuration on startup time.It is possible to inject String, Integer, Long, Boolean type arguments into the configurator. See example below the table.
neviswf.process.engine.configurators=org.activiti.ldap.LDAPConfigurator
org.activiti.ldap.LDAPConfigurator.port=81811
nevisIDM

The following table lists the parameters related to nevisIDM.

Parameter nameMandatoryDescription
ws.adminservice.endpointyesComma-separated list of endpoint URIs of the nevisIDM admin service used
ws.adminservice.wsdl.resourcenoWSDL resource of the nevisIDM admin service. Default: "/wsdl/nevisidm_adminservice_v1.wsdl"
ws.adminservice.classnoClass used as nevisIDM admin service client. Default: "ch.adnovum.nevisidm.ws.services.v1.AdminServiceV1"
ws.adminservice.request.timeoutnoRequest timeout when communicating with the nevisIDM admin service. Default: 120000
ws.adminservice.connect.timeoutnoTCP connection timeout when establishing the connection to the nevisIDM admin service. Default: 15000
ws.adminservice.token.encodingnoForwarded SecToken encoding options Possible values:*automatic / null Lets the framework encode the password property (re-encode in UTF-8) forward Forwards the whole HTTP authorization header unchanged. You may need to set the TokenEncoding attribute of the Ninja configuration. character encoding, e.g., UTF-8Converts basic auth header bytes as encoding then converts to Base64.
nevisidm.cache.enablednoEnables caching of nevisIDM results. Used to optimize the performance and reduce the load on nevisIDM. Default: true
nevisidm.cache.maxentriesnoNumber of entries stored in the nevisIDM result cache. This number should correspond to the expected number of simultaneous users. Default: 100
nevisidm.cache.ttlnoLifetime of an entry in the nevisIDM result cache in milliseconds. Default: 60000
ws.adminservice.loadbalancingnoEnable round-robin load balancing between endpoints, when more endpoints are defined. Default: false
ws.adminservice.clientcert.endpointnoComma-separated list of endpoint URIs of the nevisIDM admin service that use client certificate-based authentication. This endpoint is used by the technical user.
ws.adminservice.clientcert.keystorenoPath to JKS keystore to be used for two-way SSL, when the ws.adminservice.clientcert.endpoint is defined. If this configuration is empty, then javax.net.ssl.keyStore is used. Default: empty
ws.adminservice.clientcert.keystore.passwordnoPassword for JKS file defined in ws.adminservice.clientcert.keystore Default: empty
ws.adminservice.clientcert.aliasnoAlias of the certificate in javax.net.ssl.KeyStore used by technical user to connect ws.adminservice.clientcert.endpoint
ws.selfadminservice.endpointnoComma-separated list of endpoint URIs of the nevisIDM self admin service used
ws.selfadminservice.wsdl.resourcenoWSDL resource of the nevisIDM self admin service. Default: "/wsdl/nevisidm_adminservice_v1.wsdl"
ws.selfadminservice.classnoClass used as nevisIDM self admin service client. Default: "ch.adnovum.nevisidm.ws.services.v1.SelfAdminServiceV1"
E-mail server

The following table lists the parameters related to the e-mail server.

Parameter nameMandatoryDescription
mail.smtp.hostyesSMTP server host used to send e-mail notifications and used by e-mail tasks.
mail.smtp.portyesSMTP server port used to send e-mail notifications and used by e-mail tasks.
mail.sender.addressyesSender address used in e-mail notifications.
mail.server.usernamenoUser name for the mail server used to send notifications by the application.See Activiti documentation.
mail.server.passwordnoPassword for the mail server used to send notifications by the application. See Activiti documentation.
mail.server.sslnoIf true, server side ssl encryption is allowed. Default is false. See Activiti documentation.
mail.server.tlsnoIf true, server side tls encryption is allowed. Default is false. See Activiti documentation.
mail.server.session.jndinoJNDI name of javax.mail.Session in "java:comp/env". See Activiti documentation.
nevisWorkflow

The following table lists the parameters related to nevisWorkflow.

Parameter nameMandatoryDescription
daily.summary.scheduleyesSchedule expression defining when daily notification mails should be sent. syntax: Sec, Min, Hours, DayOfMonth, Month, DayOfWeek Special characters like * can be used, for syntax check: http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html Example: 0 0 7 * * ? means every day at 7 o'clock.
show.variablesnoIf true, the variables tab is shown on the task/process details screen. Default: true
variable.editnoIf true, the variables are editable on the variables tab. Default: false
show.commentsnoIf true, the comments tab is shown on the task/process details screen. Default: true
show.attachmentsnoIf true, the attachments tab is shown on the task/process details screen. Default: true
neviswf.external.resource.foldernoAbsolute path of root folder of additional resource files (css, js, images). This folder must have read rights to the web server.
neviswf.external.cssnoIf defined, this file serves as default css file. The path to this file is relative to neviswf.external.resource.folder.
neviswf.external.logonoIf defined, this file serves as a default logo to be shown on the header of the GUI. The path is relative to neviswf.external.resource.folder.
gui.search.enablednoIf true, the Process and Task search functionality is turned on. Default: true For more information on the Process and Task search functionality, see the chapters: Task Search.
Ninja and SecToken

The following table lists the parameters related to the Ninja and SecToken.

Parameter nameMandatoryDescription
identityservice.use.sectoken.infonoIf set to true, user information such as name, e-mail, roles, country and language is read from the SecToken. Otherwise, this information is queried from nevisIDM.Default: false.
nevis.sectoken.attr.loginidnoSecToken attribute name holding the user's login id.Default: loginId
nevis.sectoken.attr.profileidnoSecToken attribute name holding the user's profile id.Default: profileId
nevis.sectoken.attr.clientidnoSecToken attribute name defining the user's nevisIDM client external id.Default: clientId
nevis.sectoken.attr.firstNamenoSecToken attribute name holding the user's first name.Default: firstName
nevis.sectoken.attr.lastNamenoSecToken attribute name holding the user's last name.Default: lastName
nevis.sectoken.attr.countrynoSecToken attribute name holding the user's country.Default: country
nevis.sectoken.attr.languagenoSecToken attribute name holding the user's language.Default: language
REST interface

The following table lists the parameters related to the REST interface.

Parameter nameMandatoryDescription
rest.enablednoEnables or disables REST service.Default: false
rest.clientip.auth.enablednoEnables/disables IP-based authorization.Default: false
rest.clientip.auth.whitelistnoDefines a comma-separated whitelist for client-based authorization.Default: 127.0.0.1
neviswf.rest.response.hide.domain.namenoHides the domain name in response JSON message.Default: false
neviswf.job.executor.activatenoDeactivates the JobExecutor.Default: true

nevisWorkflow log levels (file: logback.xml)

The nevisWorkflow log levels are defined in the file logback.xml located in the configuration directory of nevisWorkflow. By default, the log levels are aimed for productive setups. As a consequence, the log levels are set in such a way that only the most important information is traced. For an in-depth analysis in case of problems, the log levels of the right categories can be increased. For every category, one of six log levels can be defined:

  • OFF: no tracing at all.
  • ERROR: only errors are traced. Mainly used in productive setups.
  • WARN: notifies about issues that should be addressed, but do not block the running system.
  • INFO: general information is traced. It is more trace than ERROR would produce, but still ok concerning the amount of information in the log file. INFO includes ERROR too.
  • DEBUG: very verbose logging output. DEBUG includes ERROR and INFO too.
  • TRACE: includes the output of all other log levels and additionally the entering and exiting events of Java methods.

High log levels are likely to slow down nevisWorkflow. So, use the log levels with care in productive setups or when performance analyses are performed.The following table describes the most important categories:

Log categoryDescription
org.activitiBy default set to INFO. This tracegroup allows enabling tracing of the Activiti framework.
ch.adnovumBy default disabled. This tracegroup allows enabling tracing of nevisWorkflow core code.
ch.nevisBy default disabled. This tracegroup allows enabling tracing of Nevis subcomponent such as Ninja.
http.requestBy default disabled. Allows debugging of HTTP requests.
http.responseBy default disabled. Allows debugging of HTTP responses.
http.bodyBy default disabled. Allows debugging of HTTP requests body.
http.sessionBy default disabled. Allows debugging of HTTP sessions.
http.timeBy default disabled. Allows debugging of HTTP timings.
jcan.OpBy default set to INFO. It will trace information about SOAP method invocations.
jcan.OpContentBy default set to OFF. If set to DEBUG, all SOAP traffic is dumped into the log file. This is helpful if you want to see the actual SOAP requests and responses.
jcan.Op.activitiBy default set to ERROR. It will trace information about Activiti method invocations.
Other nevisWorkflow configuration files

The file list found in /opt/neviswf/template/conf is copied to the /var/opt/neviswf/neviswf/conf directory upon installation. After installation, every change made to the configuration files should be done in the nevisWF instance directory (/var/opt/neviswf).

  • Changing any file in the /opt/neviswf/template directory will only affect the installation procedure, and results in the modified file to be copied to the installation directory.
  • Changing any file in the /var/opt/neviswf/neviswf/conf directory will affect the installed nevisWF instance.
File nameDescription
db.propertiesDefines the database connection pool configuration. After installation changing this file will result in reconfiguration of the application server data sources. When this file is changed in the installation directory, the neviswf command will substitute properties defined in the <database-type>_datasource.xml files.
env.confDefines adnglassfish installation parameters. This file only has effect on installation.
login.confNinja login configuration file for JAAS authentication.
login-dev.confNinja developer mode login configuration file for JAAS authentication.
vmargs.confAdding JVM arguments to this file will be added to the Glassfish domain instance. To remove existing properties, delete their value. Changing this file requires restarting nevisWF
logback.xmlLogback configuration file to configure application logging.
<database>_datasource.xmlGlassFish specific database resource file. This file is updated, when the db.properties file is changed. important: Changing this file directly does not result in changing the configured GlassFish data source. The data source needs to be reconfigured. Thus, it is advised to reconfigure the database via the db.properties file, because that automatically triggers database reconfiguration in nevisWF admin script on restart.
<db>_admin_datasource.xmlSame as <database>_datasource.xml, but for a user with administration rights. This data source is only used by the nevisWF application, when applying automatic database upgrade.
neviswf.propertiesConfiguration of nevisWF runtime parameters. Changing these parameters requires restart.

Storing passwords in nevisCred

Passwords appearing in neviswf.properties can be stored in nevisCred. Simply use the following syntax where applicable:

password.property=neviscred://<passwordId>

where <passwordId> is the same as it is stored in nevisCred. Example:

mail.server.password=neviscred://smtpPassword

Prerequisite is to have the nevisCred client available on the same machine where nevisWorkflow is installed. If ncclient is in the default location (/opt/neviscred/bin/ncclient), no configuration is needed. To set non-default location, add the following argument to vmargs.conf:

-Dch.nevis.neviscred.client=/neviscred/client/location/ncclient

Another valid prefix for passwords is "plain://". This is only used to mark in the configuration that the password is in plain text. It is the same as without the prefix.

To mark a plain text password, use the following syntax:

password.property=plain://<plainTextPassword>

where <plainTextPassword> is the password itself. For example:

mail.server.password=plain://smtpPassword

is exactly the same as:

mail.server.password=smtpPassword

Embedded container deployment

From version 1.11.0.0 on, nevisWorkflow can be deployed in the following ways:

Deployment TypeRemarksState
WildflynevisWorkflow deployed as a web application.Stable
GlassFishnevisWorkflow deployed as a web application.Stable
StandalonenevisWorkflow deployed as a web application including an embedded container.Stable, recommended deployment type

The following sections describe the configuration of the standalone deployment type.

Standalone

The standalone deployment type makes use of an embedded container. There is no need anymore to install a separate container application. You specify the usage of an embedded container during instance creation (or handover), by setting the WF_DEPLOY_TYPE variable to "standalone".

The following configuration files control the behavior of nevisWorkflow in the standalone deployment type:

Configuration fileRemarks
env.confAdministration command and process environment:JAVA_HOME: Use specified JRE/JDK. Only version 1.7 / 1.8 is supported. All other parameters should not be changed.
vmargs.confJVM command-line options:Heap size. Garbage collector. * System properties configuration.
neviswf.propertiesApplication, login, server configuration:Application configuration options (connection to IDM, notification e-mail, nevisWF). Ninja authentication module configuration options. Scaling (concurrency with worker threads). Network settings (host, port, protocol, TLS, ...).
logback.xmlLogging configuration:Configuration of log levels for in Audit channel (if the file rotation policy or output file needs to be customized).

The configuration files are located here:/var/opt/neviswf/<instance>/conf

Environment configuration

As the first priority, nevisWorkflow uses the Java installation defined by the configuration property JAVA_HOME in the file env.conf. If the JAVA_HOME property is not set, the Java version as defined in the PATH environment variable is used.

To define the usage of a specific Java installation, we recommend setting the configuration property JAVA_HOME in the file env.conf:

Example

JAVA_HOME=/opt/adnjdk18

Server configuration properties

You can configure the server of the standalone deployment type through the properties in the file neviswf.properties, see the following table.

**Name**Example valueDefault valueRemarks
server.name<instance>Name of the server. Give each server a unique name, for the sake of identification. This name will also be logged.
server.protocolhttpshttpsEnumeration: https, http(info) Set this property to "https" if you would like to use TLS.
server.port89918991Configures the port where the server will listen for incoming authentication requests.
server.hostlocalhostConfigures the hostname on which the server will listen for incoming authentication requests.
server.tls.keystore/var/opt/keybox/default/node_keystore.jksKeystore object used for the TLS.
server.tls.keystore-passphrasekeystorepassword
server.tls.truststore/var/opt/keybox/default/truststore.jksTruststore object used for the TLS.
server.tls.truststore-passphrasetruststorepassword
server.tls.require-client-authtruefalseControls if client authentication is required for the TLS connection.- "false" = one-way TLS connection- "true" = two-way TLS connection
server.tls.supported-protocolsTLSv1.2TLSv1, TLSv1.1, TLSv1.2Provides a list of protocols that are accepted by the client when trying to initiate a connection with TLS.
server.tls.cipher-suitesTLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSVProvides a list of ciphers that are accepted by the client when trying to initiate a connection with TLS.
server.max-threads200200Number of threads used to process incoming requests.

The property values related to server configuration in the file neviswf.properties can be expressions that will be replaced. The next table shows the available syntax:

SyntaxExampleRemarks
${exec:command}server.tls.keystore-passphrase: ${exec:/var/opt/keys/own/instance/keypass.sh}server.host: ${exec:hostname -f}Executes the given command and uses its output as the value.
${env:variablename}server.host: ${env:HOSTNAME}Uses the value of the specified environment variable.

Standalone server command-line interface

For standalone deployments, the standalone command-line interface (CLI) provides a low level interface to run the server process. It can be used by higher level tools like the administrative CLI or by the user directly. You can use the standalone CLI to start nevisWorkflow without involvement of other system components like for example systemd. You find the standalone script at /opt/neviswf/bin/neviswf-server.It provides the following command-line options:

Command-line argumentRemarksDefault
-c, --config PATHRequired. Path to the configuration file neviswf.properties.No default.
-n, --name NAMEUnique name for that NEVIS component node.Overrides the value of the property server.name (in the neviswf.properties file).See the server.name property in the neviswf.properties file.
-p, --port PORTThe HTTP/S port to listen on. TLS must be configured in the config file and not as an argument.Overrides the value of the property server.port (in the neviswf.properties file).See the server.port property in the neviswf.properties file.
-H, --host HOSTThe HTTP/S host to bind on. By default binds on all IPv4 and IPv6 interfaces.Overrides the value of the property server.host (in the neviswf.properties file).See the server.host property in the neviswf.properties file.
--log-config PATHLog configuration file to be used.If a log configuration is provided, nevisWorkflow will use the given configuration file to determine how logging should behave. If no configuration file is provided, nevisWorkflow will log to the console by default.Not set.
-V, --versionDisplay version and exit with status code 0.
-h, --helpShows complete and detailed usage and exit with status code 0.

Command-line arguments always prevail over the configuration in the neviswf.properties file.

Example usage of the standalone CLI

Execute the following commands to start an existing nevisWorkflow instance named "neviswf" without using systemd to manage the service:

# set working directory
cd /var/opt/neviswf/neviswf
# set environment variables from env.conf and start nevisWF standalone deployment
# use subshell to not interfere with environment variables
(set -a && source /var/opt/neviswf/neviswf/conf/env.conf && set +a && /opt/neviswf/bin/neviswf-server --config /var/opt/neviswf/neviswf/conf/neviswf.properties --log-config /var/opt/neviswf/neviswf/conf/logback.xml)

Migration Guide from containers to standalone

The scope of this document is to provide a guideline for migrating a nevisWF instance (v1.11.1.0 or newer) with containers of the type adnglassfish and adnwildfly to a new nevisWF instance with embedded Jetty standalone (v9.4.x).

This document does not claim completeness, but covers the most common configuration use cases and indicates recommendations for their migration.

There is no automated instance migration. The information from the current instance has to be gathered and used to create a new target standalone instance.

If the current adnglassfish/adnwildfly instance and the new standalone instance should be on the same host, the existing instance must be stopped first. Use the following command:

neviswf <instance_name> stop
Adnwildfly instance parameters gathering

The recommended way to migrate from containers to standalone is to use the property file. The same property file can be used to create the standalone instance. See the following sample property file:

Sample property file
db_type=oracle
db_user_app_password=unwf02
db_user_app_username=******
db_user_adm_username=unwf01
db_user_adm_password=******
db_connection_host=acme.adnovum.ch
db_connection_port=8884
db_connection_db_name=ACME_DB
db_connection_pool_id=neviswfDs
db_connection_url=jdbc:oracle:thin:@acme.adnovum.ch:8884:ACME_DB
db_admin_connection_pool_id=neviswfAdminDs
ws.adminservice.endpoint=https://acme.adnovum.ch:8080/nevisidm/services/v1_39/AdminService
JVM_KEYSTORE_PASSWORD=******
JVM_TRUSTSTORE_PASSWORD=******

From version 1.13.x and above, standalone deployment only uses the property db_connection_url to establish a database connection instead of the properties db_connection_host, db_connection_port and db_connection_db_name. This is to provide more flexibility to the user for further advanced connection configuration, such as load balancing, connection attributes, etc.

If there is no property file, it is suggested to create one, as all settings can be gathered in one place. Also, you can reuse the file later to create the instance.

The /var/opt/neviswf/.setup.defaults file of the last created instance is a good starting point. As reference, use /var/opt/**adnglassfish**/.setup.<instance_name> or /var/opt/**adnwildfly**/.setup.<instance_name>. Those files contain all the settings used to create the instance.

On instance creation, it is adviced gathering the property values in the following order:

  1. The package defaults
  2. The provided property file
  3. The properties provided on the command line

This means that first the package defaults will be considered, then the values from the given property file (if any) and finally the properties provided on the command line (if any).

Standalone instance creation
Using the property file during the instance creation

Once you have the property file, you can start with the instance creation. Eexecute one of the following commands:

neviswf inst create <new_instance_name> <property_file_location> WF_DEPLOY_TYPE="standalone" NEVISWF_SERVER_URL="<neviswf endpoint>"

Some notes:

  • It is important to set WF_DEPLOY_TYPE correctly to create an standalone instance.
  • The NEVISWF_SERVER_URL parameter is mandatory and specifies whether HTTP or HTTPS has to be used to access the nevisWorkflow web application and the host and port. To find out the endpoint of nevisWorkflow (neviswf) on adnwildfly - which has to be reused for the new instance - executing the command neviswf <instance name> status.
neviswf inst create <instance> <property file location> WF_DEPLOY_TYPE="standalone" NEVISWF_SERVER_URL="<neviswf endpoint>"
Configuration

The settings of the application can also be altered manually after instance creation.

If the creation of an instance failed, make sure that the application is deployed after making the manual changes to the configuration.

neviswf <new_instance_name> restart
Application settings

The nevisWorkflow configuration can be changed with the following command:

neviswf <new_instance_name> config

The following property has to be set:

PropertyDescription
ws.adminservice.endpointThe endpoint URL of the NevisIDM AdminService SOAP service. For example: https://localhost:8989/nevisidm/services/v1_39/AdminService, https://neviswf-linux.zh.adnovum.ch:8989/nevisidm/services/v1_27/AdminService
VM arguments

The VM arguments can be changed with the following command:

neviswf <new_instance_name> config vmargs

Check if the keystore/truststore configurations are correct:

ParameterDefaultDescription
-Djavax.net.ssl.trustStore/var/opt/neviskeybox/default/default/truststore.jksTruststore used to validate client certificates.
-Djavax.net.ssl.keyStore/var/opt/neviskeybox/default/default/node_keystore.jksKeystore used to identify the server (sent to client on SSL/TLS client hello).
-Djavax.net.ssl.trustStorePasswordPassphrase to access the server truststore.
-Djavax.net.ssl.keyStorePasswordPassphrase to access the server keystore.
-Djboss.socket.binding.port-offset=8884The instance offset for the port.
Standalone instance start

After the migration is completed, the new standalone instance can be started with the following command:

neviswf <new_instance_name> restart
Containers instance removal

After the new standalone instance is successfully migrated, the old adnglassfish instance can be removed with the following command:

neviswf inst remove <instance_name>

Notifications

The user can register itself for notification upon different type of events. The following different types of notifications are available:

  • Process completed
  • Process cancelled
  • Task completed
  • Task assigned
  • Daily summary notification about processes

The notifications are sent to the registered user e-mail address as defined in nevisIDM.

Notification templates

Templates for the notifications to be sent are defined within the database in the table TNWFC_TEMPLATES, see section Database table TNWFC_TEMPLATES. As placeholders in the templates EL expressions can be used to resolve any data provided by nevisWorkflow and the Activiti framework.

The currently supported notification types in the TYPE column are: process_created, process_completed, process_cancelled, task_completed, task_created, task_assigned, and process_summary.

An SQL insert command for an example template is:

INSERT INTO TNWFC_TEMPLATES VALUES (3,'process_completed','nevisWf - Process completed
#{emailService.currentNotification.processDefinitionId}',
'Dear #{emailService.currentContact.firstName}!

Process (#{emailService.currentNotification.processDefinitionId}) with id
(#{emailService.currentNotification.processInstanceId}) has completed.',
'en','admin',Current_Timestamp ,'admin',Current_Timestamp, 0 );

An e-mail sent with such a template could for example result in the following e-mail content:

Dear Adminophil!
Process someProcessId with id 12345 has completed.

nevisWorkflow command-line API

neviswf                                                           # get this usage

neviswf [instance name | all] start # start the server instance(s)
neviswf [instance name | all] stop # stop the server instance(s)
neviswf [instance name | all] restart # restart the server instance(s)
neviswf [instance name | all] status # show state of server instance(s)
neviswf [instance name | all] deploy # deploy application
neviswf [instance name | all] undeploy # undeploy application
neviswf [instance name | all] redeploy # redeploy application

neviswf [instance name] config [neviswf] # application properties
neviswf [instance name] config logging # logging configuration (requires restart)
neviswf [instance name] config login # ninja (jaas) login configuration
neviswf [instance name] config db # configure database properties
neviswf [instance name] config vmargs # configure VM options

neviswf [instance name] config export <tarfile> # export configurations in <tarfile>
neviswf [instance name] config import <tarfile> # import configurations from <tarfile>
neviswf [instance name] config backup list # list available backups
neviswf [instance name] config backup [<descr>] # backup actual configurations
neviswf [instance name] config backup remove <stamp> # remove specified backup
neviswf [instance name] config restore [<stamp>] # restore last or specified backup

neviswf [instance name] addLib [path to jar file] # add an application lib/workflow jar (no wildcards supported)
neviswf [instance name] rmLib [name of jar file] # remove an application lib/workflow jar with name
neviswf [instance name] lsLib # list added application libs/workflow jars

neviswf create-custom-db-scripts # create custom db scripts based on db.properties, and put them into the ./custom folder

neviswf handover [<propertyfile>] # create the default instance (neviswf)
neviswf inst # list all existing instances
neviswf inst remove <name> # remove an instance
neviswf inst create <name> [<propertyfile>] # create an instance
neviswf inst exists <name> # check for an existing instance
<propertyfile>: use your own property file

Display currently installed version of nevisWorkflow

To display the currently installed version of nevisWorkflow, use the commands neviswf pkg or neviswf version.

Developer Guide

Data model

This chapter explains the nevisWorkflow data model which involves two separate parts. One set of tables are provided by the Activiti framework on which nevisWorkflow is based. Another set of tables is used by nevisWorkflow directly to provide extensions to Activiti.

In the following parts of this chapter, more details are given about the database tables nevisWorkflow uses directly. For more details about the data model used by the Activiti database, refer directly to the Activiti documentation.

Data types

All tables listing the attributes of entities contain a column "Java data type". The Java data type and not the database data type is specified because depending on the used database, i.e., MySQL or Oracle, the database data type may vary. The table below shows the default mappings between Java and database data types in nevisWorkflow.

Java data typeOracle data typeMySQL data type
longnumber(19,0)bigint
integernumber(10,0)integer
shortnumber(5,0)smallint
stringvarchar2varchar, text
datedatedatetime
booleannumber(1,0)bit

Database table TNWFC_SEARCHES

Stores bookmarked searches.

DB field name of attributeJava data type (max. size) DefaultsDescription
search_idLong, not NULLPrimary key
user_idString (64), not NULLId of the user
search_typeString (64), not NULLType of search (process, task, …)
search_nameString (255), not NULLName defined for the search
search_parametersString (4000), not NULLParameters chosen for the search (search query)

Database table TNWFC_SUBSCRIPTIONS

Stores users' subscriptions to notifications about task and process changes. Which nullable field must be set is defined by the notification_type. For example, the task_id column must not be set if the type of notification is about ending the process.

DB field name of attributeJava data type (max. size) DefaultsDescription
subscription_idLong, not NULLPrimary key
process_definition_idString (64)Process definition ID
process_instance_idString (64)Process instance ID
task_nameString (255)Name of the task
task_idString (64)ID of the task
notification_typeString (64), not NULLType of notification
user_idString (64), not NULLID of the user subscribed
user_firstnameString (255), not NULLFirst name of the user subscribed
user_lastnameString (255), not NULLLast name of the user subscribed
user_localeString (2)Locale code of user's language
notification_channelsString (255), not NULLType of notification used

Database table TNWFC_TEMPLATES

Notification e-mail templates.

DB field name of attributeJava data type (max. size) DefaultsDescription
template_idLong, not NULLPrimary key
typeString (64), not NULLType of template
subjectString (255), not NULLSubject of the template (used as e-mail subject for example for e-mail templates)
bodyString (4000), not NULLContent of the template
language_codeString (2), not NULLLanguage code such as EN, DE, …

Database table TNWFC_PROC_PERM

Holds process-related permissions, including which user is permitted to start or cancel a process; who is permitted to read or write a process variable; who is permitted to complete a task.

DB field name of attributeJava data type (max. size) DefaultsDescription
permission_idLong, not NULLPrimary key
process_definition_idString (64)Process definition this permission is applied to
task_nameString (64)Task name this permission is applied to
is_assigneeBooleanWhether or not the permission is applied to the assignee of task_name
is_process_starterBooleanWhether or not the permission is applied to the process starter
operationString (32)Id of the operation
granularityString (32)Granularity includes:Process level Task level * Variable level
permissionBoolean, not NULLTrue: permitted False: Prohibited

Database table TNWFC_PROC_PERM_GROUP

Holds information about which groups are assigned a process permission.

DB field name of attributeJava data type (max. size) DefaultsDescription
group_idString (64), not NULLPrimary key
permission_idLong, not NULLPrimary key

Database table TNWFC_PROC_PERM_USER

Holds information about which users are assigned a process permission.

DB field name of attributeJava data type (max. size) DefaultsDescription
user_idString (64), not NULLPrimary key
permission_idLong, not NULLPrimary key

Database table TNWFC_PROC_PERM_VAR

Holds information about which variables are assigned a process permission. Only used when the permission controls access to process variables.

DB field name of attributeJava data type (max. size) DefaultsDescription
variable_nameString (64), not NULLPrimary key
permission_idLong, not NULLPrimary key

Database table TNWFC_PROPERTY

Used for holding configuration properties for workflows, e.g., URLs of remote services.

DB field name of attributeJava data type (max. size) DefaultsDescription
property_idLong, not NULLPrimary key
environmentString (64)Deployment environment, e.g.,: prod, test, dev, inst1, inst2, inst3
familyString (64), not NULLGrouping identifier, e.g.,:neviswf, workflow1, workflow2
keyString (64), not NULLName of the property
valueString (255)Value of the property

Technical DB fields

A further simplification is made by explaining hereafter certain technical fields that are not table-specific. It can be assumed that these attributes exist in every table except in static reference tables, so they are not listed later on in this chapter.

DB field name of attributeJava data type (max. size) DefaultsDescription
ctl_tcnInteger, not NULLCounter used for optimistic locking.
ctl_cre_uidString(110), not NULLLoginID of the user who created the entry.
ctl_cre_dateDate, not NULLCreation date.
ctl_mod_uidString(110), not NULLLoginID of the user who last modified the entry.
ctl_mod_datDate, not NULLDate of the latest modification.

The main purpose of the technical fields listed in the table above is traceability and audit: who has changed an entry, and when.

Authorization Engine

Short description

With the new nevisWorkflow authorization engine it is possible to put authorization tags into BPMNs (Business Process Model and Notation), which can restrict or grant operations to users. The purpose of the chapter "Authorization engine" is to describe the features and functionality of the new authorization engine.

Why the authorization engine was introduced

The authorization engine was introduced to allow an operation-specific authorization definition with different authorization scopes.

Simply put, the new authorization engine helps defining specifically who is allowed to do what.

Attributes

Scope

The following scopes are accepted:

  • USER: The authorization will apply to one or more users. If this scope is set, the authorization tag must contain at least one user tag.
  • GROUP: The authorization will apply to one or more groups. If this scope is set, the authorization tag must contain at least one group tag.
  • PROCESS_STARTER: The authorization will apply to the one who started the process.
  • ASSIGNEE: The authorization will be applied to the one who is assigned to the task.
  • OTHERS: This scope has the least priority. If no other rule applies to the user that needs to be authorized, the authorization with this scope will be applied (if there is any).

Operation

The following operations can be authorized:

All

Applies to every operation.

  • ALL: If denied, the scope of the authorization will not be able to execute any operations listed below .
Process

Valid only in the process.

  • START_PROCESS: If denied, the scope of the authorization will not be able to start the process (note: if there are no authorizations specified by candidates or tags, this will be denied for all scopes by default).
  • CANCEL_PROCESS: If denied, the scope of the authorization will not be able to cancel the process.
  • SUSPEND_PROCESS: If denied, the scope of the authorization will not be able to suspend the process.
  • ACTIVATE_PROCESS: If denied, the scope of the authorization will not be able to activate the process.
  • LIST_PROCESS: If denied, the scope of the authorization will not be able to see the process instance when using the search feature (including historic process instances, which have been finished).
Task

Valid only in the tasks.

  • DELEGATE_TASK: If denied, the scope of the authorization will not be able to delegate the task.
  • COMPLETE_TASK: If denied, the scope of the authorization will not be able to complete the task.
  • CLAIM_TASK: If denied, the scope of the authorization will not be able to claim the task.
  • UNCLAIM_TASK: If denied, the scope of the authorization will not be able to unclaim the task.
  • ACCEPT_DELEGATION: If denied, the scope of the authorization will not be able to accept the delegated task.
  • REJECT_DELEGATION: If denied, the scope of the authorization will not be able to reject the delegated task.
  • LIST_TASK: If denied, the scope of the authorization will not be able to see the task instance when using the search feature (including historic task instances, which have been completed).
Variables

Valid in both process and tasks.

  • READ_VARIABLES: If denied, the scope of the authorization will not be able to read the variables of the process or task.
  • SET_VARIABLE: If denied, the scope of the authorization will not be able to set the variables of the process or task.
  • WRITE_VARIABLE: If denied, the scope of the authorization will not be able to write the variables of the process or task.
Comments

Valid in both process and tasks.

  • READ_COMMENTS: If denied, the scope of the authorization will not be able to read comments of the process or task.
  • ADD_COMMENT: If denied, the scope of the authorization will not be able to add comments to the process or task.
  • DELETE_COMMENT: If denied, the scope of the authorization will not be able to delete comments of the process or task.
Attachments

Valid in both process and tasks.

  • READ_ATTACHMENTS: If denied, the scope of the authorization will not be able to read attachments of the process or task.
  • ADD_ATTACHMENT: If denied, the scope of the authorization will not be able to add attachments to the process or task.
  • DELETE_ATTACHMENT: If denied, the scope of the authorization will not be able to delete attachments of the process or task.

Permission

The following permissions are accepted:

  • ALLOW: If the authorization applies to the user, the operation will be allowed.
  • DENY: If the authorization applies to the user, the operation will be denied.

Possible approaches to authorization

There are two basic approaches to authorization:

  • White-listing: DENY everything on the process or task through a large-scoped permission (e.g., OTHERS) with OPERATION: ALL, ALLOW selected operations for smaller-scoped permissions (e.g., USER).
    • The START_PROCESS operation works on a white-listing basis; permission is denied by default; allowing operations has to be done explicitly if needed.
  • Black-listing: ALLOW everything on the process or task through a large-scoped permission (e.g., OTHERS) with OPERATION: ALL, DENY selected operations for smaller-scoped permissions (e.g., USER).
    • Every operation except for START_PROCESS works on a black-listing basis; permission is given by default; denying operations has to be done explicitly if needed.

Candidates

Candidate conflicts

The new authorization engine cooperates with the candidate authorizations provided by Activiti (which is considered to be the "old" authorization). Although using the new authorization is advised for every scenario, the two authorization mechanisms can both be included in the same BPMN.

To ensure backward compatibility, the candidate authorization functionality has not changed. Users specified in the candidate authorizations will receive permissions as before.

However, the simultaneous use of the old and the new authorization system may result in conflicts. Consider the following:

<process activiti:candidateStarterGroups="nevisWF">

<neviswf:authorization
neviswf:scope="GROUP"
neviswf:operation="START_PROCESS"
neviswf:permission="DENY"><neviswf:group>nevisWF</neviswf:group>
</neviswf:authorization>

</process>

To resolve the conflict, the contradictory authorizations will be resolved using the rule defined in the priority of permissions (with contradictory authorizations of the same scope, DENY permissions are always stronger, see section "Priority of permissions").

The evaluation of the tags above can be broken down as follows:

  • The old authorization attribute (activiti:candidateStarterGroups="nevisWF") will allow the group nevisWF to start the process, and deny every other group.
  • The new authorization tag (neviswf:authorization neviswf:scope="GROUP" neviswf:operation="START_PROCESS" neviswf:permission="DENY") will deny permission from the group nevisWF to start the process.
  • As a result, no one will have permission to start the process in the example above.

Upgrading candidates

Upgrading candidate authorizations is not necessary, but it is possible. Consider the following simple candidate authorization:

<process activiti:candidateStarterGroups="nevisWF">
</process>

The authorization above has its equivalent definition using the new authorization tags:

<process>

<extensionElements>

<neviswf:authorization
neviswf:scope="GROUP"
neviswf:operation="ALL"
neviswf:permission="ALLOW"><neviswf:group>nevisWF</neviswf:group>
</neviswf:authorization>

<neviswf:authorization
neviswf:scope="OTHERS"
neviswf:operation="ALL"
neviswf:permission="DENY">
</neviswf:authorization>

</extensionElements>
</process>

Note the purpose of the second authorization tag in the example above:

<neviswf:authorization
neviswf:scope="OTHERS"
neviswf:operation="ALL"
neviswf:permission="DENY">
</neviswf:authorization>

This tag guarantees identical behavior to that of the candidate authorization, where the group nevisWF is given permission, while everyone else is denied.

EL expressions on authorizations

Introduction to EL expressions in the authorization

Expressions written in EL (expression language) can now be part of the authorization tags. These are supported on two scopes: USER, and GROUP.

As mentioned above, when authorizing for the USER or GROUP scope, hard-coded values are specified between the opening and the closing tag to identify the entity to which the authorization belongs.

These hard-coded values can be changed to EL expressions, as follows:

<process>
<extensionElements>
<neviswf:authorization
xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER"
neviswf:operation="ALL"
neviswf:permission="DENY">

<neviswf:user>
#{stringProcVar}
</neviswf:user>

</neviswf:authorization>
</extensionElements>
</process>

The example above works just as hard-coded values if the stringProcVar is declared and is defined to point at a specific user.

How to create and define variables

There are two use cases for creating and defining variables:

It can be done either via the GUI by using custom .xhtml files.

Or via REST service:

PUT runtime/process-instances/{processInstanceId}/variables/{variableName}

Example request for creating a new variable:

PUT runtime/process-instances/12563/variables/

Request body:

[
{
"name":"stringProcVar",
"type":"string",
"value":"user1, user2, user3"
}
]

The variables are then stored in the database in the ACTRU_VARIABLE tableTEXTfield:

TEXT_
user1, user2, user3

Note that multiple users are put in the same variable separated by comma. No other delimiters are accepted.*

How to switch on the authorization engine

The authorization engine can be switched on in neviswf.properties (or use neviswf config command):

authorization.enabled=true

How to use the authorization engine

Basic construction

The authorization engine can be used via BPMNs, where the authorizations are determined for the following attributes, see also section Attributes:

  • To whom the authorization applies, details in section Scope
  • To which operation the authorization applies, details in section Operation
  • Whether the authorization allows or denies the permission, details in section Permission

These attributes are defined in the form of authorization tags.

Functionality and syntax rules

  1. Any operation (except for START_PROCESS) without a specified authorization tag is set to ALLOW by default. If the operation does not need to be restricted, the authorization tags are not required in the BPMNs.
  2. The authorization engine allows every unspecified authorization, except START_PROCESS authorization for the startable processes list reachable from the GUI. The reason is that special "technical" processes can be created without any authorization tags defined in the BPMN, such as the taskDelegationProcess and the notification process. As a result, processDefinitions (also known as the BPMN itself) without any defined activiti:candidateStarterUsers or activiti:candidateStarterGroups or authorization tag containing an ALLOW on START_PROCESS operation cannot be started by users using the nevisWorkflow GUI.
  3. Whenever a new authorization is added, all of the attributes must be defined.
  4. The authorization definition syntax is written as follows (explanations in red):
Authorization definition syntax

For basic usage of authorization tags, see section Process and task authorization. For more complex examples, see section BPMN examples.

Prioritize authorizations

 Priority of scopes

The scopes define to whom the authorizations applies. It is highly likely that multiple authorization tags will apply for a single user operation; moreover, these tags may convey contradicting information.

Authorization priority handles such cases. Consider the following simple scenario:

<process>
<extensionElements>

<neviswf:authorization
xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="GROUP"
neviswf:operation="READ_COMMENTS"
neviswf:permission="DENY">

<neviswf:group>
nevisWF.Admin
</neviswf:group>
</neviswf:authorization>
<neviswf:authorization
xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER"
neviswf:operation="READ_COMMENTS"
neviswf:permission="ALLOW">

<neviswf:user>
nwf.ch.admin
</neviswf:user>
</neviswf:authorization>

</extensionElements>
</process>

The user nwf.ch.admin is part of the group nevisWF.Admin, so both authorizations should apply when the user tries to read the comments (READ_COMMENTS) on a process instance. According to the authorization with SCOPE=GROUP, the user within the group is denied to do so. And according to the authorization with SCOPE=USER, the user is allowed to read comments.

Which tag should be taken into consideration?

If this or a similar case happens, the priority of the authorization's scope will handle which one should be applied. The higher the priority of the given scope, the stronger it is. The stronger scope's authorization will be applied.

The priority of the scopes can be summarized as follows (the more specific the scope, the stronger it is):

Priority of scopes

As per the scale above, the aforementioned scenario can be resolved easily. The USER scope is stronger than the GROUP scope, therefore the authorization with USER scope will be applied, and comments can be read by the user nwf.ch.admin.

Priority of permissions

Consider a scenario, where explicitly contradictory authorizations are added to a BPMN:

<process>
<extensionElements>

<neviswf:authorization
xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="PROCESS_STARTER"
neviswf:operation="READ_COMMENTS"
neviswf:permission="DENY">
</neviswf:authorization>

<neviswf:authorization
xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="PROCESS_STARTER"
neviswf:operation="READ_COMMENTS"
neviswf:permission="ALLOW">
</neviswf:authorization>
</extensionElements>
</process>

To resolve the contradictory statements, DENY permissions are stronger by definition in these cases, when the scope priority cannot determine whether to allow or deny permission.

Process and task authorization

Authorization tag on a process

The authorization tags can be added to processes as follows. The following tag will prevent the process starter from reading any attachments:

<process>
<extensionElements>
<neviswf:authorization
xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="PROCESS_STARTER"
neviswf:operation="READ_ATTACHMENTS"
neviswf:permission="DENY">
</neviswf:authorization>
</extensionElements>
</process>

The authorization tag will only impact on its parent element. In the case above it will be applied on the process instance, which will be created from this BPMN.

Authorization tag on a task

Authorization tags can also be added to tasks as follows. The following tag will prevent the user nwf.ch.admin from completing the task:

<process>
<userTask>
<extensionElements>
<neviswf:authorization
xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER"
neviswf:operation="COMPLETE_TASK"
neviswf:permission="DENY">

<neviswf:user>
nwf.ch.admin
</neviswf:user>
</neviswf:authorization>
</extensionElements>
</userTask>
</process>

It is important to note that the authorization will have the impact on the userTask (since it is the parent element), but not on the process instance.

Use cases

Using the previous authorization system exclusively

The previous authorization system can be used exclusively, without utilizing any of the functionality provided by the new authorization engine.

The authorization engine can be switched off in neviswf.properties (or use neviswf config command):

authorization.enabled=false

The system will then function as it had previously; the candidate authorizations provide the same options.

Using the new authorization system exclusively

Similarly, the new authorization system can be used exclusively, without using the candidate authorizations. For instructions on how to upgrade authorizations in the BPMNs, refer to the sections: How to use the authorization engine and Upgrading candidates.

Using the two authorization systems together

The candidate authorization can be used together with the new engine as well. This solution is not completely backward compatible.

  • Refer to section Behavioral differences - GUI and REST service for information on behavioral differences.
  • Refer to the section Candidate conflicts for information about how conflicts are handled.

BPMN examples

Examples using only the new authorization

Authorization example 1

The user nwf.ch.admin is part of the group nevisWF.Admin. The group nevisWF.Admin gets permission to execute all operations in the process, while others get denied the same permission. Any user outside the group nevisWF.Admin will not be able to start the process or execute related operations. The user nwf.ch.admin will be able to start/cancel/suspend/activate the process, others will not.

BPMN
<process id="newAuth1" name="GROUPA favored" isExecutable="true">
<extensionElements>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="OTHERS" neviswf:operation="ALL" neviswf:permission="DENY">
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="GROUP" neviswf:operation="ALL" neviswf:permission="ALLOW">
<neviswf:group>nevisWF.Admin</neviswf:group>
</neviswf:authorization>
</extensionElements>
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="TestTask1" activiti:candidateGroups="nevisWF.User"
activiti:formKey="/views/workflow/exampleTasks/exampleTask1"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1"
targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
</process>

The user nwf.ch.admin can execute any operation related to the process. None of the buttons will be disabled.

Authorization example 1
Authorization example 2

The assignee of TestTask2 is the only one with the right to unclaim or complete the task. All authorizations on operations on the task are denied for everyone else.

Note that the process starter receives permission to claim the task; otherwise the white-listing approach would prohibit everyone from claiming the task.

BPMN
<process id="newAuth2" name="Assignee favored" isExecutable="true">
<extensionElements>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="GROUP" neviswf:operation="START_PROCESS" neviswf:permission="ALLOW">
<neviswf:group>nevisWF.Admin</neviswf:group>
</neviswf:authorization>
</extensionElements>
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="TestTask2"
activiti:formKey="/views/workflow/exampleTasks/exampleTask2">
<extensionElements>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="PROCESS_STARTER" neviswf:operation="CLAIM_TASK"
neviswf:permission="ALLOW">
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="ASSIGNEE" neviswf:operation="UNCLAIM_TASK" neviswf:permission="ALLOW">
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="ASSIGNEE" neviswf:operation="COMPLETE_TASK" neviswf:permission="ALLOW">
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="OTHERS" neviswf:operation="ALL" neviswf:permission="DENY">
</neviswf:authorization>
</extensionElements>
</userTask>
<sequenceFlow id="flow1" sourceRef="startevent1"
targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
</process>

The assignee of the task (nwf.ch.admin) can complete or unclaim the task.

Note that delegation is prohibited due to white-listing; the Delegate button will be disabled.

Authorization example 2
Authorization example 3

The group nevisWF.Admin is prohibited from adding comments on the process instance. The user nwf.ch.admin is given permission to comment, others are denied from doing so.

BPMN
<process id="newAuth3" name="USERA favored" isExecutable="true">
<extensionElements>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="GROUP" neviswf:operation="ADD_COMMENT" neviswf:permission="DENY">
<neviswf:group>nevisWF.Admin</neviswf:group>
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER" neviswf:operation="ADD_COMMENT" neviswf:permission="ALLOW">
<neviswf:user>nwf.ch.admin</neviswf:user>
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER" neviswf:operation="START_PROCESS" neviswf:permission="ALLOW">
<neviswf:user>nwf.ch.admin</neviswf:user>
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="OTHERS" neviswf:operation="ALL" neviswf:permission="DENY">
</neviswf:authorization>
</extensionElements>
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="TestTask3"
activiti:formKey="/views/workflow/exampleTasks/exampleTask3"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1"
targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
</process>

Due to the priority of scopes, see the chapter Priority of scopes nwf.ch.admin is able to leave a comment:

Authorization example 3
Authorization example 4

Commenting on the process is forbidden for all by the authorization tag specifying the scope OTHERS. As it is the only tag referencing the operation in the process, it will apply for every user.

BPMN
<process id="newAuth4" name="No Comment" isExecutable="true">
<extensionElements>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="GROUP" neviswf:operation="START_PROCESS" neviswf:permission="ALLOW">
<neviswf:group>nevisWF.Admin</neviswf:group>
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="OTHERS" neviswf:operation="ADD_COMMENT" neviswf:permission="DENY">
</neviswf:authorization>
</extensionElements>
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="TestTask4"
activiti:formKey="/views/workflow/exampleTasks/exampleTask4></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1"
targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
</process>

As commenting is denied completely, nwf.ch.admin cannot leave a comment on the process:

Authorization example 4a

Neither can nwf.hu.user:

Authorization example 4b

Examples using candidates and the new authorization combined

Combined authorization example 1

The group nevisWF.Admin receives authorization for all operations via candidateStarterGroups. Everyone else is denied by the authorization tag.

BPMN
<process id="mixedAuth1" name="GROUPA favored mix" isExecutable="true"
activiti:candidateStarterGroups="nevisWF.Admin">
<extensionElements>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="OTHERS" neviswf:operation="ALL" neviswf:permission="DENY">
</neviswf:authorization>
</extensionElements>
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="MixedTest1"
activiti:formKey="/views/workflow/exampleTasks/exampleTask5"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1"
targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
</process>

The user nwf.ch.admin is able to start and manipulate the process; non-members of the group nevisWf.Admin are not:

Combined authorization example 1

Combined authorization example 2

The group nevisWF.Admin receives permission on any operation via candidateStarterGroups, but is not allowed to comment on the process because of the authorization tag.

BPMN
<process id="mixedAuth2" name="No Comment Mix" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="MixedTest2"
activiti:candidateStarterGroups="nevisWF.Admin"
activiti:formKey="/views/workflow/exampleTasks/exampleTask6">
<extensionElements>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="GROUP" neviswf:operation="ADD_COMMENT" neviswf:permission="DENY">
<neviswf:group>nevisWF.Admin</neviswf:group>
</neviswf:authorization>
</extensionElements>
</userTask>
<sequenceFlow id="flow1" sourceRef="startevent1"
targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
</process>

The user nwf.ch.admin is allowed to execute any operation on the process, except for leaving a comment:

Combined authorization example 2
Combined authorization example 3

The group nevisWF.Admin is specified on the process as a candidateStarterGroup,**nwf.ch.admin is prohibited from commenting on the process. At the same time, nwf.hu.user receives permission for all operations of the process. As a result, nwf.ch.admin can start the process but cannot comment on it, while nwf.hu.user can.

BPMN
<process id="mixedAuth3" name="USERHU favored" isExecutable="true"
activiti:candidateStarterGroups="nevisWF.Admin">
<extensionElements>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER" neviswf:operation="ALL" neviswf:permission="ALLOW">
<neviswf:user>nwf.hu.user</neviswf:user>
</neviswf:authorization>
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER" neviswf:operation="ADD_COMMENT" neviswf:permission="DENY">
<neviswf:user>nwf.ch.admin</neviswf:user>
</neviswf:authorization>
</extensionElements>
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="MixedTest3"
activiti:formKey="/views/workflow/exampleTasks/exampleTask7"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1"
targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
</process>

The user nwf.ch.admin can start the process but cannot leave a comment on it:

Combined authorization example 3a

The user nwf.hu.user can start the process and add comments to it:

Combined authorization example 3b

Behavioral differences - GUI and REST service

With candidates / without the new authorization

Candidates use white-listing:

  • Activiti service responses will consider candidates
  • REST service → does not enforce any candidate check for any REST operation.
    • Some REST service responses depend on IdentityLinks (Activiti User Guide 15.7.2. List of tasks → GET runtime/tasks →
      candidateUser/candidateGroup/candidateGroups/involvedUser/candidateOrAssigned).
Everything is backward compatible
  • ALLOW-ed permissions based on IdentityLinks for users/groups
  • OTHERS scoped permission with DENY for the other users

With candidates / with the new authorization

Candidates use white-listing.

The new authorization uses black-listing:

  • Activiti services and also the REST services are intercepted and authorized based on the new authorization tags.
Not everything is backward compatible
  • Candidates will behave the same.
  • New authorization tags can override candidates:
<userTask id="usertask1" name="JustATask" activiti:candidateUsers="nwf.hu.user" >
overridden by
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER" neviswf:operation="CLAIM_TASK" neviswf:permission="DENY">
<neviswf:user>nwf.hu.user</neviswf:user>
</neviswf:authorization>
  • New authorization tags can extend candidates:
<userTask id="usertask1" name="JustATask" activiti:candidateUsers="nwf.hu.user" >
overridden by
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="USER" neviswf:operation="CLAIM_TASK" neviswf:permission="DENY">
<neviswf:user>nwf.hu.user</neviswf:user>
</neviswf:authorization>
  • New authorization tags can override each other:
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="PROCESS_STARTER" neviswf:operation="LIST_TASK"
neviswf:permission="ALLOW">
</neviswf:authorization>
overridden by (if the process starter is in group nevisWF.ProcessStarter)
<neviswf:authorization xmlns:neviswf="http://adnovum.ch/neviswf/bpmn"
neviswf:scope="GROUP" neviswf:operation="LIST_TASK" neviswf:permission="ALLOW">
<neviswf:group>nevisWF.ProcessStarter</neviswf:group>
</neviswf:authorization>
Known Limitations
  • Must provide START_PROCESS scoped permissions with ALLOW-ed for users/groups for processes.
  • Must provide CLAIM_TASK scoped permissions with ALLOW-ed for users/groups for UserTasks (if there are no candidates defined or the desired user/group is not among the candidates).

Without candidates / with the new authorization

The new authorization uses black-listing.

  • Activiti services and also the REST services are intercepted and authorized based on the new authorization tags.

  • Must provide START_PROCESS scoped permissions with ALLOW-ed for users/groups for processes.

  • Must provide CLAIM_TASK scoped permissions with ALLOW-ed for users/groups for UserTasks.

Without candidates / with the new authorization

The new authorization uses black-listing.

  • Activiti services and also the REST services are intercepted and authorized based on the new authorization tags.
Known limitations
  • Must provide START_PROCESS scoped permissions with ALLOW-ed for users/groups for processes.
  • Must provide CLAIM_TASK scoped permissions with ALLOW-ed for users/groups for UserTasks.

Without candidates / without the new authorization

"Technical" processes not started by users but other processes, for example:

  • Notifications
  • nevisWFTaskDelegation
Known limitations
  • They will not be visible on the nevisWorkflow GUI as startable processes.
  • They can be started using REST service.

Deployment problems troubleshooting

Processes disappeared on the GUI. What is the source of the issue?

The syntax rules detailed in section Functionality and syntax rules have to be followed very carefully. If there are syntactic issues within the BPMN files, these will not be discovered at compile time – the BPMN files are simply not parsed when syntax errors are encountered. The following tips can help in avoiding such problems, or finding the cause of the problem when it manifests:

  1. The most obvious symptom of a syntax error within the BPMN file is the disappearance of all processes on the GUI. If this is the case, modified BPMN files have to be checked thoroughly.
  2. The <extensionElements> tag has to be the first tag on the process and on the task.
  3. Each process and task needs its own <extensionElements> tag.
  4. Each <extensionElements> tag has to be closed with </extensionElements> after all the authorization tags are specified for the given process or task.
  5. Attributes cannot be missing from the tags, each authorization tag must contain:
    1. A scope
    2. An operation
    3. A permission
  6. If the scope of the authorization is either USER or GROUP, these have to be specified in between the opening and closing tag of the authorization. See the examples above.

REST interface

nevisWorkflow makes use of the Activiti REST API. This chapter shows you how to use this REST API and provides details about the functionality.

The configuration of the REST interface is described in the chapter REST service security.

Customized REST services

See the original service description at: http://www.activiti.org/userguide/#_create_a_new_attachment_on_a_task_containing_a_link_to_an_external_resource.

The difference in nevisWorkflow compared to the original Activiti service is that we only set the TASK _ID for the attachment, the PROC _INST _ID will be null.

Create a new attachment on a task, with an attached file

See the original service description at: https://www.activiti.org/userguide/#_create_a_new_attachment_on_a_task_with_an_attached_file.

The difference in nevisWorkflow compared to the original Activiti service is that we only set the TASK _ID for the attachment, the PROC _INST _ID will be null.

Create a new comment on a task

See the original service description at: https://www.activiti.org/userguide/#_create_a_new_comment_on_a_task.

The difference in nevisWorkflow compared to the original Activiti service is that we only set the TASK _ID for the attachment, the PROC _INST _ID will be null.

This is also the reason why parameter saveProcessInstanceId : true will not take effect.

REST services provided by nevisWorkflow

Accessing nevisWorkflow authorizations

Get authorizations of a task
Usage
GET /runtime/tasks/{taskId}/authorizations?operation={operation}
ParameterRequiredValueDescription
taskIdYesStringThe ID of the task for which to get the authorizations.
operationNoStringOnly returns authorizations with the given operation.
Success response body
{
"Task Instance": {
"id": "2761",
"url": "https://localhost:9943/neviswf/rest/runtime/tasks/2761",
"owner": null,
"assignee": null,
"delegationState": null,
"name": "CanAuth",
"description": null,
"createTime": "2017-03-21T14:14:15.900+01:00",
"dueDate": null,
"priority": 50,
"suspended": false,
"taskDefinitionKey": "usertask1CanAuth",
"tenantId": "", "category": null,
"formKey": "/views/workflow/exceptionTester/exceptionTester.xhtml",
"parentTaskId": null,
"parentTaskUrl": null,
"executionId": "2757",
"executionUrl": "https://localhost:9943/neviswf/rest/runtime/executions/2757",
"processInstanceId": "2757",
"processInstanceUrl": "https://localhost:9943/neviswf/rest/runtime/process-
instances/2757",
"processDefinitionId": "CanAuth:1:2577",
"processDefinitionUrl": "https://localhost:9943/neviswf/rest/repository/process-
definitions/CanAuth:1:2577",
"variables": []
},
"Authorization permissions": [
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "READ_COMMENTS",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.admin",
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "REJECT_DELEGATION",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.admin",
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "DELETE_ATTACHMENT",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
}
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
}
]
}
Success response body with operation
{
"Task Instance": {
"id": "2761",
"url": "https://localhost:9943/neviswf/rest/runtime/tasks/2761",
"owner": null,
"assignee": null,
"delegationState": null,
"name": "CanAuth",
"description": null,
"createTime": "2017-03-21T14:14:15.900+01:00",
"dueDate": null, "priority": 50, "suspended": false,
"taskDefinitionKey": "usertask1CanAuth",
"tenantId": "",
"category": null,
"formKey": "/views/workflow/exceptionTester/exceptionTester.xhtml",
"parentTaskId": null,
"parentTaskUrl": null,
"executionId": "2757",
"executionUrl": "https://localhost:9943/neviswf/rest/runtime/executions/2757",
"processInstanceId": "2757",
"processInstanceUrl": "https://localhost:9943/neviswf/rest/runtime/process-
instances/2757",
"processDefinitionId": "CanAuth:1:2577",
"processDefinitionUrl": "https://localhost:9943/neviswf/rest/repository/process-
definitions/CanAuth:1:2577",
"variables": []
},
"Authorization permissions": [
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "USER", "permission": "ALLOW",
"users": [
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "USER",
"permission": "DENY",
"users": [
"nwf.hu.admin"
],
"groups": null,
"variables": null \
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.admin",
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "ALL",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.admin",
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "ALL",
"scope": "OTHERS",
"permission": "DENY",
"users": null, "groups": null, "variables": null
}
]
}
Invalid operation response
{
"message": "Bad request",
"exception": "Not supported Task operation 'INVALID_OPERATION' ."
}
Response codeDescription
200Indicates the task was found and returned with its authorizations.
404Indicates the requested task was not found.
400Indicates the operation is not a valid one.
Get authorizations of a historic task
Usage
GET /history/tasks/{taskId}/authorizations?operation={operation}
ParameterRequiredValueDescription
taskIdYesStringThe ID of the historic task for which to get the authorizations.
operationNoStringOnly returns authorizations with the given operation.
Success response body
{
"Historic Task": {
"id": "2761",
"processDefinitionId": "CanAuth:1:2577",
"processDefinitionUrl": "https://localhost:9943/neviswf/rest/repository/process-
definitions/CanAuth:1:2577",
"processInstanceId": "2757",
"processInstanceUrl": "https://localhost:9943/neviswf/rest/history/historic-process-
instances/2757",
"executionId": "2757",
"name": "CanAuth",
"description": null,
"deleteReason": null,
"owner": null,
"assignee": null,
"startTime": "2017-03-21T14:14:15.900+01:00",
"endTime": null,
"durationInMillis": null,
"workTimeInMillis": null,
"claimTime": null,
"taskDefinitionKey":
"usertask1CanAuth",
"formKey": "/views/workflow/exceptionTester/exceptionTester.xhtml",
"priority": 50,
"dueDate": null,
"parentTaskId": null,
"url": "https://localhost:9943/neviswf/rest/history/historic-task-instances/2761",
"variables": [],
"tenantId": "",
"category": null
},
"Authorization permissions": \[
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "READ_COMMENTS",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.admin",
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null \},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "SET_VARIABLE",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "LIST_TASK",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
}
]
}
Success response body with operation
{
"Historic Task": {
"id": "2761",
"processDefinitionId": "CanAuth:1:2577",
"processDefinitionUrl": "https://localhost:9943/neviswf/rest/repository/process-
definitions/CanAuth:1:2577",
"processInstanceId": "2757",
"processInstanceUrl": "https://localhost:9943/neviswf/rest/history/historic-process-
instances/2757",
"executionId": "2757",
"name": "CanAuth",
"description": null,
"deleteReason": null,
"owner": null,
"assignee": null,
"startTime": "2017-03-21T14:14:15.900+01:00",
"endTime": null,
"durationInMillis": null,
"workTimeInMillis": null,
"claimTime": null,
"taskDefinitionKey": "usertask1CanAuth",
"formKey": "/views/workflow/exceptionTester/exceptionTester.xhtml",
"priority": 50,
"dueDate": null,
"parentTaskId": null,
"url": "https://localhost:9943/neviswf/rest/history/historic-task-instances/2761",
"variables": [],
"tenantId": "",
"category": null
},
"Authorization permissions": [
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "USER",
"permission": "DENY",
"users": [
"nwf.hu.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.admin",
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "CLAIM_TASK",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "ALL",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.admin",
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": "usertask1CanAuth",
"operation": "ALL",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
}
]
}
Invalid operation response
{
"message": "Bad request",
"exception": "Not supported Task operation 'INVALID_OPERATION' ."
}
Response codeDescription
200Indicates the historic task was found and returned with its authorizations.
404Indicates the requested historic task was not found.
400Indicates the operation is not a valid one.
Get authorizations of a process instance
Usage
GET /runtime/process-instances/{processInstanceId}/authorizations?operation={operation}
ParameterRequiredValueDescription
processInstanceIdYesStringThe ID of the process instance for which to get the authorizations.
operationNoStringOnly returns authorizations with the given operation.
Success response body
{
"ProcessInstance": {
"id": "2757",
"url": "https://localhost:9943/neviswf/rest/runtime/process-instances/2757",
"businessKey": null,
"suspended": false,
"ended": false,
"processDefinitionId": "CanAuth:1:2577",
"processDefinitionUrl": "https://localhost:9943/neviswf/rest/repository/process-
definitions/CanAuth:1:2577",
"activityId": "usertask1CanAuth", "
variables": [],
"tenantId": "",
"completed": false
},
"Authorization permissions": [
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "READ_COMMENTS",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "SUSPEND_PROCESS",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "DELETE_COMMENT",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "ACTIVATE_PROCESS",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
}
]
}
Success response body with operation
{
"ProcessInstance": {
"id": "2757",
"url": "https://localhost:9943/neviswf/rest/runtime/process-instances/2757",
"businessKey": null,
"suspended": false,
"ended": false,
"processDefinitionId": "CanAuth:1:2577",
"processDefinitionUrl": "https://localhost:9943/neviswf/rest/repository/process-
definitions/CanAuth:1:2577",
"activityId": "usertask1CanAuth",
"variables": [],
"tenantId": "",
"completed": false
},
"Authorization permissions": [
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "SUSPEND_PROCESS",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "SUSPEND_PROCESS",
"scope": "GROUP",
"permission": "ALLOW",
"users": null,
"groups": [
"nevisWF.User"
],
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "SUSPEND_PROCESS",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "ALL",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "ALL",
"scope": "GROUP",
"permission": "ALLOW",
"users": null,
"groups": [
"nevisWF.User"
],
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "ALL",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
}
]
}
Invalid operation response
{
"message": "Bad request",
"exception": "Not supported Process operation 'INVALID_OPERATION' ."
}
Response codeDescription
200Indicates the process instance was found and returned with its authorizations.
404Indicates the requested process instance was not found.
400Indicates the operation is not a valid one.
Get authorizations of a historic process instance
Usage
GET /history/process-instances/{processInstanceId}/authorizations?operation={operation}
ParameterRequiredValueDescription
processInstanceIdYesStringThe ID of the historic process instance for which to get the authorizations.
operationNoStringOnly returns authorizations with the given operation.
Success response body
{
"Historic ProcessInstance": {
"id": "2757",
"url": "https://localhost:9943/neviswf/rest/history/historic-process-
instances/2757",
"businessKey": null,
"processDefinitionId": "CanAuth:1:2577",
"processDefinitionUrl": "https://localhost:9943/neviswf/rest/repository/process-
definitions/CanAuth:1:2577",
"startTime": "2017-03-21T14:14:15.889+01:00",
"endTime": null,
"durationInMillis": null,
"startUserId": "nwf.ch.admin",
"startActivityId": "startevent1",
"endActivityId": null,
"deleteReason": null,
"superProcessInstanceId": null,
"variables": [],
"tenantId": ""
},
"Authorization permissions": [
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "READ_ATTACHMENTS",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "DELETE_ATTACHMENT",
"scope": "GROUP",
"permission": "ALLOW",
"users": null,
"groups": [
"nevisWF.User"
],
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "LIST_PROCESS",
"scope": "GROUP",
"permission": "ALLOW",
"users": null,
"groups": [
"nevisWF.User"
],
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "ADD_ATTACHMENT",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
}
]
}
Success response body with operation
{
"Historic ProcessInstance": {
"id": "2757",
"url": "https://localhost:9943/neviswf/rest/history/historic-process-
instances/2757",
"businessKey": null,
"processDefinitionId": "CanAuth:1:2577",
"processDefinitionUrl": "https://localhost:9943/neviswf/rest/repository/process-
definitions/CanAuth:1:2577",
"startTime": "2017-03-21T14:14:15.889+01:00",
"endTime": null,
"durationInMillis": null,
"startUserId": "nwf.ch.admin",
"startActivityId": "startevent1",
"endActivityId": null,
"deleteReason": null,
"superProcessInstanceId": null,
"variables": [],
"tenantId": ""
},
"Authorization permissions": [
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "SUSPEND_PROCESS",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "SUSPEND_PROCESS",
"scope": "GROUP",
"permission": "ALLOW",
"users": null,
"groups": [
"nevisWF.User"
],
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "SUSPEND_PROCESS",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "ALL",
"scope": "USER",
"permission": "ALLOW",
"users": [
"nwf.hu.user",
"nwf.ch.admin"
],
"groups": null,
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "ALL",
"scope": "GROUP",
"permission": "ALLOW",
"users": null,
"groups": [
"nevisWF.User"
],
"variables": null
},
{
"processKey": "CanAuth",
"taskKey": null,
"operation": "ALL",
"scope": "OTHERS",
"permission": "DENY",
"users": null,
"groups": null,
"variables": null
}
]
}
Invalid operation response
{
"message": "Bad request",
"exception": "Not supported Process operation 'INVALID_OPERATION' ."
}

Response codeDescription
200Indicates the task was found and returned with its authorizations.
404Indicates the requested task was not found.
400Indicates the operation is not a valid one.

 Authorization operation enforceability

Task authorization operation enforceability
Usage
GET /runtime/tasks/{taskId}/authorization-operation/{operation}
ParameterRequiredValueDescription
taskIdYesStringThe ID of the task to get the authorization for.
operationNoStringOnly returns authorizations with the given operation.
Success response body
{
"operation": "CLAIM_TASK",
"allowed": true
}
{
"operation": "CLAIM_TASK",
"allowed": false
}
Response codeDescription
200Indicates the task was found and returned with the corresponding response.
404Indicates the requested task was not found.
400Indicates the operation is not a valid one.
Historic task authorization operation enforceability
Usage
GET /history/tasks/{taskId}/authorization-operation/{operation}
ParameterRequiredValueDescription
taskIdYesStringThe ID of the historic process instance for which to get the authorizations.
operationNoStringOnly returns authorizations with the given operation.
ParameterRequiredValueDescription
taskIdYesStringThe ID of the historic process instance for which to get the authorizations.
operationNoStringOnly returns authorizations with the given operation.
Success response body
{
"operation": "CLAIM_TASK",
"allowed": true
}
{
"operation": "CLAIM_TASK",
"allowed": false
}
Response codeDescription
200Indicates the historic task was found and returned with the corresponding response.
404Indicates the requested historic task was not found.
400Indicates the operation is not a valid one.
Process instance authorization operation enforceability
Usage
GET /runtime/process-instances/{processInstanceId}/authorization-operation/{operation}
ParameterRequiredValueDescription
processInstanceIdYesStringThe ID of the process instance for which to get the authorizations.
operationNoStringOnly returns authorizations with the given operation.
Success response body
{
"operation": "SUSPEND_PROCESS",
"allowed": true
}
{
"operation": "SUSPEND_PROCESS",
"allowed": false
}
Response codeDescription
200Indicates the process instance was found and returned with the corresponding response.
404Indicates the requested process instance was not found.
400Indicates the operation is not a valid one.
Historic process instance authorization operation enforceability
Usage
GET /history/process-instances/{processInstanceId}/authorization-operation/{operation}
ParameterRequiredValueDescription
processInstanceIdYesStringThe ID of the historic process instance for which to get the authorizations.
operationNoStringOnly returns authorizations with the given operation.
Success response body
{
"operation": "SUSPEND_PROCESS",
"allowed": true
}
{
"operation": "SUSPEND_PROCESS",
"allowed": false
}
Response codeDescription
200Indicates the historic process instance was found and returned with the corresponding response.
404Indicates the requested historic process instance was not found.
400Indicates the operation is not a valid one.

General services

Usage
POST/runtime/process-instances/{processInstanceId}/attachments
ParameterRequiredValueDescription
processInstanceIdYesStringThe ID of the process instance for which to create the attachment.
Request body
{
"name":"Simple attachment",
"description":"Simple attachment description",
"type":"simpleType",
"externalUrl":"http://activiti.org"
}

Only the attachment name is required to create a new attachment.

Success response body
{
"id": "2566",
"url": null,
"name": "Simple attachment",
"userId": "neviswf",
"description": "Simple attachment description",
"type": "simpleType",
"taskUrl": null,
"processInstanceUrl": "https://localhost:9943/neviswf/rest/runtime/process-
instances/2560",
"externalUrl": "http://activiti.org",
"contentUrl": null,
"time": "2017-01-19T11:31:42.527+01:00"
}
Response codeDescription
201Indicates the attachment was created and the result is returned.
400Indicates the attachment name is missing from the request.
404Indicates the requested process instance was not found.
Create a new attachment on a process instance, with an attached file
Usage
POST/runtime/process-instances/{processInstanceId}/attachments
ParameterRequiredValueDescription
processInstanceIdYesStringThe ID of the process instance for which to create the attachment.
Request body

The request should be of type multipart/form-data. There should be a single file-part included with the binary value of the variable. In addition, the following form-fields can be present:

  • name: Required name of the variable.
  • description: Description of the attachment, optional.
  • type: Type of attachment, optional. Supports any arbitrary string or a valid HTTP content type.
Success response body
{
"id": "2568",
"url": null,
"name": "fileName",
"userId": "neviswf",
"description": null,
"type": null,
"taskUrl": null,
"processInstanceUrl": "https://localhost:9943/neviswf/rest/runtime/process-
instances/2560",
"externalUrl": null,
"contentUrl": null,
"time": "2017-01-19T11:42:02.341+01:00"
}

Response codeDescription
201Indicates the attachment was created and the result is returned.
400Indicates the attachment name is missing from the request or no file was present in the request. The error message contains additional information.
404Indicates the requested process instance was not found.
Get all attachments on a process instance
Usage
GET/runtime/process-instances/{processInstanceId}/attachments
ParameterRequiredValueDescription
processInstanceIdYesStringThe ID of the process instance for which to create the attachment.
Success response body
[
{
"id": "2568",
"url": null,
"name": "fileName",
"userId": "neviswf",
"description": null,
"type": null,
"taskUrl": null,
"processInstanceUrl": "https://localhost:9943/neviswf/rest/runtime/process-instances/2560",
"externalUrl": null,
"contentUrl": null,
"time": "2017-01-19T11:42:02.341+01:00"
},
{
"id": "2566",
"url": null,
"name": "Simple attachment",
"userId": "neviswf",
"description": "Simple attachment description",
"type": "simpleType",
"taskUrl": null,
"processInstanceUrl": "https://localhost:9943/neviswf/rest/runtime/process-instances/2560",
"externalUrl": "http://activiti.org", "contentUrl": null, "time": "2017-01-19T11:31:42.527+01:00"
}
]
Response codeDescription
200Indicates the process instance was found and the attachments are returned.
404Indicates the requested process instance was not found.

Security

Process definition - task candidate groups

Activiti has a way to define that only users with specific groups can start a process or claim a task. More information can be found in the Activiti user guide "ACTIVITI USER GUIDE":

nevisWorkflow and nevisIDM use the term "role" while Activiti uses the term "group". In the case of using candidate groups, the roles coming from nevisIDM are used to match groups defined in the bpmn file. As a matter of fact, roles and groups mean the same in nevisWorkflow terms.

Group names for candidateStarterGroups and candidateGroups are up to the process designer. When specifying any groups for these fields, the target users must have those roles defined in nevisIDM (or in the ACTID tables when not using nevisIDM)

More fine-grained solutions to control task assignment and process start can be implemented by using listeners.

REST service security

The REST service is turned off by default to provide a secure default setup. It can be enabled by setting the rest.enabled property to true.

Only users with nevisWF.RestAdmin or nevisWF.TechnicalUser roles are permitted to use the REST service.

Optionally when the REST service is enabled, it is possible to enable the IP-based authentication.

It authenticates users of the REST interface based on their IP address. This can be enabled by setting the property rest.clientip.auth.enabled to true. In this case, only requests from a host with an IP listed in the rest.clientip.auth.whitelist property are allowed to access the REST service.

The IP address of the user is determined with the following method:

  • In case there is an X-Forwarded-For (XFF) HTTP header in the request, the application will consider the IP address from this header.
  • Otherwise, the IP address will be determined based on the IP address from the HTTP request.

nevisWorkflow application roles

All roles are defined as a String with the "nevisWF." prefix, e.g., nevisWF.User, nevisWF.Admin.

Five distinct roles apply to nevisWorkflow:

  • nevisWF.User is required to gain access to the application.
  • nevisWF.Admin is capable of starting and cancelling any process, assigning tasks to anyone, and undeploying workflows.
  • nevisWF.TechnicalUser is not required to have a NEVIS security token, but has the same privileges as the nevisWF.Admin role. Users with this role also automatically use the technical user principal when making calls to nevisIDM. This role can be used in conjunction with, e.g., a file-based JAAS realm to allow other applications to use the REST service.
  • nevisWF.RestAdmin is allowed to access the REST interface.
  • nevisWF.Analyst is allowed to access the analytics screens.

The "User" role is required to have authorized access to nevisWorkflow, and the "Admin" role grants administration privileges to the authenticated user.

In a typical setup, those roles are managed in nevisIDM. For those roles to be defined in nevisIDM, an application called "nevisWF" must be defined with the above two roles (User and Admin). Every user managed in nevisIDM requiring access or administration privileges for nevisWorkflow can then be assigned the required role of the "nevisWF" application.

When not using nevisIDM, the customer can still use the default identity service of Activiti. Tables for the default identity service are the ones prefixed by ACTID. For the nevisWorkflow application roles the role must still be prefixed with "nevisWF."

User Guide - Web GUI

The nevisWorkflow web GUI is self-explanatory to a great extent. In this chapter we provide an overview of the different sections.

Depending on the user’s authorizations (assigned roles), certain GUI sections may not be visible.

Quick start process button

For convenience, on top of the menu list there is a Start process button. When clicking on the button, a list with the latest version of all startable processes is presented.

Personal task list

The personal task list can be found under the menu entry "Tasks – Claimed". The tasks appearing in this list are the tasks that the currently logged in user is supposed to work on and to resolve.
The action button allows performing direct actions for the selected task. Work directly related to the task should be done in the task view itself (opened by selecting the link on the task name).

Suspended task list

The suspended task list displays all the tasks from a process instance that have been suspended. It can be found under the menu entry Tasks – On hold.

Group task inbox

The group task inbox (Tasks - Unassigned) lists all the tasks that are available to be claimed by a user. Those tasks can be handled by the user who sees them in the inbox, but they are not specifically assigned to him. By claiming such a task, the user indicates that he will take care of that specific task.

Running processes

The running processes section lists all the processes that are currently running and have been started by the authenticated user. Information about a running process can be viewed by opening this specific process.

Start processes

The start processes section lists all the process definitions that can be started by the user currently authenticated. Choosing the start action will create a new instance of the process.

Selecting the magnifying glass displayed next to the tasks section opens the search task screen. This screen allows searching for currently active and completed tasks. A list of search rules can be defined to perform the desired search.

Once a search has been completed, the search result will be displayed in a table. The defined search query can be bookmarked by selecting the bookmark icon. After defining a name for the search, a new menu item with the specified name will be added, allowing performing the same search again quickly.

The search results can be exported to a CSV, XLS or PDF file.

Note that it is possible to choose which columns are displayed in the search results. Only the selected columns will be exported.

nevisWorkflow provides the same functionality for the process search as for the task search (for a description of the task search, see the chapter Task Search.

Preferences

The preference screen is reached by selecting the link in the dropdown menu appearing on the username in the top right corner of the application. In that screen the authenticated user can subscribe for notification. The following types of notifications are available:

  • Process completed
  • Process cancelled
  • Task completed
  • Task assigned
  • Daily summary notification about processes

The meaning and further details about notifications can be found in the section Notifications.

Deployment administration

This section is only available if the authenticated user has the administration role for nevisWorkflow .

This screen allows managing the deployed workflows. Actions such as enable and disable specific workflows of a deployment can be performed.

For disabling workflows the following requirement has to be met: No instance of the worklow could be running.