Problem:
We cannot work out why our Identity is only moving into Disabled the day after the endDate, from Workday. The Identity should move into Disabled on the same day, at 7pm as per the LCS rule below. However it was only moved to Disabled at 8am the next day. Manual processing of the Identity had occurred at 7pm, 8pm, 9pm, 10pm and 12am and it Identity still stayed in Active07.
SOT Connector:
Workday
Timezone on connector: UTC (we don’t believe this needs to be changed because the date format received is in date format as a string?)
/\*
\* This method will return the AD request object from the provisioning plan
\*/
public AccountRequest getADAccountRequest(ProvisioningPlan plan)
{
log.info("Entering Active Directory BeforeProvisioning Rule : getADAccountRequest method");
AccountRequest adAccntRequest = null;
String applicationName = application.getName();
if (null != plan)
{
List accReq = plan.getAccountRequests();
if (null != accReq && !accReq.isEmpty())
{
for (AccountRequest accountReq : accReq)
{
if (null != accountReq)
{
String appName = accountReq.getApplication();
if (null != appName && appName.startsWith(applicationName))
{
adAccntRequest = new AccountRequest();
adAccntRequest = accountReq;
break;
}
}
}
}
}
log.info("Exiting Active Directory BeforeProvisioning Rule : getADAccountRequest method");
return adAccntRequest;
}
/\*
\* This method will return all the existing access / Entitlement details for the AD account of the user
\*/
public List getGroupsFromADAccount(AccountRequest adAccntRequest)
{
log.info("Entering Active Directory BeforeProvisioning Rule : getGroupsFromADAccount method");
List existingGroups = new ArrayList();
Object adGroup = null;
String appName = application.getName();
if (null != adAccntRequest && null != appName)
{
String nativeIdentity = adAccntRequest.getNativeIdentity();
if (null != nativeIdentity)
{
adGroup = idn.getRawAccountAttribute(appName, nativeIdentity, "memberOf");
if (null != adGroup)
{
if (adGroup instanceof String)
{
existingGroups.add(adGroup);
} else if (adGroup instanceof List)
{
existingGroups.addAll(adGroup);
}
}
}
}
log.info("Exiting Active Directory BeforeProvisioning Rule : getGroupsFromADAccount method");
return existingGroups;
}
/\*
\* This method create attribute request to revoke all the existing access from the user AD account
\*/
public AccountRequest removeGroups(AccountRequest adAccountRequest, List existingGroups)
{
log.info("Entering Active Directory BeforeProvisioning Rule : removeGroups method");
if (null != adAccountRequest && null != existingGroups && !existingGroups.isEmpty())
{
for (String group : existingGroups)
{
if (null != group && !group.startsWith("CN=Domain Users"))
{
AttributeRequest removeAccess = new AttributeRequest("memberOf", ProvisioningPlan.Operation.Remove, group);
adAccountRequest.add(removeAccess);
}
}
}
log.info("Exiting Active Directory BeforeProvisioning Rule :removeGroups method");
return adAccountRequest;
}
log.info("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Entering Active Directory Before Provisioning rule \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*");
if (plan != null)
{
// TODO replace with prod domain user group e.g "CN=Domain
// Users,CN=Users,DC=GMHBA,DC=GEELONG"
String domainGroup = "CN=Domain Users,CN=Users,DC=GMHBA,DC=GEELONG";
AccountRequest adAccountRequest = getADAccountRequest(plan);
Identity identity = plan.getIdentity();
if (adAccountRequest != null && identity != null)
{
AccountRequest.Operation op = adAccountRequest.getOperation();
// Getting user LCS stage value
String lifecycleState = (String) identity.getAttribute("cloudLifecycleState");
// to support rehire use case
String enabledOU = (String) identity.getAttribute("adUserOu");
log.debug("Account Request Operation :" + op);
log.debug("User life cycle State :" + lifecycleState);
if (op != null && Util.isNotNullOrEmpty(lifecycleState))
{
if (null != adAccountRequest && (adAccountRequest.getOperation().equals(ProvisioningPlan.AccountRequest.Operation.Enable)))
{
if ("active".equalsIgnoreCase(lifecycleState))
{
if (Util.isNotNullOrEmpty(enabledOU))
{
AttributeRequest enableAttrRequest = new AttributeRequest("AC_NewParent", ProvisioningPlan.Operation.Set, enabledOU);
adAccountRequest.add(enableAttrRequest);
}
} else if ("deprovisioned".equalsIgnoreCase(lifecycleState))
{
// if user sits in deprovisioned state, and
// operation is enabled,firstly we need to set op to
// disable then we set user's group to base domain
// group so
// that other groups can be removed
// Retrieving all the assigned AD groups from the
// user account
List existingGroups = getGroupsFromADAccount(adAccountRequest);
// Remove all groups but leave Domain Users
if (null != existingGroups && !existingGroups.isEmpty())
{
adAccountRequest = removeGroups(adAccountRequest, existingGroups);
}
} else if ("inactive".equalsIgnoreCase(lifecycleState))
{
log.debug("deleting user account OU, user is inactive");
// Delete account
adAccountRequest.setOperation(AccountRequest.Operation.Delete);
} else
log.debug("No additional changes in plan required");
}
} else
{
log.info("LCS value is invalid or null");
}
}
} else
{
log.warn("Plan is null or empty");
}
log.info("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Exiting Active Directory Before Provisioning rule \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*");
The before provisioning rule looks good but did you check if the LCS is set to deprovision at the correct date? Can you share the transform/rule you are using to set the lifecycle state?
In my experience, the workday connector changes the status of the account 1 day after the end date, so you’ll have to specifically handle the lifecycle state change on end date.
Is it possible that in the LCS rule, it’s converting the date format, string type field to Gregorian calendar which is in UTC even though our tenancy is in Australia/Melbourne?
Could this be why the LCS is only changed at 8am the next day for Disabled?
Is: Date today = new Date(); returning UTC time because of the server where the rule runs from isn’t from our tenancy/cloud service but a different shared service which is running on UTC time?
irrespective of where the java code of your rule is executed, new Date() always returns UTC time. You will have to change it to your time zone adding the required number of hours for which you can use the addHours() function that you already have in the rule