# Login to SailPoint.
# Navigate to Applications ---> Application Definition
# Select the Application Type as DUO and provide the required details.
# Login to SailPoint.
# Navigate to Applications ---> Application Definition
# Select the Application Type as DUO and provide the required details.
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule created="1640624033221" id="ff8080817dee757a017dfcd00dc503e0" language="beanshell" name="Log4j 2 version">
<Signature>
<Inputs>
<Argument name="log">
<Description>`
The log object is associated with the SailPointContext.
</Description>
</Argument>
<Argument name="context">
<Description>
A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
</Description>
</Argument>
</Inputs>
</Signature>
<Source>
String version = org.apache.logging.log4j.util.PropertiesUtil.class.getPackage().getImplementationVersion();
return version;
</Source>
</Rule>
# 22 = SSH (Secure Shell) - log into a Linux instance
# 21 = FTP (File Transfer Protocol)
# 22 = SFTP (Secure File Transfer Protocol) upload files using SSH
# 80 = HTTP - access unsecured websites
# 443 = HTTPS - access secured websites
# 3389 = RDP (Remote Desktop Protocol) - log into a windows instance
# To fix the Log4j 2 vulnerability, we have to add -Dlog4j2.formatMsgLookups=true in catalina.sh and iiq file.
# Navigate to iiq path
cd /opt/apache/bin
# Update the JAVA options (vi iiq)
JAVA_OPTS="-Xms128m -Xmx256m -Dsun.lang.ClassLoader.allowArraySyntax=true -Djava.awt.headless=true -Dlog4j2.formatMsgLookups=true"
# Save & exit (:wq!)
# Navigate to catalina.sh path
cd /opt/apache/webapps/idenityiq/WEB-INF/bin
# Update the JAVA options (vi catalina.sh)
rem Register custom URL handlers
rem Do this here so custom URL handles (specifically 'war:...') can be used in the security policy
set "JAVA_OPTS=%JAVA_OPTS% -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dlog4j2.formatMsgLookups=true"
# Save & exit (:wq!)
# Restart the server.
./shutdown.sh
./startup.sh
# First copy the ZIP file to identityiq location.
# Check the ZIP file in identityiq whether it is copied or not.
# Extract the ZIP file.
# Update all jars
# Restart the server.
===============================################============================
# cp /home/sudo/idenityiq-8.1-8.1p3-IIQCB-4601.zip /opt/apache/webapps/identityiq
# cd /opt/apache/webapps/identityiq
# ls -ltr
# unzip idenityiq-8.1-8.1p3-IIQCB-4601.zip
# A (Shift+A)
# cd /opt/apache/bin
./shutdown.sh
./startup.sh
# aws s3 cp s3://S3 Bucket Name/Jar File /home/Root User or Any user/
# aws s3 cp s3://iamdir-OIM-dev-vendorbinaries-s3/jd-gui-1.6.6.jar /home/sudo/
Ex:
1. Navigate to the following directory C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\identityiq\WEB-INF\classes\sailpoint\object.
2. Add the following three lines in IdentityExtended.hbm.xml file
<property name="costCenter" type="string" length="450" access="sailpoint.persistence.ExtendedPropertyAccessor"
index="spt_identity_costCenter_ci"/>
<property name="empId" type="string" length="450" access="sailpoint.persistence.ExtendedPropertyAccessor"
index="spt_identity_empId_ci"/>
<property name="status" type="string" length="450" access="sailpoint.persistence.ExtendedPropertyAccessor"
index="spt_identity_status_ci"/>
import sailpoint.object.Filter;
import sailpoint.object.QueryOptions;
QueryOptions qOptions = new QueryOptions();
qOptions.addFilter(Filter.eq("workgroup",false));
int numberOfIdentities = context.countObjects(Identity.class, qOptions);
QueryOptions qOptions = new QueryOptions();
qOptions.addFilter(Filter.eq("workgroup",true));
int numberOfWorkGroups = context.countObjects(Identity.class, qOptions);
String message = "No of identities : "+numberOfIdentities+" No of workgroups : "+numberOfWorkGroups;
log.debug("message : "+message);
logger.WFLog.name=sailpoint.WorkflowTrace
logger.WFLog.level=trace
logger.RoleLifecycler.name=sailpoint.api.RoleLifecycler
logger.RoleLifecycler.level=trace
logger.Workflower.name=sailpoint.api.Workflower
logger.Workflower.level=trace
# ./iiq console -j
# Display the list of console commands: help (or) ?
# Exit the from IIQ console: quit
# Delete all identities except spadmin from the IIQ console: delete identity *
# Export a single object from the IIQ console using the checkout command:
checkout workflow "Provisioning Approval Subprocess" workflow.xml -clean
# Run the task from the IIQ console using the run command: run "Mighty Run Rule Task"
# Export an object from the IIQ console:
export -clean /usr/binrootsh/Desktop/apps.xml application
import sailpoint.object.ManagedAttribute;
Boolean entitlementCheck(){
boolean existingEnt = false;
String appName = "SAP";
String entDN = "CN=abc, OU=Pedia, DC=com";
String cn = "Java";
String displayName = null;
Filter managedAttrFilter = Filter.eq("application.name", appName);
managedAttrFilter = Filter.and(managedAttrFilter, filter.eq("value", entDN));
ManagedAttribute managedAttribute = context.getUniueObject(ManagedAttribute.class, managedAttrFilter);
if(managedAttribute != null){
displayName = managedAttribute.getDisplayName();
if(displayName.equals(cn))
existingEnt= true;
}
return existingEnt;
}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import sailpoint.object.Filter;
import sailpoint.object.Identity;
import sailpoint.object.IdentitySnapshot;
import sailpoint.object.LinkSnapshot;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.QueryOptions;
import sailpoint.tools.GeneralException;
public List<LinkSnapshot> getIdSnapshot(String identityName) throws GeneralException {
log.debug("Enter into the method : getIdSnapshot");
boolean checkSnapshot = false;
List<LinkSnapshot> linkSnap = new ArrayList<LinkSnapshot>();
QueryOptions qop = new QueryOptions();
qop.addFilter(Filter.eq("identityName", identityName));
qop.setOrderBy("created");
qop.setOrderAscending(false);
Iterator<IdentitySnapshot> it = context.search(IdentitySnapshot.class, qop);
checkSnapshot = it.hasNext();
if (checkSnapshot) {
IdentitySnapshot eachIdentitySnapshot = (IdentitySnapshot) it.next();
linkSnap = eachIdentitySnapshot.getLinks();
}
log.debug("Exiting from the method : getIdSnapshot");
return linkSnap;
}
public ProvisioningPlan buildPlanFromSnapshot(String identityName) throws GeneralException {
log.debug("Enter into the method : buildFromSnapshot");
ProvisioningPlan plan = new ProvisioningPlan();
Identity identity = context.getObjectByName(Identity.class, identityName);
if (plan != null) {
plan.setIdentity(identity);
}
List<LinkSnapshot> linkSnap = new ArrayList<LinkSnapshot>();
linkSnap = getIdSnapshot(identityName);
for (LinkSnapshot ls : linkSnap) {
if (ls.getAttributes().get("IIQDisabled") == null
|| ls.getAttributes().get("IIQDisabled").toString().equals("false")) {
AccountRequest accountRequest = new AccountRequest();
accountRequest.setApplication(ls.getApplicationName());
accountRequest.setInstance(ls.getInstance());
accountRequest.setNativeIdentity(ls.getNativeIdentity());
accountRequest.setOperation(AccountRequest.Operation.Create);
plan.add(accountRequest);
}
}
log.debug("Link plan : " + plan.toXml());
log.debug("Exiting from the method : buildPlanFromSnapshot");
return plan;
}
Reference: Lifecycle Manager Workflows - Compass (sailpoint.com)
Workflow: LCM Provisioning
# Identity Request Initialize
Identity Request Violation Review
Do Provisioning Forms
Manage Ticket
Provision with retries
# Provisioning Approval Subprocess
# Approve and Provision Subprocess
Provisioning Approval Subprocess
Manage Ticket
Provision with retries
Identity Request Provision
Do Provisioning Forms
Provision with retries
Check Status of queued items
Manage Ticket
Provision with retries
# Identity Request Notify
# Identity Request Finalize
Manage Ticket
Provision with retries
import java.util.ArrayList;
import java.util.List;
import sailpoint.object.Identity;
import sailpoint.api.SailPointContext;
import sailpoint.tools.GeneralException;
public void removeWorkGroupsAssignment(String name) throws GeneralException{
String methodName = "removeWprkGroupAssignment";
log.debug("Entering into the method : "+methodName);
Identity identityObj = context.getObject(Identity.class, name);
List<Identity idWorkGroups = new ArrayList<Identity>();
idWorkGroups = identityObj.getWorkgroups();
for(Identity workGoup : idWorkGroups){
identityObj.remove(workGoup);
context.saveObject(identityObj);
context.commitTansaction();
}
log.debug("Exiting from the method : "+methodName);
}
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Get Request Objects">
<Description>
</Description>
<Signature>
<Inputs>
<Argument name="log">
<Description>
The log object associated with the SailPointContext.
</Description>
</Argument>
<Argument name="context">
<Description>
A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
</Description>
</Argument>
</Inputs>
</Signature>
<Source>
import sailpoint.api.SailPointContext;
import sailpoint.object.Request;
// fetch all the request objects
String ruleName = "getResourceObjects";
log.error("Entering into the rule : " + ruleName);
List<Request> requests = context.getObjects(Request.class);
log.error("Exiting from the rule : "+ruleName);
return requests;
</Source>
</Rule>
------------------------------------------------##################-------------------------------------------------
------------------------------------------------##################-------------------------------------------------
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Get Request Object">
<Description>
</Description>
<Signature>
<Inputs>
<Argument name="log">
<Description>
The log object associated with the SailPointContext.
</Description>
</Argument>
<Argument name="context">
<Description>
A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
</Description>
</Argument>
</Inputs>
</Signature>
<Source>
import sailpoint.api.SailPointContext;
import sailpoint.object.Request;
// fetch specific request object
String ruleName = "getResourceObject";
log.error("Entering into the rule : " + ruleName);
String name2 = null;
boolean flag = false;
List<Request> requests = context.getObjects(Request.class);
log.error("Request objects size is : " + requests.size());
for (Request request2 : requests) {
String name = request2.getName();
flag = name.contains("999999");
if (flag) {
name2 = name;
break;
}
}
log.error("Exiting from the rule : "+ruleName);
return name2;
</Source>
</Rule>
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Password Decryption">
<Description>
</Description>
<Signature>
<Inputs>
<Argument name="log">
<Description>
The log object associated with the SailPointContext.
</Description>
</Argument>
<Argument name="context">
<Description>
A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
</Description>
</Argument>
</Inputs>
</Signature>
<Source>
import sailpoint.api.SailPointContext;
String password = "1:3XlHok3A4TTAIpnoglhLFg==";
return context.decrypt(password);
</Source>
</Rule>
Total Hours = 850, Burns Hours = 180
Total % left = Total Hours - Burns Hours / (1 % Total Hours) = 850 - 180 / 8.5 = 78.82 %
% Burn = 100 - Total % left = 100 - 78.82 = 21.17
# It's initially designed for non-rule based connectors to add Privileged flag to accounts. It can be used for customization of account attributes as well.
System.out.println("Entering into Leaver Event Rule : ");
String status = newIdentity.getAttribute("status");
System.out.println("status : "+status);
if(status != null){
if(status.equalsIgnoreCase("Terminated Employee")){
boolean flag = true;
System.out.println("Entering into Leaver Event Rule : "+flag);
return flag;
}
else {
boolean flag = false;
System.out.println("Entering into Leaver Event Rule : "+flag);
return flag;
}
System.out.println("Exiting from the Leaver Event Rule : ");
}
Pre-requisites :-
1. Download the VM ware from the following URL:
Download VMware Workstation Player | VMware | IN
Steps:Steps:
1. Go to MySQL installation directory then until the bin
Ex: C:\Program Files\MySQL\MySQL Server 8.0\bin
2. Open cmd from the above path
(OR)
Navigate to the Windows icon, search for cmd, and click on Command Prompt
3. Enter the following command in cmd
cd C:\Program Files\MySQL\MySQL Server 8.0\bin
4. mysql -u root -p (mysql -u reddy -p)
NOTE: root is the default username, if you have used a custom username, as mentioned like above
5. Enter the password: *******
6. show databases;
(this command will display the lists of databases)
======================================================================
Follow the below URL's for installing MYSQL ::-
# How to Install MySQL on Windows 10 (Step-By-Step Guide) (smarttechnicalworld.com)
# Install MySQL on Windows 10 Step by Step | OnlineTutorialsPoint
# How to download and install MySQL on Windows 10? (roseindia.net)
# How To Install MySQL in Windows 10 - Step-By-Step Tutorials - MobyGeek.com
# How To Install MySQL in Windows 10?(Easy Step By Step Guideline) - FixGuider
# IdentityService : A service layer that deals with identities.
IdentityService(
SailPointContext context) : Constructor.
# WorkflowContext :
BuildMap Rule :
public ProvisioningPlan buildMoveADAccountsPlan(WorkflowContext wfc)
throws GeneralException {
Logger ruleLog = Logger.getLogger("RuleLog");
if (ruleLog.isDebugEnabled()) ruleLog.debug("Entering into buildMoveADAccountsPlan rule");
Attributes args = wfc.getArguments();
String op = Util.getString(args, "op");
if ( op == null ){
throw new GeneralException("Operation (op) must be specified.");
}
Custom settings = context.getObjectByName(Custom.class, "Custom Settings");
ProvisioningPlan plan = new ProvisioningPlan();
String identityName = Util.getString(args, "identityName");
if (ruleLog.isDebugEnabled()) ruleLog.debug("Processing identity " + identityName);
Identity identity = context.getObjectByName(Identity.class, identityName);
if (null != identity) {
plan.setIdentity(identity);
// Get a list of AD applications
List appList = getADApps();
IdentityService identityService = new IdentityService(context);
for (Application app : appList) {
List links = identityService.getLinks(identity, app);
if ((null != links) && !links.isEmpty()) {
for (Link link : links) {
String nativeIdentity = link.getNativeIdentity();
String newOU = null;
if (op.equals("Disable")) {
if (nativeIdentity.toLowerCase().endsWith("dc=mightypedia,dc=com")){
newOU = settings.get("pediaADDisabledUsersOU");
}
}
}
}
if (ruleLog.isDebugEnabled()) {
ruleLog.debug("Moving to " + newOU);
}
if (null != newOU && ! newOU.equalsIgnoreCase(getParentContainerDN(nativeIdentity))) {
AccountRequest acctReq = new AccountRequest();
acctReq.setApplication(link.getApplicationName());
acctReq.setInstance(link.getInstance());
acctReq.setNativeIdentity(link.getNativeIdentity());
acctReq.setOperation(AccountRequest.Operation.Modify);
AttributeRequest attReq = new AttributeRequest();
attReq.setName("AC_NewParent");
attReq.setValue(newOU);
attReq.setOp(ProvisioningPlan.Operation.Set);
acctReq.add(attReq);
plan.add(acctReq);
}
}
}
}
}
if (ruleLog.isDebugEnabled()) {
ruleLog.debug("Returning plan: " + plan.toXml());
}
return plan;
}
---------------------------------------------################----------------------------------------------
public List getADApps() {
Logger ruleLog = Logger.getLogger("RuleLog");
List appList = new ArrayList();
QueryOptions qo = new QueryOptions();
qo.addFilter(Filter.eq("connector", "sailpoint.connector.ADLDAPConnector"));
Iterator it = context.search(Application.class, qo);
while (it.hasNext()) {
Application thisApplication = it.next();
if (ruleLog.isDebugEnabled()) ruleLog.debug("Found Active Directory application " + thisApplication.getName());
appList.add(thisApplication);
}
if (appList.isEmpty()) {
ruleLog.warn("No Active Directory applications found");
}
return appList;
}
Steps :
1. Login to debug page
2. Navigate to Configuration Objects and click on System Configuration
search for syslog_extension then add entry
<entry key="timeMachineEnabled" value="true"/>
3. Search following URL in browser :
SailPoint IdentityIQ - Time Machine
High Level Steps of developing Custom Tasks :-
1. Create TaskDefinition.xml file then import into IIQ
Note : Define a task definition with input and return arguments
2. Develop a Java code and place it in following path :
C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\idenityiq\WEB-INF\classes\sailpoint
public class Demo extends AbstractTaskExecutor {
public void execute(SailPointContext sailpointContext, TaskSchedule taskSchedule, TaskResult taskResult, Attributes args) throws Exception {
String output = "output";
String appName = (String) args.get("application");
result.setAttribute(output, "This is Prasad Reddy" + appName);
}
public boolean terminate() {
return false;
}
NOTE : Create custom directory in above path then place the java file in custom directory.
3. Restart the application server (Apach Tomcat Server)
The Workflow tag identifies the name and type of the workflow.
<Workflow explicitTransitions="true" name="WF-Training Hello World Workflow"
type="IdentityUpdate">
# name: Specifies the name of the variable
The task types are:
# Account Aggregation — scan all applications, discover users and entitlements on those applications, and then correlate those users and entitlements with roles.
#Account Group Aggregation — scans applications and aggregates account groups and application object types. These are then used for group certification (either permissions or membership) or for displaying group information in identity certifications.
# Activity Aggregation — scan all applications, discover activity on the applications, and then correlate that activity with identity cubes. This enables you to track and monitor all activity for possible policy violations.
# Alert Aggregation — scan applications and aggregates alerts from a set of Alert Collectors. These are then used to generate alert actions.
# Alert Processor — process the aggregated alerts against the alert definitions and launch the appropriate action.
#Application Builder — create multiple IdentityIQ applications or update the attribute map of an existing IdentityIQ application.
# ArcSight Data Export — export data for HP ArcSight Database Connector to an external database table.
# Data Export — generate a de-normalized data report to export to an external database table.
# Effective Access Indexing — generate an index of any indirect access that was granted through another object. For example a nested group, an unstructured target, or another role.
# Encrypted Data Synchronization Task —re-encrypt data with user-generated encryption key.
# Entitlement Role Generator — scans the entitlements in the system and automatically generates a simple role and appropriates a profile for each one that it finds.
# FIM Application Creator — automatically discover and create FIM Management Agent Applications.
# IQService Public Key Exchange — change the public keys that are used for IQService communications
# ITIM Application Creator — inspect the IBM Tivoli Identity Manager (ITIM) and retrieve information about the ITIM services (applications). This task auto-generates an application for each service defined in ITIM.
# Identity IQ Cloud Gateway Synchronization — Synchronize the specified objects to the Cloud Gateway.
# Identity Refresh — scan all applications, including the IdentityIQ application, to ensure that all identity information is up-to-date and accurate. Refresh identity scans are also used to detect and report on policy violations and trigger event certifications.
# Identity Request Maintenance — scan for completed Lifecycle Manager access requests.
# Missing Managed Entitlements Scan — scan the selected application to create entitlement objects for items added after the application was last aggregated
# Novell Application Creator — inspect the Novell IDM application and retrieve information about all connected applications.
# OIM Application Creator — inspect the OIM application and retrieve information about all connected applications.
# Policy Scan — runs policies against identity cubes and update identity score cards with any policy violations discovered.
# Propagate Role Changes — refreshes identities who have an assigned role whose associated entitlements have changed.
# Refresh Logical Accounts — is used to refresh composite accounts for all identities that could, potentially, have a composite account on the composite applications selected.
# Role Index Refresh — updates all role information and creates the indexes needed to perform role searches. You must run this task before performing any role searching.
# Run Rule — runs the specified rule with name/value pairs.
# Sequential Task Launcher — launches the specified tasks in the order defined. This enables you to launch tasks that must be run sequentially in the proper order without having to schedule each separately based on estimated run times.
# "System Maintenance" — tasks designed to run in the background.
# Target Aggregation — scan selected applications for activity targets.
How To Create a New Workflow ::-
1. Navigate to Setup -> Business Processes.
2. Click New to create a new workflow and then enter a name for your process.
3. Specify a name and description for the workflow. Use a short descriptive name for the workflow and use a
the description that provides an overview of the workflow function.
4. In the Type field:
a. Select from the drop-down list of predefined workflow types. The available types are restricted to
the process options related to the workflow.
b. To enter a custom type, manually enter the type name in the box instead of selecting one from the
list. See the Workflow Basics chapters for any limitations to custom types.
5. Navigate through each of the process tabs and specify workflow data.
6. Click Save.
How To Use an Existing Workflow to Create a New Business Process ::-
1. Navigate to Setup -> Business Processes.
2. Select an existing workflow from the Edit an Existing Process list.
3. Navigate through each of the process tabs to view or modify the workflow data.
4. Click Save As and enter a unique name for the workflow.
Navigate to the C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\identityiq\WEB-INF\bin directory
Launch the iiq console by running this command: iiq console
The console is running when you see a > symbol in the command prompt.
In the IdentityIQ console, run this command:
import init.xml
import init-lcm.xml
a. Notice the types of objects being imported into IdentityIQ
b. List two that you are familiar with:
When the import is complete, type quit to exit from the IdentityIQ console.
Starting in version 7.0, the top-level workflows used by LCM are configured on the Gear ===> Lifecycle Manager ===> Business Processes page in the IdentityIQ user interface.
There are four main default LCM workflows which are applied to complete the required provisioning actions, depending on the origin of the provisioning request:
LCM Provisioning
LCM Manage Passwords
LCM Create and Update
LCM Registration
As shown here, the same workflow can be used to drive provisioning in response to different starting events.
For example, by default, LCM Provisioning handles requests coming from the Request Access LCM option (role and entitlement requests) as well as Manage Accounts requests (new accounts or enable/disable/unlock/delete requests), among others.
1. Configure the Manager Quicklink population to allow account only requests.
a. Navigate to ===> Global Settings ===> Quicklink Populations and open the Manager
population
b. Click the Quicklinks tab and next to Manage Accounts, click Config…
Prune Identity Cubes task ::
The purpose of the Prune Identity Cubes task is to delete non-authoritative Identity Cubes that house no accounts.
As long as the new identity obtains access (the Identity Cube has correlated accounts) by this date,
it won’t be pruned; if access is not obtained by this date, it will be pruned.
This value can be set in the LCM configuration.
What is Workflow / Business Process?
# A sequence (or) series of steps (or) operations that are launched to perform work
NOTE: Workflow is similar to Orchestration in OIM
Process Details: Specify Name, Type, and Description of the workflow.
The following events can trigger a workflow:
• Role creation or modification
• Account Group creation or modification
• Identity update
• Identity refresh
• Identity correlation
• Deferred role assignment, de-assignment
• Deferred role activation, deactivation
• Any Lifecycle Manager event
• Any Lifecycle Event (marked by changes to an Identity's attributes)
Custom workflows can be defined to do a wide variety of processing tasks. You can use:
• IdentityIQ workflow library methods and rules.
• Custom BeanShell scripts and rules.
Customizing or creating workflows generally involves a combination of XML and Java/BeanShell programming.
How many ways to implement Business Process?
# 2 ways
# One way is from UI (Business Process)
# Other way is to implement workflow in XML file then we can import that XML file into IIQ
How to delete a workflow in IIQ?
# Login to Debug page
# Search workflow or select from workflow drop-down menu under Object Browser
# Then search with a specific workflow name and select it
# Right side corner selects an action which drops down after that click on Delete.
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import sailpoint.api.ObjectUtil; import sailpoint.ob...