In a recent implementation, my team started with the SailPoint Services Standard Before Provisioning Rule and updated the “moveADAccount” method to add a uniqueness check that just adds incrementing numbers to the CN:
public void moveADAccount(Identity identity, AccountRequest accountRequest, Object value) {
log.debug("Enter MoveADAccount: " + value);
if(accountRequest == null) {
log.error("MoveADAccount: Invalid Arguments: accountRequest is null");
return;
}
if(value instanceof String) {
log.debug("MoveADAccount: value is a string, send through replace");
String newOU = replaceIdentityValue(identity, accountRequest, (String) value);
log.info("MoveADAccount: replaced new value: " + newOU);
String currentNativeIdentity = accountRequest.getNativeIdentity();
if(currentNativeIdentity == null) {
log.error("moveADAccount: Invalid State: Current Native Identity is null");
return;
}
if(newOU == null || "".equals(newOU)) {
log.error("moveADAccount: Invalid Arguments: newOU is null");
return;
}
int indexOfCurrentOU = currentNativeIdentity.indexOf(newOU);
if(indexOfCurrentOU > 0 && !currentNativeIdentity.substring(0, indexOfCurrentOU).contains("OU=")) {
log.info("moveADAccount: Account already lives in OU");
return;
}
//TODO: Uniqueness checks and serialization
//*************************************************************
//************ Customer SPECIFIC CODE - BEGIN ************
//*************************************************************
//apply unique check and collision logic for CN
String appName = accountRequest.getApplicationName();
String origCN = currentNativeIdentity.substring(3, (currentNativeIdentity.indexOf(",")));
String baseCN = origCN.replaceAll("\\\\d","");
String newCN = baseCN;
String newDN;
log.info("Customer standard BP Rule: starting Customer custom code to handle CN collision for application: " + appName);
boolean userExists = true;
int maxUniqueCheck = 20; //run thru 20 iterations which is probably overkill
int i;
for (i=1; i < maxUniqueCheck; i++){
log.info("Customer standard BP Rule: check for uniquenss of CN value in new OU: " + newCN);
newDN = "CN=".concat(newCN).concat(",").concat(newOU);
if(!(idn.accountExistsByNativeIdentity(appName, newDN))) {
log.info("Customer standard BP Rule: CN is unique in new OU, now need to determine if it is necessary to call AC_NewName");
userExists = false;
break;
}
newCN = baseCN.concat(String.valueOf(i));
}
if(userExists){
log.error("Customer standard BP Rule: moveADAccount: Unique CN could not be derived");
return;
}
if (!origCN.equals(newCN)) {
newCN = "CN=".concat(newCN);
log.info("Customer standard BP Rule: AC_NewName will be executed using: " + newCN);
accountRequest.add(new AttributeRequest("AC_NewName", ProvisioningPlan.Operation.Set, newCN));
log.info("Customer standard BP Rule: adding AttributeRequest to execute AC_NewName, resulting DN will be: " + newDN);
}
//*************************************************************
//************ Customer SPECIFIC CODE - END **************
//*************************************************************
accountRequest.add(new AttributeRequest("AC_NewParent", ProvisioningPlan.Operation.Set, newOU));
}
else{
log.error("MoveADAccount: value is not a string or is null: " + value);
}
log.debug("Exit MoveADAccount");
}