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 &amp;quot;reject&amp;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 &amp;quot;mitigate&amp;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&amp;#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 &amp;&amp; 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 &amp;&amp; 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 &lt; 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 &amp;&amp; ( 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 &amp;&amp; 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>