Notification of One Touch profiles, about to expire

This guide describes how to configure notifications for One Touch profiles that are about to expire.
Information about the profile is located in the database, value for mail will be picked up from LDAP and sent using SMTP.

NOTE: The configuration below is an example of how this can be done, using the internal HSQLDB introduced in PAS 4.0. If another type of database is used, please adjust connection and query according to environment.

Description

Notifications can be sent out using a configured schedule.
Below steps will describe how to retrieve the needed information and then use a schedule for notifications using SMTP.

NOTE: Make sure to have a recent copy of the file /config/phenix-store.json before proceeding.

Add connection to database

We need a connection to the database where tokens are stored.
So in the configuration GUI, go to the Scenarios tab, choose Connections and then click the plus sign besides JDBC. Follow the steps to configure the database connection. When done, copy "Scenario ID"  for use in the pipe configuration below.

NOTE: If internal HSQLDB is used, copy the file <PASInstallationdir>/mods/com.phenixidentity~phenix-store-mpl~<version>/lib/hsqldb-<version>.jar to <PASInstallationdir>mods/com.phenixidentity~phenix-pipes~<version>/lib/
Then run the JDBC scenario for one of the predefined databases. In the Configuration GUI, go to the ADVANCED tab and then "Database connections", change the values for "driver" and "url". Like this example:

"driver": "org.hsqldb.jdbc.JDBCDriver",
"url": "jdbc:hsqldb:hsql://localhost:9001/phenixid",
Click to copy

LDAP connection

We will also need the "Scenario ID" of the LDAP connection. It can be found in the configuration GUI, Connections and then LDAP. Copy it for use in the pipe configuration below.

Configuration for notifications

In the Configuration GUI, go to the ADVANCED tab and then Pipes.
 Add the pipe below, making sure to set the values according to your environment.

{
	"id": "notification",
	"description": "Notifications of profiles expiring in 30 days",
	"valves": [{
			"name": "ItemCreateValve",
			"config": {
				"dest_id": "item"
			}
		},
		{
			"name": "DateTimeGeneratorValve",
			"description": "Start of expiration check period, duration should be removed if todays date is expected",
			"config": {
				"dest": "startdate",
				"_duration": "P360D",
				"pattern": "yyyy-MM-dd"
			}
		},
		{
			"name": "DateTimeGeneratorValve",
			"description": "End of expiration check period. Set duration to P30D for today+30 days.",
			"config": {
				"dest": "enddate",
				"duration": "P30D",
				"pattern": "yyyy-MM-dd"
			}
		},
		{
			"name": "SessionCreateValve",
			"config": {}
		},
		{
			"name": "SessionPropertyAddValve",
			"config": {
				"name": "enddate",
				"value": "{{item.enddate}}"
			}
		},
		{
			"name": "StatementExecutorValve",
			"description": "Fetch the tokens about to expire. Make sure to sort the result by expires DESC",
			"config": {
				"connection_ref": "d6fdd5eb-5adf-424b-99d9-e31d602c85d4",
				"statement": "select id,assignedTo,expires from tokens where expires >= '{{item.startdate}}' AND expires <= '{{item.enddate}}' AND device_ref is not null ORDER BY expires DESC",
				"attributes": "assignedTo,expires"
			}
		},
		{
			"name": "StatementExecutorValve",
			"enabled": "true",
			"description": "Check if account has valid profile, after configured end date",
			"config": {
				"connection_ref": "d6fdd5eb-5adf-424b-99d9-e31d602c85d4",
				"statement": "select id,assignedTo,expires AS \"GoodToGo\" from tokens where expires >= '{{session.enddate}}' AND assignedTo = '{{item.assignedTo}}' AND device_ref is not null ORDER BY expires DESC",
				"attributes": "GoodToGo,assignedTo"
			}
		},
		{
			"name": "ItemMatchAndMergeValve",
			"enabled": "true",
			"description": "Keep one item per user",
			"config": {
				"matchingProperty": "assignedTo",
				"mergeProperties": "expires,GoodToGo"
			}
		},
		{
			"name": "ItemRemoveValve",
			"description": "Remove items that are good to go.",
			"enabled": "true",
			"config": {
				"item_include_expr": "item.containsProperty('GoodToGo')"
			}
		},
		{
			"name": "ItemRemoveValve",
			"description": "Remove initial item",
			"enabled": "true",
			"config": {
				"item_include_expr": "item.containsProperty('enddate')"
			}
		},
		{
			"name": "PropertySubstringValve",
			"description": "Keep only the yyyy-MM-dd part of expires",
			"config": {
				"source": "expires",
				"end_index": "10",
				"begin_index": "0"
			}
		},
		{
			"name": "PropertyJoinValve",
			"description": "Will only keep the first value in expires",
			"config": {
				"source": "expires"
			}
		},
		{
			"name": "LDAPSearchValve",
			"enabled": "true",
			"config": {
				"connection_ref": "c22266e1-968a-4638-b3a4-723febc95634",
				"base_dn": "DC=org,DC=local",
				"scope": "SUB",
				"size_limit": "0",
				"filter_template": "(samaccountname={{item.assignedTo}})",
				"attributes": "mail,samaccountname,givenName"
			}
		},
		{
			"name": "PropertyRenameValve",
			"config": {
				"source": "sAMAccountName",
				"dest": "assignedTo"
			}
		},
		{
			"name": "ItemMatchAndMergeValve",
			"enabled": "true",
			"description": "Merge the item from SQL with the item from LDAP",
			"config": {
				"matchingProperty": "assignedTo",
				"mergeProperties": "mail,givenName,gotValidToken"
			}
		},
		{
			"name": "ItemRemoveValve",
			"description": "Remove items that is missing mail",
			"enabled": "true",
			"config": {
				"item_include_expr": "!item.containsProperty('mail')"
			}
		},
		{
			"name": "PipeExecutorValve",
			"enabled": "true",
			"config": {
				"pipe_id": "pipeSendNotification",
				"enable_multi_value": "true"
			}
		}
	]
}, {
	"id": "pipeSendNotification",
	"description": "Sending the mail",
	"valves": [{
			"name": "ItemCreateFromRequestValve",
			"config": {
				"dest_id": "{{request.assignedTo}}"
			}
		},
		{
			"name": "SMTPValve",
			"enabled": "true",
			"config": {
				"userid_param_name": "{{item.assignedTo}}",
				"mail_param_name": "{{item.mail}}",
				"mail_template": "resources/expiration.mustache",
				"smtp_host": "smtp.org.com",
				"smtp_port": "587",
				"smtp_username": "[email protected]",
				"smtp_password": "{enc}TIIvKieZ+tLHrAuvVmYgMXjxVvTbv8/ZNdE7DXVlbyI=",
				"smtp_from_address": "[email protected]",
				"message_subject": "Your OT profile is about to expire",
				"message_body": "Hi $$USER, your One Touch profile for MyOrg will expire on $$DATE.",
				"dynamic_values": "$$USER={{item.givenName}}|$$DATE={{item.expires}}"
			}
		}
	]
}
Click to copy

Example mail_template:

<html>
<body>
{{message}}<br><br>
Login to the portal to reenroll.<br>
Please contact Helpdesk if you need assistance.
</body>
</html>
Click to copy

Add schedule for notifications

In the Configuration GUI, go to the ADVANCED tab and then Schedules.
Add the configuration below, making sure to set the values according to your environment.

{
	"id": "notification",
	"description": "Will notify if profile will expire in 30 days. Once a week on Monday@10.",
	"enabled": "true",
	"boundToNode": "phenixid_node",
	"cronSyntax": "0 0 10 ? * MON *",
	"pipeid": "notification"
}
Click to copy

The configuration above will run the schedule every Monday at 10am.
More information about the cronSyntax can be found here.