<entry key="ReassignmentRecipient"> <value> <IdentityFilter name="ReassignmentRecipient" order="Ascending"> <FilterScript> <Script> <Source> import sailpoint.object.Identity; import sailpoint.object.QueryOptions; import sailpoint.object.Filter; import java.util.List; import java.util.ArrayList; Identity identity = context.getObjectById(Identity.class, loggedInUser); if(identity == null){ identity = context.getObjectByName(Identity.class, loggedInUser); } QueryOptions qo = new QueryOptions(); List managers = new ArrayList(); int managerLevels = 2; int maxIterations = 15; if(identity != null){ int level = 0; int iter = 0; while((level < managerLevels) && (iter < maxIterations)){ iter++; Identity manager = identity.getManager(); if(null == manager) break; if(!manager.isInactive()){ managers.add(manager.getId()); level++; } identity = manager; } } qo.addFilter(Filter.in("id",managers)); return qo; </Source> </Script> </FilterScript> <OrderBy> <String>firstname</String> </OrderBy> </IdentityFilter> </value> </entry>
Thursday, November 16, 2023
IdentityIQ Sailpoint Show only Active Manager in Workitem forwarding
Thursday, February 10, 2022
Sailpoint IdentityIQ Loopback Connector Configuration
Loopback Connector is used to manage the Workgroup & Capability of Sailpoint. This Connector is part of the SSF Framework.
Below Configuration is done to manage the WG which start with "VIS"
- Ignore non correlated identities = true
- Ignore identities with no entitlements = true
- Identity filter = Workgroups.name.startsWith("VIS")
Account Customization Rule
List workgroupList = (List)object.getAttribute("workgroups.name"); List updatedWorkgroupList=new ArrayList(); if(!workgroupList.isEmpty()){ for(String workgroupName:workgroupList){ if(workgroupName.startsWith("VIS")){ updatedWorkgroupList.add(workgroupName); } } if(!updatedWorkgroupList.isEmpty()){ object.setAttribute("workgroups.name",updatedWorkgroupList); return object; }else{ return null; } }else{ return null; }
WorkGroup Customization Rule
import sailpoint.object.ManagedAttribute; import java.util.Map; import java.util.HashMap; String workGroupName = (String) object.getAttribute("name"); if (workGroupName.startsWith("VIS")){ object.put("privileged","Yes"); object.setDisplayName(object.getAttribute("name")); object.setAttribute("description",(String)object.getAttribute("description")); return object ; }
Tuesday, October 12, 2021
Sailpoint IdentityIQ Group Aggregation Refresh Rule
Sailpoint IdentityIQ Group Aggregation Refresh Rule/GroupAggregationRefresh is used to set the value for the Entitlement from Target to the Entitlement Catalogue . Code is modified to take care of the update scenario also.
import sailpoint.object.ResourceObject; import sailpoint.object.ManagedAttribute; import sailpoint.object.Identity; int TIME_DIFFERENCE = 300000; // Five minutes Date modifiedDate = accountGroup.getModified(); Date createdDate = accountGroup.getCreated(); boolean entitlementCreated = false; if(createdDate!=null){ if(modifiedDate != null){ long difference = modifiedDate.getTime() - createdDate.getTime(); if(difference <= TIME_DIFFERENCE){ entitlementCreated = true; } } else { entitlementCreated = true; } } else { } if(entitlementCreated){ Map descMap = new HashMap(); String descriptionValue = accountGroup.getAttribute("description"); if(null != descriptionValue) descMap.put("en_US",descriptionValue); else descMap.put("en_US",""); accountGroup.setAttribute("sysDescriptions",descMap); } Map descMap = new HashMap(); String descriptionValue = accountGroup.getAttribute("description"); if(null != descriptionValue) descMap.put("en_US",descriptionValue); else descMap.put("en_US",""); accountGroup.setAttribute("sysDescriptions",descMap); String displayName = accountGroup.getAttribute("description"); accountGroup.setDisplayName(displayName); return accountGroup;
Friday, September 10, 2021
Creating a Request using RequestManager API in Sailpoint IdentityIQ
Creating a Request using RequestManager and Request Object , Here in below Example i have created a plan and then used the same plan to Generate the Request using RequestManager.
public void createSnowAppRequestObject(SailPointContext context,String identityName,String operation){ try { Date currentDate = new Date(); String flow = null; String caseName = null; ProvisioningPlan plan = new ProvisioningPlan(); switch(operation.toUpperCase()){ case "DISABLE": //Plan to disable Account plan = buildPlanForDisableSnowApps(context,identityName, operation); caseName = "VIS Disable ServiceNow Integrated Applications Event: " + identityName; flow = "UserDisableSnow"; break; case "DELETE": //Plan to delete Account plan = buildPlanForDisableSnowApps(context,identityName, operation); caseName = "VIS Delete ServiceNow Integrated Applications Event: " + identityName; flow = "UserDeleteSnow"; break; case "TERMINATE": //Plan to remove all the underlying Access & Disable Account plan = buildPlanForTerminateSnowApps(context,identityName); caseName = "VIS Terminate ServiceNow Integrated Applications Event: " + identityName; flow = "UserTerminateSnow"; break; default: break; } if(plan != null && !plan.isEmpty() && plan.getAccountRequests() != null ){ String workflowName = "LCM Provisioning"; Workflow workflow = context.getObject(Workflow.class, workflowName); //Creating attributes to be used in Request Object Attributes requestArguments = new Attributes(); requestArguments.put(sailpoint.workflow.StandardWorkflowHandler.ARG_REQUEST_DEFINITION, sailpoint.request.WorkflowRequestExecutor.DEFINITION_NAME); requestArguments.put(sailpoint.workflow.StandardWorkflowHandler.ARG_WORKFLOW, workflowName); requestArguments.put(sailpoint.workflow.StandardWorkflowHandler.ARG_REQUEST_NAME, caseName); requestArguments.put("requestName", caseName); Attributes workflowArguments = new Attributes(); workflowArguments.put("identityName", identityName); workflowArguments.put("notificationScheme", "none"); workflowArguments.put("approvalScheme", "none"); workflowArguments.put("flow", flow); workflowArguments.put("plan", plan); workflowArguments.put("workflow", workflow.getId()); requestArguments.putAll(workflowArguments); //Creating Request object for kicking off another workflow. Request requestObject = new Request(); RequestDefinition requestDefinition = context.getObject(RequestDefinition.class,"Workflow Request"); requestObject.setDefinition(requestDefinition); requestObject.setEventDate(currentDate); requestObject.setName(caseName); requestObject.setAttributes(requestDefinition, requestArguments); System.out.println("Request Object " + requestObject.toXml()); RequestManager.addRequest(context, requestObject); }else{ } } catch (Exception exception){ } } public ProvisioningPlan buildPlanForDisableSnowApps(SailPointContext context,String identityName, String operation) throws GeneralException{ Identity identity = (Identity)getObject(context,identityName,Identity.class); ProvisioningPlan plan = new ProvisioningPlan(); Filter filter = null; List objectPropertiesToFetch = new ArrayList(); Map objectPropertiesFetched = new HashMap(); objectPropertiesToFetch.add("type"); objectPropertiesToFetch.add("toDisable"); String VIS_SNOW_APPLICATION_TYPE = "DelimitedFile"; //Iterate through identity links to create a disable/delete account request for the same if (identity != null) { List<Link> links = identity.getLinks(); if (links != null && !links.isEmpty()) { plan.setIdentity(identity); plan.setNativeIdentity(identity.getName()); String applicationName = null; AccountRequest accountRequest = null; for (Link link : links) { applicationName = link.getApplicationName(); filter = Filter.eq("name", applicationName); objectPropertiesFetched = getObjectProperties(context,Application.class, filter, objectPropertiesToFetch); if ( VIS_SNOW_APPLICATION_TYPE.equalsIgnoreCase((String)objectPropertiesFetched.get("type")) && "true".equalsIgnoreCase((String)objectPropertiesFetched.get("toDisable"))){ accountRequest = new AccountRequest(); accountRequest.setNativeIdentity(link.getNativeIdentity()); accountRequest.setApplication(applicationName); if("Delete".equalsIgnoreCase(operation)){ accountRequest.setOperation(ProvisioningPlan.AccountRequest.Operation.Delete); }else if("Disable".equalsIgnoreCase(operation)){ accountRequest.setOperation(ProvisioningPlan.AccountRequest.Operation.Disable); } plan.add(accountRequest); } } } } return plan; } public ProvisioningPlan buildPlanForTerminateSnowApps(SailPointContext context,String identityName) throws GeneralException{ Identity identity = (Identity)getObject(context,identityName, Identity.class); ProvisioningPlan plan = new ProvisioningPlan(); List accountRequestList = new ArrayList(); List<Object> entitlementValuesList = new ArrayList(); Application application = null; Filter filter = null; Map objectPropertiesFetched = new HashMap(); List objectPropertiesToFetch = new ArrayList(); objectPropertiesToFetch.add("type"); objectPropertiesToFetch.add("toDisable"); String VIS_SNOW_APPLICATION_TYPE = "DelimitedFile"; if (identity != null) { List<Link> links = identity.getLinks(); if (links != null && !links.isEmpty()) { plan.setIdentity(identity); plan.setNativeIdentity(identity.getName()); plan.setIdentity(identity); plan.setNativeIdentity(identity.getName()); String applicationName = null; AccountRequest accountRequestDisable = null; AccountRequest accountRequestModify = null; AttributeRequest attributeRequest = null; String entitlementAttribute = null; for (Link link : links) { applicationName = link.getApplicationName(); filter = Filter.eq("name", applicationName); objectPropertiesFetched = getObjectProperties(context,Application.class, filter, objectPropertiesToFetch); if("true".equalsIgnoreCase((String) objectPropertiesFetched.get("toDisable")) && VIS_SNOW_APPLICATION_TYPE.equalsIgnoreCase((String) objectPropertiesFetched.get("type"))){ application = (Application)getObject(context,applicationName, Application.class); if(!application.getEntitlementAttributeNames().isEmpty() && application.getEntitlementAttributeNames() != null){ entitlementAttribute = application.getEntitlementAttributeNames().get(0); if( link.getAttribute(entitlementAttribute) instanceof String ){ entitlementValuesList = Arrays.asList( link.getAttribute(entitlementAttribute) ); }else if( link.getAttribute(entitlementAttribute) instanceof List ){ entitlementValuesList = (List) link.getAttribute(entitlementAttribute); } } accountRequestDisable = new AccountRequest(); accountRequestDisable.setNativeIdentity(link.getNativeIdentity()); accountRequestDisable.setApplication(applicationName); accountRequestDisable.setOperation(ProvisioningPlan.AccountRequest.Operation.Disable); accountRequestModify = new AccountRequest(); accountRequestModify.setNativeIdentity(link.getNativeIdentity()); accountRequestModify.setApplication(applicationName); accountRequestModify.setOperation(ProvisioningPlan.AccountRequest.Operation.Modify); for( Object entitlementName : Util.safeIterable(entitlementValuesList) ){ attributeRequest = new AttributeRequest(entitlementAttribute,ProvisioningPlan.Operation.Remove,entitlementName); attributeRequest.put("assignment","true"); accountRequestModify.add(attributeRequest); } plan.add(accountRequestModify); plan.add(accountRequestDisable); } } } } System.out.println(" Plan : " + plan.toXml()); return plan; } public Object getObject(SailPointContext context,String objectName , Class objectClass) throws GeneralException { String filterString = "name == \""+objectName+"\""; Filter filter = Filter.compile( filterString ); Object object = context.getUniqueObject( objectClass ,filter); return object; } public Map getObjectProperties(SailPointContext context,java.lang.Class objectType, Filter searchFilter, List propertiesToFetch) throws GeneralException{ Object[] objectProperties; Map propertiesMap = new HashMap(); QueryOptions queryOptions = new QueryOptions(); queryOptions.addFilter(searchFilter); Iterator iterator = context.search(objectType, queryOptions, propertiesToFetch); if(iterator.hasNext()){ objectProperties = (Object[]) iterator.next(); if (objectProperties != null ){ propertiesMap = propertyArrayToMap(objectProperties, propertiesToFetch); } } Util.flushIterator(iterator); return propertiesMap; } public Map propertyArrayToMap( Object[] objectProperties, List propertiesToFetch){ Map propertiesMap = new HashMap(); Iterator nameIterator = propertiesToFetch.iterator(); for(Object value : objectProperties) { propertiesMap.put(nameIterator.next(), value); } Util.flushIterator(nameIterator); return propertiesMap; }
Plan <?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE ProvisioningPlan PUBLIC "sailpoint.dtd" "sailpoint.dtd"> <ProvisioningPlan nativeIdentity="VKEJ"> <AccountRequest application="Revenue Process Management" nativeIdentity="VKEJ" op="Modify"> <AttributeRequest name="EntitlementName" op="Remove" value="Admin"> <Attributes> <Map> <entry key="assignment" value="true"/> </Map> </Attributes> </AttributeRequest> <AttributeRequest name="EntitlementName" op="Remove" value="Super Read only"> <Attributes> <Map> <entry key="assignment" value="true"/> </Map> </Attributes> </AttributeRequest> </AccountRequest> <AccountRequest application="Revenue Process Management" nativeIdentity="VKEJ" op="Disable"/> </ProvisioningPlan> Request <?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE Request PUBLIC "sailpoint.dtd" "sailpoint.dtd"> <Request name="VIS Terminate ServiceNow Integrated Applications Event: VKEJ" nextLaunch="1631314916907"> <Attributes> <Map> <entry key="approvalScheme" value="none"/> <entry key="flow" value="UserTerminateSnow"/> <entry key="identityName" value="VKEJ"/> <entry key="notificationScheme" value="none"/> <entry key="plan"> <value> <ProvisioningPlan nativeIdentity="VKEJ"> <AccountRequest application="Revenue Process Management" nativeIdentity="VKEJ" op="Modify"> <AttributeRequest name="EntitlementName" op="Remove" value="Admin"> <Attributes> <Map> <entry key="assignment" value="true"/> </Map> </Attributes> </AttributeRequest> <AttributeRequest name="EntitlementName" op="Remove" value="Super Read only"> <Attributes> <Map> <entry key="assignment" value="true"/> </Map> </Attributes> </AttributeRequest> </AccountRequest> <AccountRequest application="Revenue Process Management" nativeIdentity="VKEJ" op="Disable"/> </ProvisioningPlan> </value> </entry> <entry key="requestDefinition" value="Workflow Request"/> <entry key="requestName" value="VIS Terminate ServiceNow Integrated Applications Event: VKEJ"/> <entry key="workflow" value="8a88b862734df7fc01734df888580351"/> </Map> </Attributes> <Definition> <Reference class="sailpoint.object.RequestDefinition" id="8a88b862734df7fc01734df83e4b0175" name="Workflow Request"/> </Definition> </Request>
Sunday, August 1, 2021
Sailpoint IdentityIQ PolicyViolation WorkFlow
PolicyViolation WorkFlow , This WF is used to modify the violation object , This will remove the violation object and will remove if anything is added through LCM .
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE Workflow PUBLIC "sailpoint.dtd" "sailpoint.dtd"> <Workflow explicitTransitions="true" handler="sailpoint.api.StandardWorkflowHandler" name="VIS Detective SOD Policy Violation Workflow" type="PolicyViolation"> <Variable input="true" name="approvalObject"> <Description>PolicyViolation to process. Note that we use approvalObject for consistency with other workflows, but the violation has already been persisted. Calling the commit or rollback actions will have no effect.</Description> </Variable> <Variable input="true" name="approver"> <Description>The user to receive the work item, normally the owner of the policy.</Description> <Script> <Source> import sailpoint.object.Identity; Identity newOwner= approvalObject.getOwner(); return newOwner.getName(); </Source> </Script> </Variable> <Variable input="true" name="violator"> <Description>The identity that has the violation.</Description> </Variable> <Variable name="approved"> <Description>Internal variable automatically set logically true an Approval process completes with no rejects. </Description> </Variable> <Variable name="action"> <Description>Variable that may be set in the approval page to determine the action to take on this violation. We handle violation approvals differently than most work items. There is no &quot;reject&quot; there is a selection of an action (mitigate, remediate, delete, ignroe) followed by buttons that always post approval.</Description> </Variable> <Variable name="expiration"> <Description>Variable that must be set to a Date (or the String representation of a Date) in order to use the &quot;mitigate&quot; action. This will be tested in the call:mitigate handler and logged if it is invalid. You may wish to have the worklfow do it&#39;s own validation.</Description> </Variable> <Variable name="comments"> <Description>Variable that may be set to comments to be included with a mitigation or remediation.</Description> </Variable> <Variable name="remediatables"> <Description>Variable that may be set to a list of things that can be selected for remediation. Currently this will only be set for Role SOD violations.</Description> </Variable> <Variable name="remediations"> <Description>Variable holding the remediatables selected in the work item.</Description> </Variable> <RuleLibraries> <Reference class="sailpoint.object.Rule" name="Rule Library"/> </RuleLibraries> <Step icon="Default" name="Logs" posX="98" posY="126"> <Arg value="ref:remediatables"/> <Script> <Source> import java.util.Map; import java.util.Date; import java.util.List; import java.util.HashMap; import java.util.ArrayList; import sailpoint.tools.Util; import sailpoint.object.Filter; import sailpoint.api.ObjectUtil; import java.text.ParseException; import java.text.SimpleDateFormat; import sailpoint.object.Identity; import sailpoint.object.QueryOptions; import sailpoint.api.SailPointContext; import sailpoint.object.EmailOptions; import sailpoint.object.EmailTemplate; import sailpoint.object.PolicyViolation; import sailpoint.object.ManagedAttribute; import org.apache.commons.logging.Log; import sailpoint.tools.GeneralException; import sailpoint.object.IdentityEntitlement; import org.apache.commons.logging.LogFactory; import sailpoint.object.IdentitySelector.MatchTerm; Log logger = LogFactory.getLog("vis.workflow.visDetectiveSODPolicyViolationWorkflow"); public boolean checkIfThroughLCM(String applicationName, String identityName, String entitlementName) { boolean wasThroughLCM = false; StringBuilder result = new StringBuilder(); String sDate1 = "06/05/2021"; Date date = new SimpleDateFormat("MM/dd/yyyy").parse(sDate1); result.append("date [").append(date).append("]\n"); Filter dateCheckFilter = Filter.gt("created", date); logger.debug(" new Date dt : "+ sDate1 + " new date : " + result); QueryOptions qo = new QueryOptions(); qo.addFilter(Filter.and(Filter.eq("source","Aggregation"),Filter.eq("application.name",applicationName), Filter.eq("identity.name",identityName),Filter.eq("value",entitlementName),dateCheckFilter)); List identityEntitlements = context.getObjects(IdentityEntitlement.class, qo); logger.debug("identityEntitlements :: " + identityEntitlements); if(identityEntitlements.size() > 0) { return true; }else { return false; } } public Map getEntitlementDetails(String entitlementValue, String applicationName) { QueryOptions qo = new QueryOptions(); qo.addFilter(Filter.and(Filter.eq("value", entitlementValue) , Filter.eq("application.name", applicationName))); Map entDetailsMap = new HashMap(); List managedAttributes = context.getObjects(ManagedAttribute.class, qo); if(managedAttributes != null && managedAttributes.size() > 0) { ManagedAttribute managedAttribute = managedAttributes.get(0); entDetailsMap.put("LogiplexName", managedAttribute.getAttribute("logiplexAppName")); entDetailsMap.put("EntitlementDescription", managedAttribute.getDescriptions().get("en_US") ); } return entDetailsMap; } //Main code starts here logger.debug("Startes Main code here"); String piiMarkerGroup = "<<Left Group>>"; String notificationTemplateForPolicyViolation = "VIS Policy Violation Notification Template"; Identity violationOnwer = approvalObject.getOwner(); EmailTemplate violationTemplate = context.getObjectByName(EmailTemplate.class,notificationTemplateForPolicyViolation ); Map emailVariables = new HashMap(); String ownerEmails= Util.listToCsv(ObjectUtil.getEffectiveEmails(context,violationOnwer)); List entitlementsTobeAddedToViolation = new ArrayList(); List PIIEntitlementsToBeAddedToViolation = new ArrayList(); if (approvalObject != null && approvalObject.getArgument("ViolatingEntitlements") != null) { Identity identityWithViolation = approvalObject.getIdentity(); String firstName = identityWithViolation.getFirstname(); String lastName = identityWithViolation.getLastname(); String lanId = identityWithViolation.getAttribute("lanId"); String identityName = identityWithViolation.getAttribute("displayName"); emailVariables.put("firstName", firstName); emailVariables.put("lastName", lastName); emailVariables.put("lanId", lanId); emailVariables.put("identityName", identityName); for (int i = 0; i < approvalObject.getArgument("ViolatingEntitlements").size(); i++) { sailpoint.object.IdentitySelector.MatchTerm entitlementViolatingAtTop = approvalObject.getArgument("ViolatingEntitlements").get(i); if (entitlementViolatingAtTop != null) { String applicationNameForViolatingEntitlement = ""; String entitlementValueForViolatingEntitlement = ""; String accountNameForViolatingEntitlement=""; if(entitlementViolatingAtTop.getApplication() != null ){ applicationNameForViolatingEntitlement = entitlementViolatingAtTop.getApplication().getName(); accountNameForViolatingEntitlement= getAccountNmae(identityWithViolation, entitlementViolatingAtTop.getApplication()); } if(entitlementViolatingAtTop.getValue() != null) { entitlementValueForViolatingEntitlement = entitlementViolatingAtTop.getValue(); } if(entitlementValueForViolatingEntitlement.equalsIgnoreCase(piiMarkerGroup)) { PIIEntitlementsToBeAddedToViolation.add(entitlementViolatingAtTop); }else { boolean checkThruLCMmethodResult = checkIfThroughLCM(applicationNameForViolatingEntitlement, identityWithViolation.getName(), entitlementValueForViolatingEntitlement) ; logger.debug("CheckThruLCMmethodResult:: " + checkThruLCMmethodResult ); if( checkThruLCMmethodResult == true ) { entitlementsTobeAddedToViolation.add(entitlementViolatingAtTop); Map entDetails = getEntitlementDetails(entitlementValueForViolatingEntitlement, applicationNameForViolatingEntitlement); auditDetectiveSOD( "Violation Detected","Aggregation",lanId,entDetails.get("LogiplexName"),entitlementValueForViolatingEntitlement,accountNameForViolatingEntitlement,approvalObject,"Aggregation",lanId ); emailVariables.put("entitltmentName",entitlementValueForViolatingEntitlement); emailVariables.put("entitltmentDesc",entDetails.get("EntitlementDescription")); if(violationTemplate!= null){ logger.debug("Violation temp loop"); Identity policyViolationApproverObject = approvalObject.getOwner(); if(null!=policyViolationApproverObject && ( Util.listToCsv(ObjectUtil.getEffectiveEmails(context,policyViolationApproverObject)) != null)){ approverEmails = Util.listToCsv(ObjectUtil.getEffectiveEmails(context,policyViolationApproverObject)); EmailOptions ops = new EmailOptions(approverEmails, emailVariables); try { context.sendEmailNotification(violationTemplate, ops); }catch(Exception e){ log.error("Could not send email to GS team as : " + e); } logger.debug("Email Sent "); } } } } } } } if(entitlementsTobeAddedToViolation != null && entitlementsTobeAddedToViolation.size() >0){ entitlementsTobeAddedToViolation.addAll(PIIEntitlementsToBeAddedToViolation) ; approvalObject.setArgument("ViolatingEntitlements",entitlementsTobeAddedToViolation ); context.saveObject(approvalObject); context.commitTransaction(); logger.debug("OBJECT persisted"); }else{ context.removeObject(approvalObject); context.commitTransaction(); logger.debug("OBJECT DELETED"); } logger.debug("End of workflow Step"); </Source> </Script> <Transition to="End"/> </Step> <Step icon="Stop" name="End" posX="160" posY="126"/> <Step icon="Start" name="Start" posX="28" posY="10"> <Transition to="Logs"/> </Step> </Workflow>
Tuesday, July 20, 2021
Custom Report In Sailpoint IdentityIQ Using JavaDataSource
Custom Report In Sailpoint IdentityIQ Using JavaDataSource , This Report Will give the Deleage Set for the User between the Dates (Start and End Date)
Form
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE Form PUBLIC "sailpoint.dtd" "sailpoint.dtd"> <Form hidden="true" name="VIS Custom Delegate Identity Report Form" type="Report"> <Section columns="2" label="Request Parameters" name="customProperties"> <Field columnSpan="1" displayName="Forward Start Date" helpKey="rept_id_risk_help_last_login_start" name="forwardStartDate" type="date" value="ref:forwardStartDate"> <Attributes> <Map> <entry key="endDate" value="true"/> </Map> </Attributes> </Field> <Field columnSpan="1" displayName="Forward End Date" helpKey="rept_id_risk_help_last_login_end" name="forwardEndDate" type="date" value="ref:forwardEndDate"> <Attributes> <Map> <entry key="endDate" value="true"/> </Map> </Attributes> </Field> </Section> </Form>
TaskDefinition
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE TaskDefinition PUBLIC "sailpoint.dtd" "sailpoint.dtd"> <TaskDefinition executor="sailpoint.reporting.LiveReportExecutor" name="VIS Custom Delegate Identity Report" progressMode="String" resultAction="Delete" subType="Identity and User Reports" template="true" type="LiveReport"> <Attributes> <Map> <entry key="report"> <value> <LiveReport disablePreview="true" title="Identity Forwarding Report"> <DataSource dataSourceClass="com.vis.reports.ExperianCustomUserForwardingDataSource" type="Java"/> <ReportForm> <Reference class="sailpoint.object.Form" name="VIS Custom Delegate Identity Report Form"/> </ReportForm> <Columns> <ReportColumnConfig field="identity" header="rept_usr_forward_col_identity" sortable="true" width="110"/> <ReportColumnConfig field="displayName" header="rept_usr_forward_col_identity_display" sortable="true" width="110"/> <ReportColumnConfig field="identityFirstName" header="First Name" sortable="true" width="110"/> <ReportColumnConfig field="identityLastName" header="Last Name" sortable="true" width="110"/> <ReportColumnConfig field="identityEmpNumber" header="Employee Number" sortable="true" width="110"/> <ReportColumnConfig field="identityStatus" header="Employee Status" sortable="true" width="110"/> <ReportColumnConfig field="identityEmail" header="Email" sortable="true" width="110"/> <ReportColumnConfig field="forwardingUser" header="Delegate User" width="110"/> <ReportColumnConfig field="forwardingDisplayName" header="Delegate User Display Name" width="110"/> <ReportColumnConfig field="startDate" header="Delegate StartDate" width="110"/> <ReportColumnConfig field="endDate" header="Delegate EndDate" width="110"/> <ReportColumnConfig field="forwardingEmail" header="Delegate Email" property="name" width="110"/> <ReportColumnConfig field="forwardingEmpNumber" header="Delegate Employee Number" width="110"/> <ReportColumnConfig field="forwardingFirstName" header="Delegate First Name" width="110"/> <ReportColumnConfig field="forwardingLastName" header="Delegate Last Name" width="110"/> </Columns> </LiveReport> </value> </entry> </Map> </Attributes> <Description>A list of users who have forwarding configured and to which user.</Description> <RequiredRights> <Reference class="sailpoint.object.SPRight" name="FullAccessUserReport"/> </RequiredRights> <Signature> <Inputs> <Argument name="forwardStartDate" type="date"> <Description>delegation start date</Description> </Argument> <Argument name="forwardEndDate" type="date"> <Description>delegation end date</Description> </Argument> </Inputs> </Signature> </TaskDefinition>
Report JavaDataSource src code
package com.vis.reports; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRField; import sailpoint.api.SailPointContext; import sailpoint.object.Attributes; import sailpoint.object.Identity; import sailpoint.object.LiveReport; import sailpoint.object.QueryOptions; import sailpoint.object.Sort; import sailpoint.reporting.datasource.JavaDataSource; import sailpoint.task.Monitor; import sailpoint.tools.GeneralException; public class CustomUserForwardingDataSource implements JavaDataSource{ private Map<String, Object> currentRow; private QueryOptions baseQueryOptions; private SailPointContext context; private Map customQueryOptions = new HashMap(); private Integer startRow; private Integer pageSize; private Iterator<Map<String, Object>> finalobjects; private Map<String, Object> object = new HashMap<String, Object>(); private Iterator<Entry<String, Object>> mapIterator; private List<Map<String, Object>> objectList = new ArrayList<Map<String, Object>>(); Log logger = LogFactory.getLog("vis.task.CustomTask"); @SuppressWarnings("unchecked") public void initialize(SailPointContext context, LiveReport report,Attributes<String, Object> arguments, String groupBy, List<Sort> sort) throws GeneralException { logger.info("entered initialize method of CustomUserForwardingDataSource with :::arguments : "+arguments); this.context = context; baseQueryOptions = new QueryOptions(); try { SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-YYYY"); if(arguments.containsKey("forwardStartDate")) { String startDate= formatter.format(arguments.get("forwardStartDate")); customQueryOptions.put("forwardStartDate",startDate); logger.info("forwardStartDate------convert" +startDate); } if(arguments.containsKey("forwardEndDate")) { String endDate= formatter.format(arguments.get("forwardEndDate")); customQueryOptions.put("forwardEndDate",endDate); logger.info("forwardEndDate------convert" +endDate); } prepare(); } catch(Exception ex) { logger.info("Exception occured in initialize method CustomUserForwardingDataSource :::"); ex.printStackTrace(); logger.error(ex.getMessage()); } } private void prepare() throws GeneralException{ logger.info("Enter in method prepare() of CustomUserForwardingDataSsource Class::::"); Map<String, Object> itemMap = null; String sql; String forwardStartDate = ""; String forwardEndDate = ""; try { if(null != customQueryOptions.get("forwardStartDate")) { forwardStartDate = (String) customQueryOptions.get("forwardStartDate"); } if(null != customQueryOptions.get("forwardEndDate")) { forwardEndDate = (String)customQueryOptions.get("forwardEndDate"); } //SQL Query to fetch the delegated identity details with in date range. sql= "with A as(select name,display_name,EXTRACT(xmltype(preferences),'/Map/entry[@key=\"forward\"]/@value').getStringVal() as delegateduser,EXTRACT(xmltype(preferences),'/Map/entry[@key=\"forwardStartDate\"]/value/Date/text()').getStringVal() as forwardStartDate ,EXTRACT(xmltype(preferences),'/Map/entry[@key=\"forwardEndDate\"]/value/Date/text()').getStringVal() as forwardEndDate from spt_identity where preferences like ('%forward%'))" + "select A.name as identity,A.display_name as displayName,A.delegateduser as forwardingUser, A.forwardStartDate as startDate,A.forwardEndDate as endDate from A " + "where To_date('1970-01-01 00', 'yyyy-mm-dd hh24') + (A.forwardStartDate) / 1000 / 60 / 60 / 24 >=" + "'"+forwardStartDate+"'"+" and To_date('1970-01-01 00', 'yyyy-mm-dd hh24') + (A.forwardEndDate) / 1000 / 60 / 60 / 24<=" + "'"+forwardEndDate+"'"; logger.info("Sqlquery build---------"+sql); System.out.println("Sqlquery build---------"+sql); Connection connection = context.getJdbcConnection(); Statement stmt = connection.createStatement(); if (stmt == null){ throw new Exception("Unable to create stmt"); } ResultSet rs=stmt.executeQuery(sql); if (rs == null){ throw new Exception("Result set is null"); } ResultSetMetaData md = rs.getMetaData(); int columns = md.getColumnCount(); while (rs.next()){ itemMap = new HashMap<String, Object>(); for(int i=1; i<=columns; ++i){ itemMap.put(md.getColumnName(i),rs.getObject(i)); } mapIterator = itemMap.entrySet().iterator(); while(mapIterator.hasNext()) { Entry<String, Object> entry = mapIterator.next(); // logger.info("Item map entries::::"+entry.getKey() + ": " + entry.getValue()); } objectList.add(itemMap); } finalobjects = objectList.iterator(); }catch(Exception ex){ System.out.println("Error occured in prepare() method of CustomUserForwardingDataSsource Class:::"); ex.printStackTrace(); logger.error(ex.getMessage()); } } public Object getFieldValue(String fieldName) throws GeneralException { logger.info("Enter into getFieldValue() method of CustomUserForwardingDataSsource Class:::");; Identity identity = this.context.getObjectByName(Identity.class, (String)this.object.get("IDENTITY")); Identity delegateId = this.context.getObjectByName(Identity.class, (String)this.object.get("FORWARDINGUSER")); SimpleDateFormat formatteddate = new SimpleDateFormat("MM/dd/yyyy"); if(fieldName.equals("identity")) { return this.object.get("IDENTITY"); }else if(fieldName.equals("displayName")) { return this.object.get("DISPLAYNAME"); }else if(fieldName.equals("identityFirstName")) { return identity.getFirstname(); }else if(fieldName.equals("identityLastName")) { return identity.getLastname(); }else if(fieldName.equals("identityEmpNumber")) { return identity.getAttribute("employeeNumber"); }else if(fieldName.equals("identityStatus")) { return identity.getAttribute("employeeStatus"); }else if(fieldName.equals("identityEmail")) { return identity.getEmail(); }else if(fieldName.equals("forwardingUser")) { return this.object.get("FORWARDINGUSER"); }else if(fieldName.equals("startDate")) { Date d = new Date(); if(this.object.get("STARTDATE") != null) { long milliSeconds= Long.parseLong((String) this.object.get("STARTDATE")); d.setTime(milliSeconds); String startDate = formatteddate.format(d); return startDate; } return ""; } else if(fieldName.equals("endDate")) { Date d = new Date(); if(this.object.get("ENDDATE") != null) { long milliSeconds= Long.parseLong((String) this.object.get("ENDDATE")); d.setTime(milliSeconds); String endDate = formatteddate.format(d); return endDate; } return ""; }else if(fieldName.equals("forwardingEmail")) { return delegateId.getEmail(); } else if(fieldName.equals("forwardingEmpNumber")) { return delegateId.getAttribute("employeeNumber"); }else if(fieldName.equals("forwardingFirstName")) { return delegateId.getFirstname(); } else if(fieldName.equals("forwardingLastName")) { return delegateId.getLastname(); }else if(fieldName.equals("forwardingDisplayName")) { return delegateId.getDisplayName(); } else { throw new GeneralException("Unknown column '" + fieldName + "'"); } } public int getSizeEstimate() throws GeneralException { // TODO Auto-generated method stub return 0; } @Override public void close() { // TODO Auto-generated method stub } @Override public void setMonitor(Monitor arg0) { // TODO Auto-generated method stub } public Object getFieldValue(JRField jrField) throws JRException { String fieldName = jrField.getName(); try { return getFieldValue(fieldName); } catch (GeneralException e) { throw new JRException(e); } } public boolean next() throws JRException { boolean hasMore = false; if (this.finalobjects != null) { hasMore = this.finalobjects.hasNext(); if (hasMore) { this.object = this.finalobjects.next(); } else { this.object = null; } } return hasMore; } @Override public void setLimit(int startRow, int pageSize) { this.startRow = startRow; this.pageSize = pageSize; } @Override public String getBaseHql() { // TODO Auto-generated method stub return null; } @Override public QueryOptions getBaseQueryOptions() { return baseQueryOptions; } }