public void addUser(String userName, Object credential, String[] roleList,
Map<String, String> claims, String profileName,
boolean requirePasswordChange) throws UserStoreException {
if (!checkUserNameValid(userName)) {
throw new UserStoreException(
"User name not valid. User name must be a non null string with following format, " +
realmConfig.getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_USER_NAME_JAVA_REG_EX));
}
if (!checkUserPasswordValid(credential)) {
throw new UserStoreException(
"Credential not valid. Credential must be a non null string with following format, " +
realmConfig.getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_JAVA_REG_EX));
}
DirContext mainDirContext = this.connectionSource.getContext();
DirContext dirContext = null;
String searchBase = realmConfig.getUserStoreProperty(LDAPConstants.USER_SEARCH_BASE);
try {
dirContext = (DirContext) mainDirContext.lookup(searchBase);
//above this the search base or base directory for this storage. we assume users
// are stored under ou=users folder here
BasicAttributes basicAttributes = new BasicAttributes(true);
//read the object class for saving user entries in LDAP.
String userObjectClass = realmConfig.getUserStoreProperty(
LDAPConstants.USER_ENTRY_OBJECT_CLASS);
// set the objectClass type for schema
BasicAttribute objectClass = new BasicAttribute(LDAPConstants.OBJECT_CLASS_NAME);
objectClass.add(userObjectClass);
//If KDC is enabled we have to set KDC specific object classes also
if (isKdcEnabled()) {
// Add Kerberos specific object classes
objectClass.add("krb5principal");
objectClass.add("krb5kdcentry");
objectClass.add("subschema");
}
basicAttributes.put(objectClass);
BasicAttribute uid = new BasicAttribute("uid");
uid.add(userName);
basicAttributes.put(uid);
if (isKdcEnabled()) {
String principal = userName + "@" + this.getRealmName();
BasicAttribute principalAttribute = new BasicAttribute(KRB5_PRINCIPAL_NAME_ATTRIBUTE);
principalAttribute.add(principal);
basicAttributes.put(principalAttribute);
BasicAttribute versionNumberAttribute = new BasicAttribute(KRB5_KEY_VERSION_NUMBER_ATTRIBUTE);
versionNumberAttribute.add("0");
basicAttributes.put(versionNumberAttribute);
}
BasicAttribute userPassword = new BasicAttribute("userPassword");
userPassword.add(getPasswordToStore((String) credential,
this.realmConfig.getUserStoreProperty(
PASSWORD_HASH_METHOD)));
basicAttributes.put(userPassword);
BasicAttribute claim;
/*we keep boolean values to know whether compulsory attributes 'sn' and 'cn' are set
during setting claims.*/
boolean isSNExists = false;
boolean isCNExists = false;
for (Map.Entry<String, String> entry : claims.entrySet()) {
/*LDAP does not allow for empty values. If an attribute has a value it’s stored
with the entry, otherwise it is not. Hence needs to check for empty values before
storing the attribute.*/
if (EMPTY_ATTRIBUTE_STRING.equals(entry.getValue())) {
continue;
}
//needs to get attribute name from claim mapping
String claimURI = entry.getKey();
ClaimMapping claimMapping = null;
claimMapping = (ClaimMapping) claimManager.getClaimMapping(claimURI);
String attributeName = null;
if (claimMapping != null) {
attributeName = claimMapping.getMappedAttribute();
if (ATTR_NAME_CN.equals(attributeName)) {
isCNExists = true;
} else if (ATTR_NAME_SN.equals(attributeName)) {
isSNExists = true;
}
} else {
attributeName = claimURI;
}
claim = new BasicAttribute(attributeName);
claim.add(claims.get(entry.getKey()));
basicAttributes.put(claim);
}
//following attribute is not added to attributes. May be it could be removed.
BasicAttribute isChangePassword = new BasicAttribute("requirePasswordChange");
isChangePassword.add(requirePasswordChange);
// If required attributes cn, sn are not set during claim mapping, set them as user names
if (!isCNExists) {
BasicAttribute cn = new BasicAttribute("cn");
cn.add(userName);
basicAttributes.put(cn);
}
if (!isSNExists) {
BasicAttribute sn = new BasicAttribute("sn");
sn.add(userName);
basicAttributes.put(sn);
}
dirContext.bind("uid=" + userName, null, basicAttributes);
if ((roleList != null) || (roleList.length != 0)) {
//add user to role according to the group configuration in user-mgt.xml
for (String role : roleList) {
if (("true".equals(READ_LDAP_USER_GROUPS)) &&
("true".equals(WRITE_LDAP_USER_GROUPS))) {
if (!isInternalRole(role)) {
this.updateRoleListOfUser(userName, new String[]{}, new String[]{role});
} else if (isInternalRole(role)) {
this.hybridRoleManager.addHybridRole(role, new String[]{userName});
}
}
if (("false".equals(READ_LDAP_USER_GROUPS)) &&
("false".equals(WRITE_LDAP_USER_GROUPS))
|| (("true".equals(READ_LDAP_USER_GROUPS)) &&
("false".equals(WRITE_LDAP_USER_GROUPS)))) {
this.hybridRoleManager.addHybridRole(role, new String[]{userName});
}
}
}
} catch (NamingException e) {
String errorMessage = "Can not access the directory context or" +
"user already exists in the system";
logger.error(errorMessage, e);
throw new UserStoreException(errorMessage, e);
} catch (org.wso2.carbon.user.api.UserStoreException e) {
String errorMessage = "Error in obtaining claim mapping.";
logger.error(errorMessage, e);
throw new UserStoreException(errorMessage, e);
} finally {
JNDIUtil.closeContext(dirContext);
JNDIUtil.closeContext(mainDirContext);
}
}