Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class XUserInfo {
private String id;
private String name;
private String firstName;
private String lastName;
private String description;
private String otherAttributes;
private String syncSource;
Expand Down Expand Up @@ -58,6 +59,10 @@ public void setName(String name) {

public void setFirstName(String firstName) { this.firstName = firstName; }

public String getLastName() { return lastName; }

public void setLastName(String lastName) { this.lastName = lastName; }

public String getDescription() {
return description;
}
Expand Down Expand Up @@ -140,7 +145,8 @@ public void setOtherAttributes(String otherAttributes) {

@Override
public String toString() {
return "XUserInfo [id=" + id + ", name=" + name + ", firstName=" + firstName + ", description="
return "XUserInfo [id=" + id + ", name=" + name + ", firstName=" + firstName
+ ", lastName=" + lastName + ", description="
+ description + ", groupNameList=" + groupNameList
+ ", userRoleList=" + userRoleList + "]";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ public class UgsyncCommonConstants {
public static final String FULL_NAME = "full_name";
public static final String SYNC_SOURCE = "sync_source";
public static final String LDAP_URL = "ldap_url";
public static final String FIRST_NAME = "first_name";
public static final String LAST_NAME = "last_name";

}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ public class LdapUserGroupBuilder implements UserGroupSource {

private String[] userSearchBase;
private String userNameAttribute;
private String userFirstNameAttribute;
private String userLastNameAttribute;
private String userCloudIdAttribute;
private int userSearchScope;
private String userObjectClass;
Expand Down Expand Up @@ -232,10 +234,14 @@ private void setConfig() throws Throwable {
userObjectClass = config.getUserObjectClass();
userSearchFilter = config.getUserSearchFilter();
userNameAttribute = config.getUserNameAttribute();
userFirstNameAttribute = config.getUserFirstNameAttribute();
userLastNameAttribute = config.getUserLastNameAttribute();
userCloudIdAttribute = config.getUserCloudIdAttribute();

Set<String> userSearchAttributes = new HashSet<String>();
userSearchAttributes.add(userNameAttribute);
userSearchAttributes.add(userFirstNameAttribute);
userSearchAttributes.add(userLastNameAttribute);
userGroupNameAttributeSet = config.getUserGroupNameAttributeSet();
for (String useGroupNameAttribute : userGroupNameAttributeSet) {
userSearchAttributes.add(useGroupNameAttribute);
Expand Down Expand Up @@ -319,6 +325,8 @@ private void setConfig() throws Throwable {
+ ", userSearchFilter: " + userSearchFilter
+ ", extendedUserSearchFilter: " + extendedUserSearchFilter
+ ", userNameAttribute: " + userNameAttribute
+ ", userFirstNameAttribute: " + userFirstNameAttribute
+ ", userLastNameAttribute: " + userLastNameAttribute
+ ", userSearchAttributes: " + userSearchAttributes
+ ", userGroupNameAttributeSet: " + userGroupNameAttributeSet
+ ", otherUserAttributes: " + otherUserAttributes
Expand Down Expand Up @@ -578,6 +586,8 @@ private long getUsers(boolean computeDeletes) throws Throwable {
userAttrMap.put(UgsyncCommonConstants.FULL_NAME, userFullName);
userAttrMap.put(UgsyncCommonConstants.SYNC_SOURCE, currentSyncSource);
userAttrMap.put(UgsyncCommonConstants.LDAP_URL, config.getLdapUrl());
addNameAttrToMap(attributes, userFirstNameAttribute, UgsyncCommonConstants.FIRST_NAME, userAttrMap);
addNameAttrToMap(attributes, userLastNameAttribute, UgsyncCommonConstants.LAST_NAME, userAttrMap);
Attribute userCloudIdAttr = attributes.get(userCloudIdAttribute);
if (userCloudIdAttr != null) {
addToAttrMap(userAttrMap, "cloud_id", userCloudIdAttr, config.getUserCloudIdAttributeDataType());
Expand Down Expand Up @@ -1056,6 +1066,24 @@ private void goUpGroupHierarchyLdap(Set<String> groupDNs, int groupHierarchyLeve
goUpGroupHierarchyLdap(nextLevelGroups, groupHierarchyLevels-1);
}

private void addNameAttrToMap(Attributes attributes, String ldapAttrName, String mapKey, Map<String, String> userAttrMap) throws NamingException {
if (StringUtils.isEmpty(ldapAttrName) || attributes == null) {
return;
}
Attribute attr = attributes.get(ldapAttrName);
if (attr == null) {
return;
}
Object val = attr.get();
if (val == null) {
return;
}
String strVal = val.toString().trim();
if (!strVal.isEmpty()) {
userAttrMap.put(mapKey, strVal);
}
}

private void addToAttrMap(Map<String, String> userAttrMap, String attrName, Attribute attr, String attrType) throws Throwable{
if (attrType.equals(DATA_TYPE_BYTEARRAY)) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ public class UserGroupSyncConfig {
private static final String LGSYNC_USER_NAME_ATTRIBUTE = "ranger.usersync.ldap.user.nameattribute";
private static final String DEFAULT_USER_NAME_ATTRIBUTE = "cn";

private static final String LGSYNC_USER_FIRST_NAME_ATTRIBUTE = "ranger.usersync.ldap.user.firstnameattribute";
private static final String DEFAULT_USER_FIRST_NAME_ATTRIBUTE = "givenName";

private static final String LGSYNC_USER_LAST_NAME_ATTRIBUTE = "ranger.usersync.ldap.user.lastnameattribute";
private static final String DEFAULT_USER_LAST_NAME_ATTRIBUTE = "sn";

private static final String LGSYNC_USER_GROUP_NAME_ATTRIBUTE = "ranger.usersync.ldap.user.groupnameattribute";
private static final String DEFAULT_USER_GROUP_NAME_ATTRIBUTE = "memberof,ismemberof";

Expand Down Expand Up @@ -707,6 +713,22 @@ public String getUserNameAttribute() {
return val;
}

public String getUserFirstNameAttribute() {
String val = prop.getProperty(LGSYNC_USER_FIRST_NAME_ATTRIBUTE);
if (val == null || val.trim().isEmpty()) {
return DEFAULT_USER_FIRST_NAME_ATTRIBUTE;
}
return val.trim();
}

public String getUserLastNameAttribute() {
String val = prop.getProperty(LGSYNC_USER_LAST_NAME_ATTRIBUTE);
if (val == null || val.trim().isEmpty()) {
return DEFAULT_USER_LAST_NAME_ATTRIBUTE;
}
return val.trim();
}

public String getUserGroupNameAttribute() {
String val = prop.getProperty(LGSYNC_USER_GROUP_NAME_ATTRIBUTE);
if(val == null || val.trim().isEmpty()) {
Expand Down Expand Up @@ -1248,6 +1270,16 @@ public void setUserNameAttribute(String userNameAttr) {
prop.setProperty(LGSYNC_USER_NAME_ATTRIBUTE, userNameAttr);
}

/* Used only for unit testing */
public void setUserFirstNameAttribute(String userFirstNameAttr) {
prop.setProperty(LGSYNC_USER_FIRST_NAME_ATTRIBUTE, userFirstNameAttr);
}

/* Used only for unit testing */
public void setUserLastNameAttribute(String userLastNameAttr) {
prop.setProperty(LGSYNC_USER_LAST_NAME_ATTRIBUTE, userLastNameAttr);
}

/* Used only for unit testing */
public void setGroupHierarchyLevel(int groupHierarchyLevel) {
prop.setProperty(LGSYNC_GROUP_HIERARCHY_LEVELS, String.valueOf(groupHierarchyLevel));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,16 @@ private <T> T setOtherAttributes(T uginfo, String syncSource, Map<String, String
xUserInfo.setSyncSource(syncSource);
xUserInfo.setOtherAttrsMap(otherAttrsMap);
xUserInfo.setOtherAttributes(otherAttributes);
if (otherAttrsMap != null) {
String firstName = otherAttrsMap.get(UgsyncCommonConstants.FIRST_NAME);
if (StringUtils.isNotBlank(firstName)) {
xUserInfo.setFirstName(firstName);
}
String lastName = otherAttrsMap.get(UgsyncCommonConstants.LAST_NAME);
if (StringUtils.isNotBlank(lastName)) {
xUserInfo.setLastName(lastName);
}
}
return ((T) xUserInfo);
} else if (uginfo instanceof XGroupInfo ){
XGroupInfo xGroupInfo = ((XGroupInfo) uginfo);
Expand Down Expand Up @@ -909,7 +919,12 @@ private List<GroupUserInfo> computeGroupUsersDelta(Map<String, Set<String>> sour
private XUserInfo addXUserInfo(String aUserName, Map<String, String> otherAttrsMap, String otherAttributes) {
XUserInfo xuserInfo = new XUserInfo();
xuserInfo.setName(aUserName);
xuserInfo.setFirstName(aUserName);
String firstName = otherAttrsMap != null ? otherAttrsMap.get(UgsyncCommonConstants.FIRST_NAME) : null;
String lastName = otherAttrsMap != null ? otherAttrsMap.get(UgsyncCommonConstants.LAST_NAME) : null;
xuserInfo.setFirstName(StringUtils.isNotBlank(firstName) ? firstName : aUserName);
if (StringUtils.isNotBlank(lastName)) {
xuserInfo.setLastName(lastName);
}
xuserInfo.setDescription(aUserName + " - add from Unix box");
xuserInfo.setUserSource(SOURCE_EXTERNAL);
xuserInfo.setStatus(STATUS_ENABLED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class PolicyMgrUserGroupBuilderTest extends PolicyMgrUserGroupBuilder {
private Map<String, Set<String>> groupUsers;
private Set<String> invalidGroups;
private Set<String> invalidUsers;
private Map<String, Map<String, String>> userAttrsByName;

public PolicyMgrUserGroupBuilderTest() {
super();
Expand All @@ -44,6 +45,11 @@ public void init() throws Throwable {
groupUsers = new HashMap<>();
invalidGroups = new HashSet<>();
invalidUsers = new HashSet<>();
userAttrsByName = new HashMap<>();
}

public Map<String, String> getUserAttrs(String username) {
return userAttrsByName.get(username);
}

public int getTotalUsers() {
Expand Down Expand Up @@ -97,8 +103,10 @@ public void addOrUpdateUsersGroups(Map<String, Map<String, String>> sourceGroups

for (String userdn : sourceUsers.keySet()) {
//System.out.println("Username: " + sourceUsers.get(userdn).get("original_name"));
String username = userNameTransform(sourceUsers.get(userdn).get("original_name"));
Map<String, String> userAttrs = sourceUsers.get(userdn);
String username = userNameTransform(userAttrs.get("original_name"));
allUsers.add(username);
userAttrsByName.put(username, userAttrs);
if (!isValidString(username)) {
invalidUsers.add(username);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.util.Map;

import org.apache.ranger.ugsyncutil.util.UgsyncCommonConstants;

import org.apache.directory.server.annotations.CreateLdapConnectionPool;
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
Expand Down Expand Up @@ -466,6 +472,62 @@ public void testGroupsWithNoUsers() throws Throwable {
assertEquals(2, sink.getGroupsWithNoUsers());
}

@Test
public void testUserFirstAndLastNameMapping() throws Throwable {
config.setUserNameAttribute("sAMAccountName");
config.setUserFirstNameAttribute("cn");
config.setUserLastNameAttribute("sn");
config.setUserSearchBase("cn=users,DC=ranger,DC=qe,DC=hortonworks,DC=com");
config.setUserSearchFilter("");
config.setGroupSearchBase("OU=Groups,DC=ranger,DC=qe,DC=hortonworks,DC=com");
config.setUserGroupMemberAttributeName("member");
config.setUserObjectClass("organizationalPerson");
config.setGroupObjectClass("groupOfNames");
config.setGroupSearchEnabled(false);
config.setPagedResultsEnabled(true);
config.setGroupSearchFirstEnabled(false);
config.setUserSearchEnabled(true);
// clear any group-name filter leftover from prior tests in this suite
config.setGroupnames("");
ldapBuilder.init();
sink.init();
ldapBuilder.updateSink(sink);

// sAMAccountName for cn=User1000 entry is "U1000"; cn/sn provide first/last name
Map<String, String> u1000Attrs = sink.getUserAttrs("U1000");
assertNotNull("U1000 should have been synced", u1000Attrs);
assertEquals("User1000", u1000Attrs.get(UgsyncCommonConstants.FIRST_NAME));
assertEquals("User1000", u1000Attrs.get(UgsyncCommonConstants.LAST_NAME));
}

@Test
public void testUserNameMappingWithoutFirstNameAttribute() throws Throwable {
config.setUserNameAttribute("sAMAccountName");
// firstName attribute defaults to givenName which is not present in the test LDIF
config.setUserFirstNameAttribute("givenName");
config.setUserLastNameAttribute("sn");
config.setUserSearchBase("cn=users,DC=ranger,DC=qe,DC=hortonworks,DC=com");
config.setUserSearchFilter("");
config.setGroupSearchBase("OU=Groups,DC=ranger,DC=qe,DC=hortonworks,DC=com");
config.setUserGroupMemberAttributeName("member");
config.setUserObjectClass("organizationalPerson");
config.setGroupObjectClass("groupOfNames");
config.setGroupSearchEnabled(false);
config.setPagedResultsEnabled(true);
config.setGroupSearchFirstEnabled(false);
config.setUserSearchEnabled(true);
// clear any group-name filter leftover from prior tests in this suite
config.setGroupnames("");
ldapBuilder.init();
sink.init();
ldapBuilder.updateSink(sink);

Map<String, String> u1000Attrs = sink.getUserAttrs("U1000");
assertNotNull("U1000 should have been synced", u1000Attrs);
assertNull("givenName is absent in the test LDIF", u1000Attrs.get(UgsyncCommonConstants.FIRST_NAME));
assertEquals("User1000", u1000Attrs.get(UgsyncCommonConstants.LAST_NAME));
}

@After
public void shutdown() throws Exception {
if (getService().isStarted()) {
Expand Down
Loading