OpenIDM 2.1 Integration Guide

Contents

  1. Architectural Overview
    1. Modular Framework
    2. Infrastructure Modules
    3. Core Services
      1. Object model
      2. Managed objects
      3. System Objects
      4. Mappings
      5. Synchronization and Reconciliation
    4. Access Layer
  2. Configuration Options
    1. Configuration Objects
      1. Single Instance Configuration Objects
      2. Multiple Instance Configuration Objects
    2. Configuration Over REST
    3. Property Substitution in Configuration
  3. Configure Server Logs
  4. Connect to External Resources
    1. Accessing Remote Connectors
    2. Configure Connectors
    3. Connector Configuration Examples
  5. Configuring Synchronization
    1. Types of Synchronization
      1. Reconciliation
      2. LiveSync
    2. Flexible Data Model
    3. Basic Data Flow Configuration
      1. Connector Configuration Files
      2. Synchronization Mappings File
  6. Scheduling Synchronization
  7. Managing Passwords
    1. Enforcing Password Policies
    2. Password Synchronization
  8. Managing Authentication, Authorization & RBAC
    1. OpenIDM Users
      1. Internal Users
      2. Managed Users
  9. Authentication
    1. Default Attributes
    2. Authentication
    3. Roles
    4. Authorization
  10. Securing & Hardening OpenIDM
  11. Integrating Business Processes & Workflows
    1. Remote Integration
      1. Checkout Trunk
      2. Compile and Package Source Codes
      3. Install OpenIDM
      4. Install Activiti
      5. Deploy OpenIDM Workflow to Activiti Tomcat
      6. Configure OpenIDM to use Remote Activiti
      7. Install the sample workflow (example.bpmn20.xml) from the openidm-workflow-activiti project
    2. Local Activiti Integration
    3. Configure Activiti Engine
    4. Define Activiti Workflows
    5. Invoking Activiti Workflows
    6. Email Notification Example
    7. Example Sunset Workflow Triggered By Reconciliation
  12. Sending Email
    1. Setup Outbound Email
    2. Send mail from REST
    3. Sending Mail from Script
  13. Errors
    1. action method not implemented on workflow
  14. References
 

Architectural Overview

Modular Framework

* OSGi (Felix)
* Servlet (Jetty)

Infrastructure Modules

* Scheduler (Quartz)
* Script engine (JavaScript)
* Audit logging
* Repository
– MySQL for production use
– OrientDB for evaluation use
– Repository API is based on JSON object model and RESTful Web Services

Core Services

Object model

* Java based object model
* Java object model represents of JSON object model
* Also exposes a set of triggers and functions for scripting hookups

Managed objects

* They are identity related data managed by OpenIDM
* Configurable, JSON based data structure living the repository
* Default configuration of a manged object is that of a user
* Can be access via /openidm/managed/ context

curl
  --header "X-OpenIDM-Username: openidm-admin"
  --header "X-OpenIDM-Password: openidm-admin"
  --request GET
  "http://localhost:8080/openidm/managed/..."

System Objects

* They are pluggable representations of objects on external systems, e.g. a user entry stored in external LDAP.
* Can be access via /openidm/system/ context

curl
  --header "X-OpenIDM-Username: openidm-admin"
  --header "X-OpenIDM-Password: openidm-admin"
  --request GET
  "http://localhost:8080/openidm/system/..."

Mappings

* Mappings define policies between source and target objects and their attributes during synchronization and reconciliation
* Can also define triggers for validation, customization, filtering, and transformation of source and target objects

Synchronization and Reconciliation

Access Layer

* Provides UI and public APIs (RESTful) for accessing and managing OpenIDM repository and its functions

Configuration Options

Configuration Objects

* Exposed as JSON objects
* Can be either single instance (one per installation) or multiple instances (more than one per installation)

Single Instance Configuration Objects

* audit: specifies how audit events are logged
* authentication: controls REST access
* managed: defines managed objects and their schemas
* repo.repo-type: configures internal repository, e.g. repo.orientdb or repo.jdbc
* router: specifies filters for specific operations
* sync: defines all sync and reconciliation mappings

Multiple Instance Configuration Objects

* Naming: objectname/instancename, e.g. provisioner.openicf/xml
* JSON file views are named: objectname-instancename.json, e.g. provisioner.openicf-xml.json

Configuration Over REST

* Configuration objects are exposed under /openidm/config context
* Single instance objects are under /openidm/config/objectname context
* Multiple instance objects are under /openidm/config/objectname/instancename context

# List all configuration objects:
curl --request GET \
 --header "X-OpenIDM-Username: openidm-admin" \
 --header "X-OpenIDM-Password: openidm-admin" http://localhost:8080/openidm/config
 
# List single instance audit configuration object:
curl \
 --header "X-OpenIDM-Username: openidm-admin" \
 --header "X-OpenIDM-Password: openidm-admin" http://localhost:8080/openidm/config/audit
 
# List multiple instance configuration object:
curl \
 --header "X-OpenIDM-Username: openidm-admin" \
 --header "X-OpenIDM-Password: openidm-admin" http://localhost:8080/openidm/config/provisioner.openicf/xml

Property Substitution in Configuration

* Define properties in conf/boot.properties. For example:

PROD.location=production
DEV.location=development

* Use Property in configuration files with &{} construct. For example, repo.orientdb.json:

{
"dbUrl" : "local:./db/&{&{environment}.location}-openidm",
"user" : "admin",
"poolMinSize" : 5,
"poolMaxSize" : 20,
...
}

* Property “environment” is further defined in environment variables:

# For DEV environment:
export OPENIDM_OPTS="-Xmx1024m -Denvironment=PROD"
./startup.sh
 
# For PROD environment:
export OPENIDM_OPTS="-Xmx1024m -Denvironment=DEV"
./startup.sh

* Java system properties can also be used. For example:

{
    "logTo" : [
        {
            "logType" : "csv",
            "location" : "&{user.home}/audit",
            "recordDelimiter" : ";"
        }
    ]
}

* Also supports nested properties
* Does not support encrypted values at this time

Configure Server Logs

* Server logging can be configured in openidm/conf/logging.properties
* Logging levels

SEVERE
WARNING
INFO
CONFIG
FINE
FINER
FINEST

* Set logging level in individual script:

org.forgerock.openidm.script.javascript.JavaScript.level=level

* Override log level defined in individual script:

org.forgerock.openidm.script.javascript.JavaScript.script-name.level=level

Connect to External Resources

* Resources are
– external systems
– databases
– directory servers
– other sources of identity data
to be managed and audited by an idM
* OpenIDM connects to external resources through OpenICF which can be either standalone or embedded
* Connectors are configured through files named openidm/conf/provisioner.openicf-connectorname
* Sample connectors are located in openidm/samples/provisioners directory (copy them to conf directory to use)

Accessing Remote Connectors

* Configure remote connectors in conf/provisioner.openicf.connectorinfoprovider.json
* See sample file in conf/provisioner directory

cat provisioner.openicf.connectorinfoprovider.jsn 
{
   "connectorsLocation" : "connectors",
   "remoteConnectorServers" :
      [
         {
            "name" : "dotnet",
            "host" : "127.0.0.1",
            "port" : 8759,
            "useSSL" : false,
            "timeout" : 0,
            "key" : "Passw0rd"
         }
      ]
}

Configure Connectors

* Via OpenICF provisioner service
* Each connector configuration is stored in a file in the conf directory named provisioner.openicf-connectorname

Connector Configuration Examples

Configuring Synchronization

Types of Synchronization

* Synchronization happens when
– OpenIDM receives a change directly: OpenIDM pushes changes immediately to all external resources
– OpenIDM discovers a change on an external resource: through reconciliation and LiveSync

Reconciliation

* Bidirectional synchronization of objects (mainly user objects) between different data stores
* Thorough and heavy weight
* Good for compliance and reports

LiveSync

* Relies on change log on the external resource (e.g. OpenDJ and AD) to determine which object has changed
* Light weight
* Might miss some changes

Flexible Data Model

Basic Data Flow Configuration

* Elements involved:
– Three types of configuration files
– A link table that OpenIDM maintains in its repository
– Scripts to check objects and manipulate attributes

Connector Configuration Files

* Maps external resource objects to OpenIDM objects
* Lives in conf directory
* Naming convention is provisioner.resource-name.json, e.g. provisioner.openicf-xml.json
* Mapping naming conventions:
nativeName: external attribute name
nativeType: external attribute type

{
    "name": "MyLDAP",
    "objectTypes": {
        "account": {
            "lastName": {
                "type": "string",
                "required": true,
                "nativeName": "sn",
                "nativeType": "string"
            },
            "homePhone": {
                "type": "array",
                "items": {
                    "type": "string",
                    "nativeType": "string"
                },
                "nativeName": "homePhone",
                "nativeType": "string"
            }
        }
    }
}

Synchronization Mappings File

* Single file: conf/sync.json
* Describes a set of mappings
– Each mapping specifies attribute mapping from source to target objects (i.e. directional from source to target)
– External objects are identified as system/name/object-type
* By default, synchronize all objects matching those defined in the connector config file for the resource
* Can also do
– creating new attribute
– conditional sync
– transformation

{
    "mappings": [
        {
            "name": "systemLdapAccounts_managedUser",
            "source": "system/MyLDAP/account",
            "target": "managed/user",
            "properties": [
                {
                    "target": "familyName",
                    "source": "lastName"
                },
                {
                    "target": "homePhone",
                    "source": "homePhone"
                },
                /* Creates a new attribute on the target name phoneExtension with default value of 0047 */
                {
                    "target": "phoneExtension",
                    "default": "0047"
                },
                /* Sync conditionally (only if source email is not null) */
                {
                    "target": "mail",
                    "comment": "Set mail if non-empty.",
                    "source": "email",
                    "condition": {
                        "type": "text/javascript",
                        "source": "(source.email != null)"
                    }
                },
                /* Create a new target attribute named displayName */
                {
                    "target": "displayName",
                    "source": "";
                    "transform": {
                        "type": "text/javascript",
                        "source": "(source.lastName +', ' + source.firstName;)"
                    }
                }
            ]
        }
    ]
}

* Filters to determine if source of target is valid to be mapped
– validSource

{
    "validSource": {
        "type": "text/javascript",
        "source": "source.ldapPassword != null"
    }
}

– validTarget

{
    "validTarget": {
        "type": "text/javascript",
        "source": "target.employeeType == 'internal'"
    }
}

Scheduling Synchronization

Managing Passwords

Enforcing Password Policies

* By applying validation rules to attributes of managed user objects
* For example, to exclude the use of password strings: ‘password’,’123456′,’12345678′, ‘qwerty’, ‘abc123’:
– In conf/managed.json file:

{
    "objects" : [
        {
            "name" : "user",
            "properties" : [
                {
                    "name" : "password",
                    "encryption" : {
                        "key" : "openidm-sym-default"
                    }
                }
            ],
            "onValidate" : {
                "type" : "text/javascript",
                "file" : "script/password-validator.js"
            }
        }
    ]
}

– Password validation file (script/password-validator.js)

const dictionary = ['password','123456','12345678', 'qwerty', 'abc123'];
 
function isValidPassword() {
    var cleartextObject = openidm.decrypt(object);
    for (var i = 0; i < dictionary.length; i++) {
        if (cleartextObject.password == dictionary[i]) {
            throw "Password Policy Violation Exception";
        };
    };
};
 
isValidPassword();

Password Synchronization

Managing Authentication, Authorization & RBAC

OpenIDM Users

Internal Users

* anonymous: for self registration. Default password is anonymous
* openidm-admin: super user. Default password is openidm-admin

Managed Users

* Users managed by OpenIDM

Authentication

Default Attributes

* login: email
* password: password
* Default attributes are defined in conf/repo.repotype.json file, e.g. repo.orientdb.json
– credential-internaluser-query
– credential-query

        "credential-query" : "SELECT * FROM ${_resource} WHERE userName = '${username}'",
        "credential-internaluser-query" : "SELECT * FROM internal_user WHERE _openidm_id = ${username}",

* Authentication file conf/authentication.json defines currently active query

cat authentication.json 
{
    "queryId" : "credential-query",
    "queryOnResource" : "managed/user",
    "propertyMapping" : {
        "userId" : "_id",
        "userCredential" : "password",
        "userRoles" : "roles"
    },
    "defaultUserRoles" : [ ]
}

Authentication

* With standard header fields:

curl --user userName:password

* With OpenIDM header fields:

curl
 --header "X-OpenIDM-Username: openidm-admin"
 --header "X-OpenIDM-Password: openidm-admin"

Roles

* openidm-reg: anonymous user
* openidm-admin: super user
* openidm-authorized: authenticated users.
– Configured by defaultUserRoles property in the conf/authentication.json file:

cat authentication.json 
{
    "queryId" : "credential-query",
    "queryOnResource" : "managed/user",
    "propertyMapping" : {
        "userId" : "_id",
        "userCredential" : "password",
        "userRoles" : "roles"
    },
    "defaultUserRoles" : [ ]
}

* openidm-cert: authenticated by mutual SSL authentication

Authorization

* Based on REST interface URLs
* Defined in script/router-authz.js file
– Return “Access denied” to deny access:

if (!allow()) {
    throw "Access denied";
}

Securing & Hardening OpenIDM

TODO

Integrating Business Processes & Workflows

* Two modes of integration
– Local integration: Activiti is embedded in OpenIDM OSGI container
– Remote integration: Standalone Activiti engine

Remote Integration

Checkout Trunk

* Checkout OpenIDM trunk from SVN URL: https://svn.forgerock.org/openidm/trunk

Compile and Package Source Codes

* Install Maven 3 if not already done
* Run Maven command:

mvn package

Install OpenIDM

* Copy openidm-zip/target/openidm-2.1.0-SNAPSHOT to target machine
* Unzip

Install Activiti

* Download and unzip activiti-5.10.zip
* Change Activiti listening port from 8080 to 9090
– Edit setup/build.xml and do a global replacement of 8080 to 9090 with vi command: :%s/8080/9090/g
* Start Activiti demo app:

ant demo.start

* Access Activiti Explorer from URL: http://localhost:9090/activiti-explorer

Deploy OpenIDM Workflow to Activiti Tomcat

* Stop Tomcat

ant tomcat.stop

* Deploy openidm-workflow-remote web app to Tomcat by copying openidm-workflow-remote/target/openidm-workflow-remote-2.1.0-SNAPSHOT.war to Tomcat webapps directory:

$ cd /opt/openidm/builtFromSrc/activiti-5.10/apps/apache-tomcat-6.0.32/webapps
$ pwd
/opt/openidm/builtFromSrc/activiti-5.10/apps/apache-tomcat-6.0.32/webapps
$ ls
activiti-explorer  activiti-rest  docs  examples  host-manager  manager  ROOT
$ cp /mnt/hgfs/vmshare/src/openidm-workflow-remote-2.1.0-SNAPSHOT.war .

* Deploy openidm workflow activiti jar file to activiti-explorer web app’s WEB-INF/lib directory

$ cd /opt/openidm/builtFromSrc/activiti-5.10/apps/apache-tomcat-6.0.32/webapps/activiti-explorer/WEB-INF/lib
$ pwd
/opt/openidm/builtFromSrc/activiti-5.10/apps/apache-tomcat-6.0.32/webapps/activiti-explorer/WEB-INF/lib
$ cp /mnt/hgfs/vmshare/src/openidm-workflow-activiti-2.1.0-SNAPSHOT-jar-with-dependencies.jar .

* Edit Activiti Explorer config file to be able to use OpenIDM extenstions

$ cd /opt/openidm/builtFromSrc/activiti-5.10/apps/apache-tomcat-6.0.32/webapps/activiti-explorer/WEB-INF
$ pwd
/opt/openidm/builtFromSrc/activiti-5.10/apps/apache-tomcat-6.0.32/webapps/activiti-explorer/WEB-INF
$ ls
activiti-ui-context.xml  applicationContext.xml  classes  lib  web.xml
$ vi applicationContext.xml

– Replace

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
 <property name="dataSource" ref="dataSource" />
 <property name="transactionManager" ref="transactionManager" />
 <property name="databaseSchemaUpdate" value="true" />
 <property name="jobExecutorActivate" value="true" />
 <property name="customFormTypes">
  <list>
   <ref bean="userFormType"/>
  </list>
 </property>
</bean>

with

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  <property name="mailServerHost" value="mail.my.com" /> 
  <property name="mailServerPort" value="26" />    
  <property name="mailServerUsername" value="me@my.com" /> 
  <property name="mailServerPassword" value="secret1" />    
  <property name="mailServerDefaultFrom" value="activiti@my.com" /> 
  <property name="dataSource" ref="dataSource" />
  <property name="transactionManager" ref="transactionManager" />
  <property name="databaseSchemaUpdate" value="true" />
  <property name="jobExecutorActivate" value="true" />
  <property name="customFormTypes">
  <list>
       <ref bean="userFormType"/>
      </list>
     </property>
  <property name="customSessionFactories">
  <list>
       <bean class="org.forgerock.openidm.workflow.activiti.impl.session.OpenIDMSessionFactory">
  <property name="url" value="http://localhost:8080/openidm/"/>
  <property name="user" value="openidm-admin"/>
  <property name="password" value="openidm-admin"/>
       </bean>
     </list>
   </property>
  <property name="resolverFactories">
  <list>
       <bean class="org.forgerock.openidm.workflow.activiti.impl.OpenIDMResolverFactory"></bean>
       <bean class="org.activiti.engine.impl.scripting.VariableScopeResolverFactory"></bean>
       <bean class="org.activiti.engine.impl.scripting.BeansResolverFactory"></bean>
     </list>
   </property>
  <property name="expressionManager">
     <bean class="org.forgerock.openidm.workflow.activiti.impl.OpenIDMExpressionManager"> </bean>
   </property>
</bean>

* Restart Activiti Demo:

cd $ACTIVITI_HOME/setup
ant demo.stop
ant demo.start

* Check that Activiti Explorer is accessible.

Configure OpenIDM to use Remote Activiti

* Copy sample workflow.json file to conf directory if none exists:

cd $OPENIDM_HOME
cp samples/misc/workflow.json conf/

* Edit workflow.json file to point to remote Activiti instance with correct username and password (i.e. kermit/kermit)

{
    "enabled" : true,
    "location" : "remote",
    "engine" : {
        "url" : "http://localhost:9090/openidm-workflow-remote-2.1.0-SNAPSHOT/",
        "username" : "kermit",
        "password" : "kermit"
    },

* Start OpenIDM

cd $OPENIDM_HOME
./startup.sh

* Test integration:

curl \
  --header "X-OpenIDM-Username: openidm-admin" \
  --header "X-OpenIDM-Password: openidm-admin" \
  --request GET "http://localhost:8080/openidm/workflow"
 
{"result":[{"name":"Vacation request","processDefinitionId":"vacationRequest:1:21","key":"vacationRequest"},{"name":"Helpdesk process","processDefinitionId":"escalationExample:1:22","key":"escalationExample"},{"name":"Review sales lead","processDefinitionId":"reviewSaledLead:1:23","key":"reviewSaledLead"},{"name":"Fix system failure","processDefinitionId":"fixSystemFailure:1:24","key":"fixSystemFailure"},{"name":"Expense process","processDefinitionId":"adhoc_Expense_process:1:25","key":"adhoc_Expense_process"}]}

Install the sample workflow (example.bpmn20.xml) from the openidm-workflow-activiti project

* Login remote Activiti Explorer as kermit/kermit
* Select Manage > Deployment > Upload New

* Browse to file openidm-workflow-activiti/src/main/resources/OSGI-INF/activiti/example.bpmn20.xml
* Start osgiProcess from REST API:

curl \
	--header "X-OpenIDM-Username: openidm-admin" \
	--header "X-OpenIDM-Password: openidm-admin" \
	--request POST "http://localhost:8080/openidm/workflow/processinstance?_action=createProcessInstance" \
	--data '{ "key":"osgiProcess" }'
 
{"_id":"1010","processInstanceId":"1010","status":"ended","businessKey":null,"processDefinitionId":"osgiProcess:1:915"}

– Also check Activiti Tomcat catalina.out for osgiProcess related outputs:

$ pwd
/opt/openidm/builtFromSrc/activiti-5.10/apps/apache-tomcat-6.0.32/logs
$ vi catalina.out	
 
script task using expression resolver: [result:[[name:Vacation request, processDefinitionId:vacationRequest:1:21, key:vacationRequest], [name:Helpdesk process, processDefinitionId:escalationExample:1:22, key:escalationExample], [name:Review sales lead, processDefinitionId:reviewSaledLead:1:23, key:reviewSaledLead], [name:Fix system failure, processDefinitionId:fixSystemFailure:1:24, key:fixSystemFailure], [name:Expense process, processDefinitionId:adhoc_Expense_process:1:25, key:adhoc_Expense_process], [name:Osgi process, processDefinitionId:osgiProcess:1:915, key:osgiProcess]]]

* Alternatively, start osgiProcess from Activiti Explorer:

– Check Activiti Tomcat catalina.out for osgiProcess related outputs:

Sep 18, 2012 1:07:26 PM org.restlet.engine.log.LogFilter afterHandle
INFO: 2012-09-18	13:07:26	127.0.0.1	kermit	127.0.0.1	9090	GET	/openidm-workflow-remote-2.1.0-SNAPSHOT/	-	200	-0	8	http://localhost:9090	Restlet-Framework/2.0.15	-
script task using expression resolver: [result:[[name:Vacation request, processDefinitionId:vacationRequest:1:21, key:vacationRequest], [name:Helpdesk process, processDefinitionId:escalationExample:1:22, key:escalationExample], [name:Review sales lead, processDefinitionId:reviewSaledLead:1:23, key:reviewSaledLead], [name:Fix system failure, processDefinitionId:fixSystemFailure:1:24, key:fixSystemFailure], [name:Expense process, processDefinitionId:adhoc_Expense_process:1:25, key:adhoc_Expense_process], [name:Osgi process, processDefinitionId:osgiProcess:1:915, key:osgiProcess]]]
Sep 18, 2012 1:07:26 PM org.restlet.engine.log.LogFilter afterHandle
INFO: 2012-09-18	13:07:26	127.0.0.1	kermit	127.0.0.1	9090	GET	/openidm-workflow-remote-2.1.0-SNAPSHOT/	-	200	-0	15	http://localhost:9090	Restlet-Framework/2.0.15	-
script task using resolver: [result:[[name:Vacation request, processDefinitionId:vacationRequest:1:21, key:vacationRequest], [name:Helpdesk process, processDefinitionId:escalationExample:1:22, key:escalationExample], [name:Review sales lead, processDefinitionId:reviewSaledLead:1:23, key:reviewSaledLead], [name:Fix system failure, processDefinitionId:fixSystemFailure:1:24, key:fixSystemFailure], [name:Expense process, processDefinitionId:adhoc_Expense_process:1:25, key:adhoc_Expense_process], [name:Osgi process, processDefinitionId:osgiProcess:1:915, key:osgiProcess]]]

Local Activiti Integration

* Local Activiti integration is included in the standard OpenIDM 2.1 build without Activiti Explorer.
* To access Activiti Explorer with Local Activiti Engine, see this post.
* To use Single User Store for both OpenIDM and Activiti, see this post.

Configure Activiti Engine

* Configured in conf/workflow.json file:
– For local embedded Activiti engine:

cat workflow.json 
{
    "enabled" : true
}

– For remote standalonoe Activiti instance:

{
    "enabled" : true,
    "location" : "remote",
    "engine" : {
        "url" : "http://localhost:9090/openidm-workflow-remote-2.1.0-SNAPSHOT/",
        "username" : "kermit",
        "password" : "kermit"
    },

Define Activiti Workflows

* Define BPMN 2.0 work flow file (with text editor or BPMN 2.0 editor)
* Package as a .bar file
* Copy bar file to workflow directory
* Invoke workflow using a script
* Optionally schedule workflow

Invoking Activiti Workflows

* From any trigger point within OpenIDM
* From script files using openidm.action() function

/*
 * Calling 'myWorkflow' workflow
 */
var workflow = {   
 "_action" : "myWorkflow"
};
 
var params = {
 "foo" : "bar"
};
 
openidm.action("workflow/activiti", workflow, params);

* Directly from REST interface

curl --header "X-OpenIDM-Username: openidm-admin" \
  --header "X-OpenIDM-Password: openidm-admin" \
  --data '{"foo":"bar"}' \
  --request POST "http://localhost:8080/openidm/workflow?_action=myWorkflow"

Email Notification Example

* Create EmailNotification.bpmn file
* Package as .bar file
* Copy .bar file to workflow directory
* Invoke directly from REST

curl \
	--header "X-OpenIDM-Username: openidm-admin" \
	--header "X-OpenIDM-Password: openidm-admin" \
	--request POST "http://localhost:8080/openidm/workflow/processinstance?_action=createProcessInstance" \
	--data '{"key":"EmailNotification","fromSender" : "noreply@openidm","toEmail" : "jdoe@example.com"}'
 
{"_id":"208","processInstanceId":"208","status":"ended","businessKey":null,"processDefinitionId":"EmailNotification:1:207"}

Example Sunset Workflow Triggered By Reconciliation

* Authoritative data source: CSV file

"firstName","uid","lastName","email","employeeNumber",password,"sunrise","sunset","active"
"Darth","DDOE","Doe","doe@example.com","123456","Z29vZA==","2012-06-30T00:00:00Z","2012-12-23T00:00:00Z","TRUE"

* Target data source: XML file

 

* Scenario:
New user in CSV -> Kicks of reconcile process -> Found new user -> Add to XML

 

Sending Email

Setup Outbound Email

* Shutdown OpenIDM
* Copy sample email config file to conf directory:

cd $OPENIDM_HOME
cp samples/misc/external.email.json conf/

* Modify email config file:

{
        "host" : "smtp.example.com",
        "port" : "25",
        "username" : "openidm",
        "password" : "secret12",
        "mail.smtp.auth" : "true",
        "mail.smtp.starttls.enable" : "true"
}

* Restart OpenIDM
* Check external mail is up and running

-> scr list
...
[   6] [active       ] org.forgerock.openidm.external.email
...

Send mail from REST

curl \
 --header "X-OpenIDM-Username: openidm-admin" \
 --header "X-OpenIDM-Password: openidm-admin" \
 --request POST "http://localhost:8080/openidm/external/email?_from=openidm@example.com&_to=user@example.com&_subject=Test&_body=Test"
 
{"status":"OK"}

Sending Mail from Script

* Use external/email context:

var params =  new Object();
params._from = "openidm@example.com";
params._to = "admin@example.com";
params._cc = "wally@example.com,dilbert@example.com";
params._subject = "OpenIDM recon report";
params._type = "text/html";
params._body = "<html><body><p>Recon report follows...</p></body></html>";
 
openidm.action("external/email", params);

Errors

action method not implemented on workflow

* Error message:

curl \
  --header "X-OpenIDM-Username: openidm-admin" \
  --header "X-OpenIDM-Password: openidm-admin" \
  --request POST "http://localhost:8080/openidm/workflow?_action=osgiProcess"
 
curl \
>   --header "X-OpenIDM-Username: openidm-admin" \
>   --header "X-OpenIDM-Password: openidm-admin" \
>   --request POST "http://localhost:8080/openidm/workflow?_action=osgiProcess"
{"error":400,"reason":"Bad Request","detail":"action method not implemented on workflow"}

* Reason: OpenIDM/Activiti REST interface has changed.

References

* OpenIDM 2.1.0 Integrator’s Guide
* ForgeRock Documentation
* OpenIDM Wiki
* Forum
* Enhanced REST interface for the Activiti integration

This entry was posted in OpenIdm and tagged , . Bookmark the permalink.

One Response to OpenIDM 2.1 Integration Guide

Leave a Reply

Your email address will not be published. Required fields are marked *


*

This site uses Akismet to reduce spam. Learn how your comment data is processed.