Please be sure you’ve read the docs and API specs before asking for help. Also, please be sure you’ve searched the forum for your answer before you create a new topic.
Hi,
I’ve implemented a custom AttributeGenerator rule to generate a uniquesAMAccountName
for AD accounts.
Logic:
- Username = first letter of
preferredName
+ first letter oflastname
+ start date (MMyy
) + suffix (a
–z
). - Example: John Doe, start date
2023-10-15
→ base username =JD1023
. - Expected:
JD1023a
,JD1023b
,JD1023c
, etc.
Issue:
- First account generates
JD1023a
correctly. - On duplicate, it still returns
JD1023a
instead of incrementing tob
,c
, etc.
Rule:
/* Rule to generate a unique username for Active Directory.
The username is generated using the first letter of preferredName, first letter of lastname,
the start date in mmyy format, and a suffix letter from 'a' to 'z' to ensure uniqueness.
For example, for preferredName "John", lastname "Doe", and startDate "2023-10-15",
the base username would be "JD1023". The rule will then try "JD1023a", "JD1023b", etc.,
until it finds a unique username. */
import sailpoint.tools.GeneralException;
import sailpoint.object.Application;
import sailpoint.object.Field;
import sailpoint.object.Identity;
import sailpoint.server.IdnRuleUtil;
import sailpoint.api.*;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import java.text.Normalizer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.PatternSyntaxException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public String generateUsername(String preferredName, String lastname, String startDate) throws GeneralException {
preferredName = cleanAlphaNumeric(StringUtils.trimToNull(preferredName));
lastname = cleanAlphaNumeric(StringUtils.trimToNull(lastname));
startDate = StringUtils.trimToNull(startDate);
if(preferredName == null || lastname == null || startDate == null) {
throw new GeneralException("Invalid input: preferredName" + preferredName + ", lastname" + lastname + ", and startDate" + startDate + "cannot all be null.");
}
String preferredNamefirstLetter = preferredName.substring(0, 1);
String lastnamefirstLetter = lastname.substring(0, 1);
String dateFormatmmyy = extractDateFormat(startDate);
String baseUsername = preferredNamefirstLetter + lastnamefirstLetter + dateFormatmmyy;
for (char suffix = 'a'; suffix <= 'z'; suffix++) {
String username = baseUsername + suffix;
if (isUnique(username)) {
log.debug("GSB AD Unique sAMAccountName generated: " + username);
return username;
}
}
throw new GeneralException("Unable to generate a unique username after trying all suffixes.");
}
public String cleanAlphaNumeric(String input) {
if (input == null) {
return null;
}
String cleanedInput = input.replaceAll("[^a-zA-Z0-9]", "");
return cleanedInput.length() > 0 ? cleanedInput : null;
}
public String extractDateFormat(String date) throws GeneralException {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date parsedDate = sdf.parse(date);
SimpleDateFormat outputFormat = new SimpleDateFormat("MMyy");
return outputFormat.format(parsedDate);
} catch (ParseException e) {
throw new GeneralException("Invalid date format: " + date, e);
}
}
public boolean isUnique(String username) throws GeneralException {
List sourceIds = Collections.singletonList(application.getId());
List searchValues = Collections.singletonList(username);
int count = idn.attrSearchCountAccounts(sourceIds, "sAMAccountName", "Equals", searchValues);
log.debug("GSB AD sAMAccountName uniqueness check for '" + username + "': found " + count + " existing accounts.");
return count == 0;
}
return generateUsername(identity.getAttribute("preferredName"), identity.getAttribute("lastname"), identity.getAttribute("startDate"));
Has anyone else run into this? Am I using attrSearchCountAccounts
incorrectly, or is there another recommended way to ensure suffix increments properly?