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
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
- 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:
- 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 name | Description |
---|---|
db.oracle.tablespace.data | The tablespace data of the oracle database. |
db.oracle.tablespace.index | The tablespace index of the oracle database. |
db.role.adm.username | The role of the admin user. |
db.role.app.username | The role of the application user. |
db.user.adm_username | The admin username. |
db.user.app_username | The application user's username. |
- 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 chapter neviswf.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.
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 userOn 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.pemCopy the technicalAdmin CSR to the nevisIDM server.
Sign the CSR for the technicalAdmin.
neviskeybox sign -ca myCA -out /tmp/technicalAdmin_signed.pem -file
/tmp/technicalAdmin_request.pem -certtype userImport 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.pemCopy the signed certificate back to the nevisWorkflow server.
Import signed cert into the nevisWorkflow keystore.
neviskeybox import -slot default -label technicaladmin -file
/tmp/technicalAdmin_signed.pemImport the nevisIDM node certificate or the certificate of the CA that signed the nevisIDM node certificate to the nevisWorkflow truststore.
Import the CA that signed the technicalAdmin CSR (nevisIDM local CA in this case, see point 4) into nevisWorkflow truststore.
infoAlso 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:
- http://forums.activiti.org/content/important-activiti-515-and-mysql-56-users
- http://activiti.org/userguide/index.html#creatingDatabaseTable
nevisWorkflow's own database table upgrades are compatible with MySQL below and above version 5.6.
With automatic DB 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, aneviswf-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
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:
- upgradestep.513.to.515.engine.sql
- upgradestep.513.to.515.history.sql
- 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 inACT_GE_PROPERTY
table. For versions prior to1.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).
- The
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.
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 and Activiti Engine 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 name | Description |
---|---|
group.entity.factory.class | Mandatory. Defines 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.class | Mandatory. Defines 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.class | Mandatory. Defines 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.configurators | A 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 name | Description |
---|---|
ws.adminservice.endpoint | Mandatory. Comma-separated list of endpoint URIs of the nevisIDM admin service used. |
ws.adminservice.wsdl.resource | WSDL resource of the nevisIDM admin service. Default: /wsdl/nevisidm_adminservice_v1.wsdl . |
ws.adminservice.class | Class used as nevisIDM admin service client. Default: ch.adnovum.nevisidm.ws.services.v1.AdminServiceV1 . |
ws.adminservice.request.timeout | Request timeout when communicating with the nevisIDM admin service. Default: 120000 . |
ws.adminservice.connect.timeout | TCP connection timeout when establishing the connection to the nevisIDM admin service. Default: 15000 . |
ws.adminservice.token.encoding | Forwarded SecToken encoding options Possible values: automatic or 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 , for example: UTF-8 : Converts basic auth header bytes as encoding then converts to Base64. |
nevisidm.cache.enabled | Enables caching of nevisIDM results. Used to optimize the performance and reduce the load on nevisIDM. Default: true . |
nevisidm.cache.maxentries | Number of entries stored in the nevisIDM result cache. This number should correspond to the expected number of simultaneous users. Default: 100 . |
nevisidm.cache.ttl | Lifetime of an entry in the nevisIDM result cache in milliseconds. Default: 60000 . |
ws.adminservice.loadbalancing | Enable round-robin load balancing between endpoints, when more endpoints are defined. Default: false. |
ws.adminservice.clientcert.endpoint | Comma-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.keystore | Path 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.password | Password for JKS file defined in ws.adminservice.clientcert.keystore Default: empty. |
ws.adminservice.clientcert.alias | Alias of the certificate in javax.net.ssl.keyStore used by technical user to connect ws.adminservice.clientcert.endpoint. |
ws.selfadminservice.endpoint | Comma-separated list of endpoint URIs of the nevisIDM self admin service used. |
ws.selfadminservice.wsdl.resource | WSDL resource of the nevisIDM self admin service. Default: /wsdl/nevisidm_adminservice_v1.wsdl . |
ws.selfadminservice.class | Class 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 name | Description |
---|---|
mail.smtp.host | Mandatory. SMTP server host used to send e-mail notifications and used by e-mail tasks. |
mail.smtp.port | Mandatory. SMTP server port used to send e-mail notifications and used by e-mail tasks. |
mail.sender.address | Mandatory. Sender address used in e-mail notifications. |
mail.server.username | User name for the mail server used to send notifications by the application.See Activiti documentation. |
mail.server.password | Password for the mail server used to send notifications by the application. See Activiti documentation. |
mail.server.ssl | If true, server side ssl encryption is allowed. Default is false. See Activiti documentation. |
mail.server.tls | If true, server side tls encryption is allowed. Default is false. See Activiti documentation. |
mail.server.session.jndi | JNDI name of javax.mail.Session in "java:comp/env". See Activiti documentation. |
nevisWorkflow
The following table lists the parameters related to nevisWorkflow.
Parameter name | Description |
---|---|
daily.summary.schedule | Mandatory. Schedule 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 here. Example: 0 0 7 * * ? means every day at 7 o'clock. |
show.variables | If true, the variables tab is shown on the task/process details screen. Default: true |
variable.edit | If true, the variables are editable on the variables tab. Default: false |
show.comments | If true, the comments tab is shown on the task/process details screen. Default: true |
show.attachments | If true, the attachments tab is shown on the task/process details screen. Default: true |
neviswf.external.resource.folder | Absolute path of root folder of additional resource files (css, js, images). This folder must have read rights to the web server. |
neviswf.external.css | If defined, this file serves as default css file. The path to this file is relative to neviswf.external.resource.folder. |
neviswf.external.logo | If 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.enabled | If 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 name | Description |
---|---|
identityservice.use.sectoken.info | If 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.loginid | SecToken attribute name holding the user's login id. Default: loginId. |
nevis.sectoken.attr.profileid | SecToken attribute name holding the user's profile id. Default: profileId. |
nevis.sectoken.attr.clientid | SecToken attribute name defining the user's nevisIDM client external id. Default: clientId. |
nevis.sectoken.attr.firstName | SecToken attribute name holding the user's first name. Default: firstName. |
nevis.sectoken.attr.lastName | SecToken attribute name holding the user's last name. Default: lastName. |
nevis.sectoken.attr.country | SecToken attribute name holding the user's country. Default: country. |
nevis.sectoken.attr.language | SecToken attribute name holding the user's language. Default: language. |
REST interface
The following table lists the parameters related to the REST interface.
Parameter name | Description |
---|---|
rest.enabled | Enables or disables REST service. Default: false. |
rest.clientip.auth.enabled | Enables/disables IP-based authorization. Default: false. |
rest.clientip.auth.whitelist | Defines a comma-separated whitelist for client-based authorization. Default: 127.0.0.1. |
neviswf.rest.response.hide.domain.name | Hides the domain name in response JSON message. Default: false. |
neviswf.job.executor.activate | Deactivates 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 category | Description |
---|---|
org.activiti | By default set to INFO. This tracegroup allows enabling tracing of the Activiti framework. |
ch.adnovum | By default disabled. This tracegroup allows enabling tracing of nevisWorkflow core code. |
ch.nevis | By default disabled. This tracegroup allows enabling tracing of Nevis subcomponent such as Ninja. |
http.request | By default disabled. Allows debugging of HTTP requests. |
http.response | By default disabled. Allows debugging of HTTP responses. |
http.body | By default disabled. Allows debugging of HTTP requests body. |
http.session | By default disabled. Allows debugging of HTTP sessions. |
http.time | By default disabled. Allows debugging of HTTP timings. |
jcan.Op | By default set to INFO. It will trace information about SOAP method invocations. |
jcan.OpContent | By 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.activiti | By 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 name | Description |
---|---|
db.properties | Defines 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.conf | Defines adnglassfish installation parameters. This file only has effect on installation. |
login.conf | Ninja login configuration file for JAAS authentication. |
login-dev.conf | Ninja developer mode login configuration file for JAAS authentication. |
vmargs.conf | Adding 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.xml | Logback configuration file to configure application logging. |
<database>_datasource.xml | GlassFish specific database resource file. This file is updated, when the db.properties file is changed. 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.xml | Same 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.properties | Configuration 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
Operation and Administration - Embedded container deployment
From version 1.11.0.0 on, nevisWorkflow can be deployed in the following ways:
Deployment Type | Remarks | State |
---|---|---|
Wildfly | nevisWorkflow deployed as a web application. | Stable |
GlassFish | nevisWorkflow deployed as a web application. | Stable |
Standalone | nevisWorkflow 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 file | Remarks |
---|---|
env.conf | Administration 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.conf | JVM command-line options: 1. Heap size; 2. Garbage collector; 3. System properties configuration |
neviswf.properties | Application, login, server configuration: 1. Application configuration options (connection to IDM, notification e-mail, nevisWF); 2. Ninja authentication module configuration options; 3. Scaling (concurrency with worker threads); 4. Network settings (host, port, protocol, TLS, ...). |
logback.xml | Logging configuration: 1. Configuration of log levels for individual components; 2. 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:
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 section.
server.name
- Example:
<instance>
- Name of the server. Give each server a unique name, for the sake of identification. This name will also be logged.
server.protocol
- Example:
https
- Default:
https
- Enumeration: https, http(info) Set this property to "https" if you would like to use TLS.
server.port
- Example:
8991
- Default:
8991
- Configures the port where the server will listen for incoming authentication requests.
server.host
- Example:
localhost
- Configures the hostname on which the server will listen for incoming authentication requests.
server.tls.keystore
- Example:
/var/opt/keybox/default/node_keystore.jks
- Keystore object used for the TLS.
server.tls.keystore-passphrase
- Example:
keystorepassword
server.tls.truststore
- Example:
/var/opt/keybox/default/truststore.jks
- Truststore object used for the TLS.
server.tls.truststore-passphrase
- Example:
truststorepassword
server.tls.require-client-auth
- Example:
true
- Default:
false
- Controls if client authentication is required for the TLS connection.- "false" = one-way TLS connection- "true" = two-way TLS connection
server.tls.supported-protocols
- Example:
TLSv1.2
- Default:
TLSv1, TLSv1.1, TLSv1.2
- Provides a list of protocols that are accepted by the client when trying to initiate a connection with TLS.
server.tls.cipher-suites
- Example:
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
- Default:
TLS_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_SCSV
- Provides a list of ciphers that are accepted by the client when trying to initiate a connection with TLS.
server.max-threads
- Example:
200
- Default:
200
- Number 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:
Syntax | Example | Remarks |
---|---|---|
${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 argument | Remarks | Default |
---|---|---|
-c, --config PATH | Required. Path to the configuration file neviswf.properties. | No default. |
-n, --name NAME | Unique 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 PORT | The 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 HOST | The 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 PATH | Log 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, --version | Display version and exit with status code 0. | |
-h, --help | Shows 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.
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:
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:
- The package defaults
- The provided property file
- 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:
- ws.adminservice.endpoint: The 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:
Parameter | Default | Description |
---|---|---|
-Djavax.net.ssl.trustStore | /var/opt/neviskeybox/default/default/truststore.jks | Truststore used to validate client certificates. |
-Djavax.net.ssl.keyStore | /var/opt/neviskeybox/default/default/node_keystore.jks | Keystore used to identify the server (sent to client on SSL/TLS client hello). |
-Djavax.net.ssl.trustStorePassword | Passphrase to access the server truststore. | |
-Djavax.net.ssl.keyStorePassword | Passphrase to access the server keystore. | |
-Djboss.socket.binding.port-offset=8884 | The 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>
Operation and Administration - 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
- 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
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 type | Oracle data type | MySQL data type |
---|---|---|
long | number(19,0) | bigint |
integer | number(10,0) | integer |
short | number(5,0) | smallint |
string | varchar2 | varchar, text |
date | date | datetime |
boolean | number(1,0) | bit |
Database table TNWFC_SEARCHES
Stores bookmarked searches.
DB field name of attribute | Java data type (max. size) Defaults | Description |
---|---|---|
search_id | Long, not NULL | Primary key |
user_id | String (64), not NULL | Id of the user |
search_type | String (64), not NULL | Type of search (process, task, …) |
search_name | String (255), not NULL | Name defined for the search |
search_parameters | String (4000), not NULL | Parameters 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 attribute | Java data type (max. size) Defaults | Description |
---|---|---|
subscription_id | Long, not NULL | Primary key |
process_definition_id | String (64) | Process definition ID |
process_instance_id | String (64) | Process instance ID |
task_name | String (255) | Name of the task |
task_id | String (64) | ID of the task |
notification_type | String (64), not NULL | Type of notification |
user_id | String (64), not NULL | ID of the user subscribed |
user_firstname | String (255), not NULL | First name of the user subscribed |
user_lastname | String (255), not NULL | Last name of the user subscribed |
user_locale | String (2) | Locale code of user's language |
notification_channels | String (255), not NULL | Type of notification used |
Database table TNWFC_TEMPLATES
Notification e-mail templates.
DB field name of attribute | Java data type (max. size) Defaults | Description |
---|---|---|
template_id | Long, not NULL | Primary key |
type | String (64), not NULL | Type of template |
subject | String (255), not NULL | Subject of the template (used as e-mail subject for example for e-mail templates) |
body | String (4000), not NULL | Content of the template |
language_code | String (2), not NULL | Language 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 attribute | Java data type (max. size) Defaults | Description |
---|---|---|
permission_id | Long, not NULL | Primary key |
process_definition_id | String (64) | Process definition this permission is applied to |
task_name | String (64) | Task name this permission is applied to |
is_assignee | Boolean | Whether or not the permission is applied to the assignee of task_name |
is_process_starter | Boolean | Whether or not the permission is applied to the process starter |
operation | String (32) | Id of the operation |
granularity | String (32) | Granularity includes: Process level Task level * Variable level |
permission | Boolean, not NULL | True: permitted False: Prohibited |
Database table TNWFC_PROC_PERM_GROUP
Holds information about which groups are assigned a process permission.
DB field name of attribute | Java data type (max. size) Defaults | Description |
---|---|---|
group_id | String (64), not NULL | Primary key |
permission_id | Long, not NULL | Primary key |
Database table TNWFC_PROC_PERM_USER
Holds information about which users are assigned a process permission.
DB field name of attribute | Java data type (max. size) Defaults | Description |
---|---|---|
user_id | String (64), not NULL | Primary key |
permission_id | Long, not NULL | Primary 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 attribute | Java data type (max. size) Defaults | Description |
---|---|---|
variable_name | String (64), not NULL | Primary key |
permission_id | Long, not NULL | Primary key |
Database table TNWFC_PROPERTY
Used for holding configuration properties for workflows, e.g., URLs of remote services.
DB field name of attribute | Java data type (max. size) Defaults | Description |
---|---|---|
property_id | Long, not NULL | Primary key |
environment | String (64) | Deployment environment, e.g.,: prod, test, dev, inst1, inst2, inst3 |
family | String (64), not NULL | Grouping identifier, e.g.,:neviswf, workflow1, workflow2 |
key | String (64), not NULL | Name of the property |
value | String (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 attribute | Java data type (max. size) Defaults | Description |
---|---|---|
ctl_tcn | Integer, not NULL | Counter used for optimistic locking. |
ctl_cre_uid | String(110), not NULL | LoginID of the user who created the entry. |
ctl_cre_date | Date, not NULL | Creation date. |
ctl_mod_uid | String(110), not NULL | LoginID of the user who last modified the entry. |
ctl_mod_dat | Date, not NULL | Date 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.
Developer Guide - 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 (note: this can be fine-tuned using the priority of scopes described in section "Priority of scopes").
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.
<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
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 ACT_RU_VARIABLE_
table TEXT
field, for example, user1, user2, user3
.
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
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.
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.
Whenever a new authorization is added, all of the attributes must be defined.
The authorization definition syntax is written as follows (explanations in red):
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.
<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):
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
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.
<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 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.
The process starter receives permission to claim the task; otherwise the white-listing approach would prohibit everyone from claiming the task.
<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.
Dlegation is prohibited due to white-listing; the Delegate button will be disabled.
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.
<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 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.
<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:
Neither can nwf.hu.user:
Combined authorization example 1
The group nevisWF.Admin receives authorization for all operations via candidateStarterGroups. Everyone else is denied by the authorization tag.
<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 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.
<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 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.
<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:
The user nwf.hu.user can start the process and add comments to it:
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.
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:
- 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.
- The
<extensionElements>
tag has to be the first tag on the process and on the task. - Each process and task needs its own
<extensionElements>
tag. - Each
<extensionElements>
tag has to be closed with</extensionElements>
after all the authorization tags are specified for the given process or task. - Attributes cannot be missing from the tags, each authorization tag must contain:
- A scope
- An operation
- A permission
- 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.
Developer Guide - 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
Create a new attachment on a task, containing a link to an external resource
See the original service description here.
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 here.
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 here.
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
GET /runtime/tasks/{taskId}/authorizations?operation={operation}
Parameter | Value | Description |
---|---|---|
taskId | String | Required. The ID of the task for which to get the authorizations. |
operation | String | Only returns authorizations with the given 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": "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
}
]
}
{
"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
}
]
}
{
"message": "Bad request",
"exception": "Not supported Task operation 'INVALID_OPERATION' ."
}
Response code | Description |
---|---|
200 | Indicates the task was found and returned with its authorizations. |
404 | Indicates the requested task was not found. |
400 | Indicates the operation is not a valid one. |
Get authorizations of a historic task
GET /history/tasks/{taskId}/authorizations?operation={operation}
Parameter | Value | Description |
---|---|---|
taskId | String | Required. The ID of the historic task for which to get the authorizations. |
operation | String | Only returns authorizations with the given 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": "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
}
]
}
{
"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
}
]
}
{
"message": "Bad request",
"exception": "Not supported Task operation 'INVALID_OPERATION' ."
}
Response code | Description |
---|---|
200 | Indicates the historic task was found and returned with its authorizations. |
404 | Indicates the requested historic task was not found. |
400 | Indicates the operation is not a valid one. |
Get authorizations of a process instance
GET /runtime/process-instances/{processInstanceId}/authorizations?operation={operation}
Parameter | Value | Description |
---|---|---|
processInstanceId | String | Required. The ID of the process instance for which to get the authorizations. |
operation | String | Only returns authorizations with the given 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": "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
}
]
}
{
"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
}
]
}
{
"message": "Bad request",
"exception": "Not supported Process operation 'INVALID_OPERATION' ."
}
Response code | Description |
---|---|
200 | Indicates the process instance was found and returned with its authorizations. |
404 | Indicates the requested process instance was not found. |
400 | Indicates the operation is not a valid one. |
Get authorizations of a historic process instance
GET /history/process-instances/{processInstanceId}/authorizations?operation={operation}
Parameter | Value | Description |
---|---|---|
processInstanceId | String | Required. The ID of the historic process instance for which to get the authorizations. |
operation | String | Only returns authorizations with the given 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": "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
}
]
}
{
"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
}
]
}
{
"message": "Bad request",
"exception": "Not supported Process operation 'INVALID_OPERATION' ."
}
Response code | Description |
---|---|
200 | Indicates the task was found and returned with its authorizations. |
404 | Indicates the requested task was not found. |
400 | Indicates the operation is not a valid one. |
REST services provided by nevisWorkflow - Authorization operation enforceability
Task authorization operation enforceability
GET /runtime/tasks/{taskId}/authorization-operation/{operation}
Parameter | Value | Description |
---|---|---|
taskId | String | Required. The ID of the task to get the authorization for. |
operation | String | Only returns authorizations with the given operation. |
{
"operation": "CLAIM_TASK",
"allowed": true
}
{
"operation": "CLAIM_TASK",
"allowed": false
}
Response code | Description |
---|---|
200 | Indicates the task was found and returned with the corresponding response. |
404 | Indicates the requested task was not found. |
400 | Indicates the operation is not a valid one. |
Historic task authorization operation enforceability
GET /history/tasks/{taskId}/authorization-operation/{operation}
Parameter | Value | Description |
---|---|---|
taskId | String | Required. The ID of the historic process instance for which to get the authorizations. |
operation | String | Only returns authorizations with the given operation. |
Parameter | Value | Description |
---|---|---|
taskId | String | Required. The ID of the historic process instance for which to get the authorizations. |
operation | String | Only returns authorizations with the given operation. |
{
"operation": "CLAIM_TASK",
"allowed": true
}
{
"operation": "CLAIM_TASK",
"allowed": false
}
Response code | Description |
---|---|
200 | Indicates the historic task was found and returned with the corresponding response. |
404 | Indicates the requested historic task was not found. |
400 | Indicates the operation is not a valid one. |
Process instance authorization operation enforceability
GET /runtime/process-instances/{processInstanceId}/authorization-operation/{operation}
Parameter | Value | Description |
---|---|---|
processInstanceId | String | Required. The ID of the process instance for which to get the authorizations. |
operation | String | Only returns authorizations with the given operation. |
{
"operation": "SUSPEND_PROCESS",
"allowed": true
}
{
"operation": "SUSPEND_PROCESS",
"allowed": false
}
Response code | Description |
---|---|
200 | Indicates the process instance was found and returned with the corresponding response. |
404 | Indicates the requested process instance was not found. |
400 | Indicates the operation is not a valid one. |
Historic process instance authorization operation enforceability
GET /history/process-instances/{processInstanceId}/authorization-operation/{operation}
Parameter | Value | Description |
---|---|---|
processInstanceId | String | Required. The ID of the historic process instance for which to get the authorizations. |
operation | String | Only returns authorizations with the given operation. |
{
"operation": "SUSPEND_PROCESS",
"allowed": true
}
{
"operation": "SUSPEND_PROCESS",
"allowed": false
}
Response code | Description |
---|---|
200 | Indicates the historic process instance was found and returned with the corresponding response. |
404 | Indicates the requested historic process instance was not found. |
400 | Indicates the operation is not a valid one. |
REST services provided by nevisWorkflow - General services
Create a new attachment on a process instance, containing a link to an external resource
POST/runtime/process-instances/{processInstanceId}/attachments
Parameter | Value | Description |
---|---|---|
processInstanceId | String | Required. The ID of the process instance for which to create the attachment. |
{
"name":"Simple attachment",
"description":"Simple attachment description",
"type":"simpleType",
"externalUrl":"http://activiti.org"
}
Only the attachment name is required to create a new attachment.
{
"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 code | Description |
---|---|
201 | Indicates the attachment was created and the result is returned. |
400 | Indicates the attachment name is missing from the request. |
404 | Indicates the requested process instance was not found. |
Create a new attachment on a process instance, with an attached file
POST/runtime/process-instances/{processInstanceId}/attachments
Parameter | Value | Description |
---|---|---|
processInstanceId | String | Required. The 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.
{
"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 code | Description |
---|---|
201 | Indicates the attachment was created and the result is returned. |
400 | Indicates the attachment name is missing from the request or no file was present in the request. The error message contains additional information. |
404 | Indicates the requested process instance was not found. |
Get all attachments on a process instance
GET/runtime/process-instances/{processInstanceId}/attachments
Parameter | Value | Description |
---|---|---|
processInstanceId | String | Required. The ID of the process instance for which to create the attachment. |
[
{
"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 code | Description |
---|---|
200 | Indicates the process instance was found and the attachments are returned. |
404 | Indicates the requested process instance was not found. |
Developer Guide - 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.
Task Search
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.
It is possible to choose which columns are displayed in the search results. Only the selected columns will be exported.
Process Search
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 (see also the section: "Accessing nevisWorkflow authorizations" for more details).
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.