Cybersecurity
DevOps Cloud (ADM)
IT Operations Cloud
In many cases there is a need to add loops to a workflow.
Such loops may be required if you need to execute repetitive tasks, or to perform tasks on multiple objects.
This article shows both:
The workflow sample outlined in this article has the purpose to deactivate users who have not logged in for a specified number of days.
For this purpose, the example uses two loops:
Adding a time-controlled loop is rather simple.
Adding data-dependent loops is only slightly more complicated, since you need to add some custom ECMAscript to evaluate the data and control the loop.
Here's the basic logic for a workflow that, once started, will automatically run every day, identify the inactive users, and disable each user in the list:
The form will also show what users will be affected during the first run.
Internally, a Query is used, and you will probably need to adapt this query to your own needs:
The sample query is named "CoolSolution_inactiveUsers" and perform a search on the container "OU=users,O=utopia" with a filter "( && ( loginDisabled != true )( loginTime < [param] ))"
We store the calculated criterionDate in flowdata (flowdata.start/criterionDate).
This is the code to calculate the target date:
function getCriterionDate( )
{
var result = "00000000000000Z";
try
{
var daysOfInactivity = flowdata.get('start/request_form/daysOfInactivity');
var someTimeAgo = new Date();
someTimeAgo.setDate( someTimeAgo.getDate() - daysOfInactivity );
result = ""
( // make date 8-digit
10000 * someTimeAgo.getUTCFullYear()
100 * (someTimeAgo.getMonth() 1)
someTimeAgo.getUTCDate()
)
( // make time 8-digit
10000 * someTimeAgo.getUTCHours()
100 * someTimeAgo.getUTCMinutes()
someTimeAgo.getUTCSeconds()
)
"Z";
}
catch ( ex ) {}
return( result );
}
getCriterionDate();
This is the code to run the query and store the list:
function getInactiveUsers()
{
var result = new java.util.Vector();
try
{
var daysOfInactivity = flowdata.get('start/request_form/daysOfInactivity');
var criterionDate = flowdata.get('start/criterionDate');
result = IDVault.globalQuery( "CoolSolution_inactiveUsers", {"someTimeAgo": criterionDate });
}
catch ( ex ) {}
return( result );
};
getInactiveUsers();
If inactive users were found, we continue with step e)
( flowdata.get('start/inactiveUsers/DNs').length > 0 )
This step will simply get the first user from this list and store the DN in flowdata (flowdata.start/inactiveUsers/nextDN).
flowdata.get('start/inactiveUsers/DNs')
The condition will return "true" as long there are more users to process; in this case, we'll continue with step g).
It will return "false", after all users have been processed; in this case we'll goto step i) to wait for the next polling loop on the next day.
( flowdata.get('start/inactiveUsers/nextDN').length > 0 )
We continue with step e) to get the next user in the reduced list.
This code removes the first list entry:
function removeFirstElement()
{
var result = new java.util.Vector();
try
{
var objectsRemaining = flowdata.getObject('start/inactiveUsers/DNs')
// start loop with second element
for ( var i=1; i < objectsRemaining.size(); i )
{
try
{
result.add( objectsRemaining.get(i).getFirstChild().getNodeValue() );
}
catch (e) {}
}
}
catch (e) {}
return result;
} ;
removeFirstElement();
If the selected addressee does nothing, the workflow will timeout and continue with step b)
If an admin opens the approval form and presses "Deny Request", the whole workflow ends with step j)
The sample workflow for this article has been attached and can be imported into designer.
It consists of
If you are not working with Novell's demo environment "Utopia", you will probably have to modify the trustees of the workflow and the search base for the query.
Developed and tested on Identity Manager version 3.7.0