You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/04/18 20:09:14 UTC
ambari git commit: AMBARI-19632. Ldap sync fails when there are
special characters in distinguished names (rlevas)
Repository: ambari
Updated Branches:
refs/heads/branch-2.4 36226da09 -> f613941aa
AMBARI-19632. Ldap sync fails when there are special characters in distinguished names (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f613941a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f613941a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f613941a
Branch: refs/heads/branch-2.4
Commit: f613941aabb78b600ea627f89bb78aa014bf1e79
Parents: 36226da
Author: Robert Levas <rl...@hortonworks.com>
Authored: Tue Apr 18 16:08:55 2017 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Tue Apr 18 16:08:55 2017 -0400
----------------------------------------------------------------------
ambari-project/pom.xml | 4 +-
.../security/authorization/AmbariLdapUtils.java | 71 +++++++++--
.../security/ldap/AmbariLdapDataPopulator.java | 100 ++++++++--------
.../server/security/AmbariLdapUtilsTest.java | 118 ++++++++++++++-----
.../ldap/AmbariLdapDataPopulatorTest.java | 9 +-
5 files changed, 200 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f613941a/ambari-project/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml
index 8825032..be00c9f 100644
--- a/ambari-project/pom.xml
+++ b/ambari-project/pom.xml
@@ -140,12 +140,12 @@
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
- <version>3.1.2.RELEASE</version>
+ <version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
- <version>1.3.1.RELEASE</version>
+ <version>2.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f613941a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java
index 6d20de3..a1c7009 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java
@@ -1,4 +1,4 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -7,7 +7,7 @@
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,13 +19,17 @@
package org.apache.ambari.server.security.authorization;
import com.google.common.base.Preconditions;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.security.ldap.LdapUtils;
+import org.springframework.ldap.support.LdapUtils;
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
import javax.naming.Name;
+import javax.naming.NamingException;
+
import java.util.regex.Pattern;
/**
@@ -42,8 +46,9 @@ public class AmbariLdapUtils {
/**
* Returns true if the given user name contains domain name as well (e.g. username@domain)
+ *
* @param loginName the login name to verify if it contains domain information.
- * @return
+ * @return true if the given user name contains domain name as well; false otherwise
*/
public static boolean isUserPrincipalNameFormat(String loginName) {
return UPN_FORMAT.matcher(loginName).matches();
@@ -52,9 +57,10 @@ public class AmbariLdapUtils {
/**
* Determine that the full DN of an LDAP object is in/out of the base DN scope.
+ *
* @param adapter used for get the full dn from the ldap query response
- * @param baseDn
- * @return
+ * @param baseDn the base distinguished name
+ * @return true if the object is out of scope; false otherwise
*/
public static boolean isLdapObjectOutOfScopeFromBaseDn(DirContextAdapter adapter, String baseDn) {
boolean isOutOfScope = true;
@@ -62,9 +68,9 @@ public class AmbariLdapUtils {
Name dn = adapter.getDn();
Preconditions.checkArgument(dn != null, "DN cannot be null in LDAP response object");
- DistinguishedName full = LdapUtils.getFullDn((DistinguishedName) dn, adapter);
- DistinguishedName base = new DistinguishedName(baseDn);
- if (full.startsWith(base)) {
+ Name fullDn = getFullDn(dn, adapter);
+ Name base = LdapUtils.newLdapName(baseDn);
+ if (fullDn.startsWith(base)) {
isOutOfScope = false;
}
} catch (Exception e) {
@@ -72,4 +78,49 @@ public class AmbariLdapUtils {
}
return isOutOfScope;
}
+
+ /**
+ * Ensures the given distinguished name is an absolute value rather than a name relative to the context.
+ *
+ * @param dn a distinguished name
+ * @param context the context containing the base distinguished name
+ * @return the absolute distinguished name
+ */
+ public static Name getFullDn(String dn, Context context) throws NamingException {
+ return getFullDn(LdapUtils.newLdapName(dn), context);
+ }
+
+ /**
+ * Ensures the given distinguished name is an absolute value rather than a name relative to the context.
+ *
+ * @param dn a distinguished name
+ * @param context the context containing the base distinguished name
+ * @return the absolute distinguished name
+ */
+ public static Name getFullDn(Name dn, Context context) throws NamingException {
+ return getFullDn(LdapUtils.newLdapName(dn), LdapUtils.newLdapName(context.getNameInNamespace()));
+ }
+
+ /**
+ * Ensures the given distinguished name is an absolute value rather than a name relative to the context.
+ *
+ * @param dn a distinguished name
+ * @param baseDn the base distinguished name
+ * @return the absolute distinguished name
+ */
+ public static Name getFullDn(Name dn, Name baseDn) {
+
+ if (dn.startsWith(baseDn)) {
+ return dn;
+ } else {
+ try {
+ //Copy the baseDN so we do not change the one that is passed in...
+ baseDn = LdapUtils.newLdapName(baseDn);
+ baseDn.addAll(dn);
+ } catch (InvalidNameException e) {
+ LOG.error(e.getMessage());
+ }
+ return baseDn;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f613941a/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java b/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
index 91ef97a..c91f53b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
@@ -1,4 +1,4 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -32,7 +32,6 @@ import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
-import com.google.common.collect.Lists;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.security.authorization.AmbariLdapUtils;
@@ -45,6 +44,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
+
import org.springframework.ldap.control.PagedResultsDirContextProcessor;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.ContextMapper;
@@ -57,6 +57,7 @@ import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.filter.HardcodedFilter;
import org.springframework.ldap.filter.LikeFilter;
import org.springframework.ldap.filter.OrFilter;
+import org.springframework.ldap.support.LdapUtils;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.google.inject.Inject;
@@ -90,13 +91,8 @@ public class AmbariLdapDataPopulator {
*/
private LdapTemplate ldapTemplate;
- /**
- * List for organizationUnits from the base DN
- */
- private List<String> baseOrganizationUnits = Lists.newArrayList();
-
// Constants
- private static final String UID_ATTRIBUTE = "uid";
+ private static final String UID_ATTRIBUTE = "uid";
private static final String OBJECT_CLASS_ATTRIBUTE = "objectClass";
private static final int USERS_PAGE_SIZE = 500;
@@ -109,8 +105,8 @@ public class AmbariLdapDataPopulator {
/**
* Construct an AmbariLdapDataPopulator.
*
- * @param configuration the Ambari configuration
- * @param users utility that provides access to Users
+ * @param configuration the Ambari configuration
+ * @param users utility that provides access to Users
*/
@Inject
public AmbariLdapDataPopulator(Configuration configuration, Users users) {
@@ -355,11 +351,11 @@ public class AmbariLdapDataPopulator {
/**
* Check group members of the synced group: add missing ones and remove the ones absent in external LDAP.
*
- * @param batchInfo batch update object
- * @param group ldap group
- * @param internalUsers map of internal users
- * @param groupMemberAttributes set of group member attributes that have already been refreshed
- * @param recursive if disabled, it won't refresh members recursively (its not needed in case of all groups are processed)
+ * @param batchInfo batch update object
+ * @param group ldap group
+ * @param internalUsers map of internal users
+ * @param groupMemberAttributes set of group member attributes that have already been refreshed
+ * @param recursive if disabled, it won't refresh members recursively (its not needed in case of all groups are processed)
* @throws AmbariException if group refresh failed
*/
protected void refreshGroupMembers(LdapBatchDto batchInfo, LdapGroupDto group, Map<String, User> internalUsers,
@@ -371,7 +367,7 @@ public class AmbariLdapDataPopulator {
groupMemberAttributes = new HashSet<String>();
}
- for (String memberAttributeValue: group.getMemberAttributes()) {
+ for (String memberAttributeValue : group.getMemberAttributes()) {
LdapUserDto groupMember = getLdapUserByMemberAttr(memberAttributeValue);
if (groupMember != null) {
externalMembers.add(groupMember.getUserName());
@@ -390,7 +386,7 @@ public class AmbariLdapDataPopulator {
}
String groupName = group.getGroupName();
final Map<String, User> internalMembers = getInternalMembers(groupName);
- for (String externalMember: externalMembers) {
+ for (String externalMember : externalMembers) {
if (internalUsers.containsKey(externalMember)) {
final User user = internalUsers.get(externalMember);
if (user == null) {
@@ -412,7 +408,7 @@ public class AmbariLdapDataPopulator {
batchInfo.getMembershipToAdd().add(new LdapUserGroupMemberDto(groupName, externalMember));
}
}
- for (Entry<String, User> userToBeUnsynced: internalMembers.entrySet()) {
+ for (Entry<String, User> userToBeUnsynced : internalMembers.entrySet()) {
final User user = userToBeUnsynced.getValue();
batchInfo.getMembershipToRemove().add(new LdapUserGroupMemberDto(groupName, user.getUserName()));
}
@@ -421,8 +417,7 @@ public class AmbariLdapDataPopulator {
/**
* Get the set of LDAP groups for the given group name.
*
- * @param groupName the group name
- *
+ * @param groupName the group name
* @return the set of LDAP groups for the given name
*/
protected Set<LdapGroupDto> getLdapGroups(String groupName) {
@@ -435,8 +430,7 @@ public class AmbariLdapDataPopulator {
/**
* Get the set of LDAP users for the given user name.
*
- * @param username the user name
- *
+ * @param username the user name
* @return the set of LDAP users for the given name
*/
protected Set<LdapUserDto> getLdapUsers(String username) {
@@ -448,31 +442,30 @@ public class AmbariLdapDataPopulator {
/**
* Get the LDAP user member for the given member attribute.
*
- * @param memberAttributeValue the member attribute value
- *
+ * @param memberAttributeValue the member attribute value
* @return the user for the given member attribute; null if not found
*/
protected LdapUserDto getLdapUserByMemberAttr(String memberAttributeValue) {
- Set<LdapUserDto> filteredLdapUsers = new HashSet<LdapUserDto>();
+ Set<LdapUserDto> filteredLdapUsers;
memberAttributeValue = getUniqueIdByMemberPattern(memberAttributeValue,
- ldapServerProperties.getSyncUserMemberReplacePattern());
+ ldapServerProperties.getSyncUserMemberReplacePattern());
Filter syncMemberFilter = createCustomMemberFilter(memberAttributeValue,
- ldapServerProperties.getSyncUserMemberFilter());
+ ldapServerProperties.getSyncUserMemberFilter());
if (memberAttributeValue != null && syncMemberFilter != null) {
LOG.trace("Use custom filter '{}' for getting member user with default baseDN ('{}')",
- syncMemberFilter.encode(), ldapServerProperties.getBaseDN());
+ syncMemberFilter.encode(), ldapServerProperties.getBaseDN());
filteredLdapUsers = getFilteredLdapUsers(ldapServerProperties.getBaseDN(), syncMemberFilter);
- } else if (memberAttributeValue!= null && isMemberAttributeBaseDn(memberAttributeValue)) {
+ } else if (memberAttributeValue != null && isMemberAttributeBaseDn(memberAttributeValue)) {
LOG.trace("Member can be used as baseDn: {}", memberAttributeValue);
Filter filter = new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getUserObjectClass());
filteredLdapUsers = getFilteredLdapUsers(memberAttributeValue, filter);
} else {
LOG.trace("Member cannot be used as baseDn: {}", memberAttributeValue);
Filter filter = new AndFilter()
- .and(new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getUserObjectClass()))
- .and(new EqualsFilter(ldapServerProperties.getUsernameAttribute(), memberAttributeValue));
+ .and(new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getUserObjectClass()))
+ .and(new EqualsFilter(ldapServerProperties.getUsernameAttribute(), memberAttributeValue));
filteredLdapUsers = getFilteredLdapUsers(ldapServerProperties.getBaseDN(), filter);
}
return (filteredLdapUsers.isEmpty()) ? null : filteredLdapUsers.iterator().next();
@@ -481,21 +474,20 @@ public class AmbariLdapDataPopulator {
/**
* Get the LDAP group member for the given member attribute.
*
- * @param memberAttributeValue the member attribute value
- *
+ * @param memberAttributeValue the member attribute value
* @return the group for the given member attribute; null if not found
*/
protected LdapGroupDto getLdapGroupByMemberAttr(String memberAttributeValue) {
- Set<LdapGroupDto> filteredLdapGroups = new HashSet<LdapGroupDto>();
+ Set<LdapGroupDto> filteredLdapGroups;
memberAttributeValue = getUniqueIdByMemberPattern(memberAttributeValue,
- ldapServerProperties.getSyncGroupMemberReplacePattern());
+ ldapServerProperties.getSyncGroupMemberReplacePattern());
Filter syncMemberFilter = createCustomMemberFilter(memberAttributeValue,
- ldapServerProperties.getSyncGroupMemberFilter());
+ ldapServerProperties.getSyncGroupMemberFilter());
if (memberAttributeValue != null && syncMemberFilter != null) {
LOG.trace("Use custom filter '{}' for getting member group with default baseDN ('{}')",
- syncMemberFilter.encode(), ldapServerProperties.getBaseDN());
+ syncMemberFilter.encode(), ldapServerProperties.getBaseDN());
filteredLdapGroups = getFilteredLdapGroups(ldapServerProperties.getBaseDN(), syncMemberFilter);
} else if (memberAttributeValue != null && isMemberAttributeBaseDn(memberAttributeValue)) {
LOG.trace("Member can be used as baseDn: {}", memberAttributeValue);
@@ -504,8 +496,8 @@ public class AmbariLdapDataPopulator {
} else {
LOG.trace("Member cannot be used as baseDn: {}", memberAttributeValue);
filteredLdapGroups = getFilteredLdapGroups(ldapServerProperties.getBaseDN(),
- new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getGroupObjectClass()),
- getMemberFilter(memberAttributeValue));
+ new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getGroupObjectClass()),
+ getMemberFilter(memberAttributeValue));
}
return (filteredLdapGroups.isEmpty()) ? null : filteredLdapGroups.iterator().next();
@@ -554,7 +546,7 @@ public class AmbariLdapDataPopulator {
*/
protected void cleanUpLdapUsersWithoutGroup() throws AmbariException {
final List<User> allUsers = users.getAllUsers();
- for (User user: allUsers) {
+ for (User user : allUsers) {
if (user.isLdapUser() && user.getGroups().isEmpty()) {
users.removeUser(user);
}
@@ -584,7 +576,7 @@ public class AmbariLdapDataPopulator {
*/
protected boolean isMemberAttributeBaseDn(String memberAttributeValue) {
Pattern pattern = Pattern.compile(String.format(IS_MEMBER_DN_REGEXP,
- ldapServerProperties.getUsernameAttribute(), ldapServerProperties.getGroupNamingAttr()));
+ ldapServerProperties.getUsernameAttribute(), ldapServerProperties.getGroupNamingAttr()));
return pattern.matcher(memberAttributeValue).find();
}
@@ -604,10 +596,10 @@ public class AmbariLdapDataPopulator {
String dnAttribute = ldapServerProperties.getDnAttribute();
return new OrFilter().or(new EqualsFilter(dnAttribute, memberAttributeValue)).
- or(new EqualsFilter(UID_ATTRIBUTE, memberAttributeValue));
+ or(new EqualsFilter(UID_ATTRIBUTE, memberAttributeValue));
}
- private Set<LdapGroupDto> getFilteredLdapGroups(String baseDn, Filter...filters) {
+ private Set<LdapGroupDto> getFilteredLdapGroups(String baseDn, Filter... filters) {
AndFilter andFilter = new AndFilter();
for (Filter filter : filters) {
andFilter.and(filter);
@@ -620,7 +612,7 @@ public class AmbariLdapDataPopulator {
final LdapTemplate ldapTemplate = loadLdapTemplate();
LOG.trace("LDAP Group Query - Base DN: '{}' ; Filter: '{}'", baseDn, filter.encode());
ldapTemplate.search(baseDn, filter.encode(),
- new LdapGroupContextMapper(groups, ldapServerProperties));
+ new LdapGroupContextMapper(groups, ldapServerProperties));
return groups;
}
@@ -635,7 +627,7 @@ public class AmbariLdapDataPopulator {
return getFilteredLdapUsers(ldapServerProperties.getBaseDN(), userObjectFilter);
}
- private Set<LdapUserDto> getFilteredLdapUsers(String baseDn, Filter...filters) {
+ private Set<LdapUserDto> getFilteredLdapUsers(String baseDn, Filter... filters) {
AndFilter andFilter = new AndFilter();
for (Filter filter : filters) {
andFilter.and(filter);
@@ -656,15 +648,15 @@ public class AmbariLdapDataPopulator {
do {
LOG.trace("LDAP User Query - Base DN: '{}' ; Filter: '{}'", baseDn, encodedFilter);
List dtos = configuration.getLdapServerProperties().isPaginationEnabled() ?
- ldapTemplate.search(baseDn, encodedFilter, searchControls, ldapUserContextMapper, processor) :
- ldapTemplate.search(baseDn, encodedFilter, searchControls, ldapUserContextMapper);
+ ldapTemplate.search(LdapUtils.newLdapName(baseDn), encodedFilter, searchControls, ldapUserContextMapper, processor) :
+ ldapTemplate.search(LdapUtils.newLdapName(baseDn), encodedFilter, searchControls, ldapUserContextMapper);
for (Object dto : dtos) {
if (dto != null) {
- users.add((LdapUserDto)dto);
+ users.add((LdapUserDto) dto);
}
}
} while (configuration.getLdapServerProperties().isPaginationEnabled()
- && processor.getCookie().getCookie() != null);
+ && processor.getCookie().getCookie() != null);
return users;
}
@@ -728,7 +720,7 @@ public class AmbariLdapDataPopulator {
ldapServerProperties = properties;
final LdapContextSource ldapContextSource = createLdapContextSource();
-
+
// The LdapTemplate by design will close the connection after each call to the LDAP Server
// In order to have the interaction work with large/paged results, said connection must be pooled and reused
ldapContextSource.setPooled(true);
@@ -768,6 +760,7 @@ public class AmbariLdapDataPopulator {
/**
* PagedResultsDirContextProcessor factory method.
+ *
* @return new processor;
*/
protected PagedResultsDirContextProcessor createPagingProcessor() {
@@ -777,8 +770,7 @@ public class AmbariLdapDataPopulator {
/**
* LdapTemplate factory method.
*
- * @param ldapContextSource the LDAP context source
- *
+ * @param ldapContextSource the LDAP context source
* @return new LDAP template
*/
protected LdapTemplate createLdapTemplate(LdapContextSource ldapContextSource) {
@@ -813,7 +805,7 @@ public class AmbariLdapDataPopulator {
group.setGroupName(groupNameAttribute.toLowerCase());
final String[] uniqueMembers = adapter.getStringAttributes(ldapServerProperties.getGroupMembershipAttr());
if (uniqueMembers != null) {
- for (String uniqueMember: uniqueMembers) {
+ for (String uniqueMember : uniqueMembers) {
group.getMemberAttributes().add(uniqueMember.toLowerCase());
}
}
@@ -833,7 +825,7 @@ public class AmbariLdapDataPopulator {
@Override
public Object mapFromContext(Object ctx) {
- final DirContextAdapter adapter = (DirContextAdapter) ctx;
+ final DirContextAdapter adapter = (DirContextAdapter) ctx;
final String usernameAttribute = adapter.getStringAttribute(ldapServerProperties.getUsernameAttribute());
final String uidAttribute = adapter.getStringAttribute(UID_ATTRIBUTE);
http://git-wip-us.apache.org/repos/asf/ambari/blob/f613941a/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java
index 5bcdf48..b05fa15 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -7,7 +7,7 @@
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,33 +15,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.ambari.server.security;
+import junit.framework.Assert;
+
import org.apache.ambari.server.security.authorization.AmbariLdapUtils;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.security.ldap.LdapUtils;
+import org.springframework.ldap.support.LdapUtils;
-import javax.naming.Context;
+import javax.naming.Name;
import javax.naming.NamingException;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(LdapUtils.class)
public class AmbariLdapUtilsTest {
- private static final String USER_DN = "uid=myuser,ou=hdp,ou=Users,dc=apache,dc=org";
+ private static final String USER_BASE_DN = "ou=hdp,ou=Users,dc=apache,dc=org";
+ private static final String USER_RELATIVE_DN = "uid=myuser";
+ private static final String USER_DN = USER_RELATIVE_DN + "," + USER_BASE_DN;
@Test
public void testIsUserPrincipalNameFormat_True() throws Exception {
@@ -106,46 +105,101 @@ public class AmbariLdapUtilsTest {
@Test
public void testIsLdapObjectOutOfScopeFromBaseDn() throws NamingException {
// GIVEN
- DistinguishedName fullDn = new DistinguishedName(USER_DN);
- Context context = createNiceMock(Context.class);
- DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
-
- PowerMock.mockStatic(LdapUtils.class);
- expect(LdapUtils.getFullDn(anyObject(DistinguishedName.class), anyObject(Context.class)))
- .andReturn(fullDn).anyTimes();
+ Name fullDn = LdapUtils.newLdapName(USER_DN);
+ DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
expect(adapter.getDn()).andReturn(fullDn);
- expect(context.getNameInNamespace()).andReturn(USER_DN);
+ expect(adapter.getNameInNamespace()).andReturn(USER_DN);
- replay(adapter, context);
- PowerMock.replayAll();
+ replay(adapter);
// WHEN
boolean isOutOfScopeFromBaseDN = AmbariLdapUtils.isLdapObjectOutOfScopeFromBaseDn(adapter, "dc=apache,dc=org");
// THEN
assertFalse(isOutOfScopeFromBaseDN);
+
+ verify(adapter);
}
@Test
public void testIsLdapObjectOutOfScopeFromBaseDn_dnOutOfScope() throws NamingException {
// GIVEN
- DistinguishedName fullDn = new DistinguishedName(USER_DN);
- Context context = createNiceMock(Context.class);
+ Name fullDn = LdapUtils.newLdapName(USER_DN);
DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
- PowerMock.mockStatic(LdapUtils.class);
- expect(LdapUtils.getFullDn(anyObject(DistinguishedName.class), anyObject(Context.class)))
- .andReturn(fullDn).anyTimes();
-
expect(adapter.getDn()).andReturn(fullDn);
- expect(context.getNameInNamespace()).andReturn(USER_DN);
+ expect(adapter.getNameInNamespace()).andReturn(USER_DN);
- replay(adapter, context);
- PowerMock.replayAll();
+ replay(adapter);
// WHEN
boolean isOutOfScopeFromBaseDN = AmbariLdapUtils.isLdapObjectOutOfScopeFromBaseDn(adapter, "dc=apache,dc=org,ou=custom");
// THEN
assertTrue(isOutOfScopeFromBaseDN);
+
+ verify(adapter);
+ }
+
+ @Test
+ public void testGetFullDn() throws Exception {
+
+ DirContextAdapter adapterFullDn = createStrictMock(DirContextAdapter.class);
+ expect(adapterFullDn.getNameInNamespace()).andReturn(USER_DN).anyTimes();
+
+ DirContextAdapter adapterBaseDn = createStrictMock(DirContextAdapter.class);
+ expect(adapterBaseDn.getNameInNamespace()).andReturn(USER_BASE_DN).anyTimes();
+
+ Name absoluteDn = LdapUtils.newLdapName(USER_DN);
+ Name relativeDn = LdapUtils.newLdapName(USER_RELATIVE_DN);
+
+ replay(adapterFullDn, adapterBaseDn);
+
+ Name fullDn;
+
+ // ****************************
+ // getFullDn(Name, Context)
+ fullDn = AmbariLdapUtils.getFullDn(absoluteDn, adapterFullDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+
+ fullDn = AmbariLdapUtils.getFullDn(absoluteDn, adapterBaseDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+
+ fullDn = AmbariLdapUtils.getFullDn(relativeDn, adapterBaseDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+ // ****************************
+
+
+ // ****************************
+ // getFullDn(String, Context)
+ fullDn = AmbariLdapUtils.getFullDn(absoluteDn.toString(), adapterFullDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+
+ fullDn = AmbariLdapUtils.getFullDn(absoluteDn.toString(), adapterBaseDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+
+ fullDn = AmbariLdapUtils.getFullDn(relativeDn.toString(), adapterBaseDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+ // ****************************
+
+ // ****************************
+ // getFullDn(Name, Name)
+ Name nameInNamespaceFullDn = LdapUtils.newLdapName(adapterFullDn.getNameInNamespace());
+ Name nameInNamespaceBaseDn = LdapUtils.newLdapName(adapterBaseDn.getNameInNamespace());
+
+ fullDn = AmbariLdapUtils.getFullDn(absoluteDn, nameInNamespaceFullDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+
+ fullDn = AmbariLdapUtils.getFullDn(absoluteDn, nameInNamespaceBaseDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+
+ fullDn = AmbariLdapUtils.getFullDn(relativeDn, nameInNamespaceBaseDn);
+ Assert.assertEquals(absoluteDn, fullDn);
+
+ // Make sure nameInNamespace was not altered
+ Assert.assertEquals(adapterFullDn.getNameInNamespace(), nameInNamespaceFullDn.toString());
+ Assert.assertEquals(adapterBaseDn.getNameInNamespace(), nameInNamespaceBaseDn.toString());
+ // ****************************
+
+ verify(adapterFullDn, adapterBaseDn);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f613941a/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
index 34eadad..f31468a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
@@ -57,6 +57,7 @@ import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.filter.Filter;
+import org.springframework.ldap.support.LdapUtils;
import javax.naming.directory.SearchControls;
@@ -1585,12 +1586,12 @@ public class AmbariLdapDataPopulatorTest {
expect(ldapServerProperties.isPaginationEnabled()).andReturn(true).anyTimes();
expect(ldapServerProperties.getUserObjectClass()).andReturn("objectClass").anyTimes();
expect(ldapServerProperties.getDnAttribute()).andReturn("dn").anyTimes();
- expect(ldapServerProperties.getBaseDN()).andReturn("baseDN").anyTimes();
+ expect(ldapServerProperties.getBaseDN()).andReturn("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com").anyTimes();
expect(ldapServerProperties.getUsernameAttribute()).andReturn("uid").anyTimes();
expect(processor.getCookie()).andReturn(cookie).anyTimes();
expect(cookie.getCookie()).andReturn(null).anyTimes();
- expect(ldapTemplate.search(eq("baseDN"), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture), eq(processor))).andReturn(list);
+ expect(ldapTemplate.search(eq(LdapUtils.newLdapName("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com")), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture), eq(processor))).andReturn(list);
replay(ldapTemplate, ldapServerProperties, users, configuration, processor, cookie);
@@ -1625,9 +1626,9 @@ public class AmbariLdapDataPopulatorTest {
expect(ldapServerProperties.getUserObjectClass()).andReturn("objectClass").anyTimes();
expect(ldapServerProperties.getUsernameAttribute()).andReturn("uid").anyTimes();
expect(ldapServerProperties.getDnAttribute()).andReturn("dn").anyTimes();
- expect(ldapServerProperties.getBaseDN()).andReturn("baseDN").anyTimes();
+ expect(ldapServerProperties.getBaseDN()).andReturn("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com").anyTimes();
- expect(ldapTemplate.search(eq("baseDN"), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture))).andReturn(list);
+ expect(ldapTemplate.search(eq(LdapUtils.newLdapName("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com") ), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture))).andReturn(list);
replay(ldapTemplate, ldapServerProperties, users, configuration, processor, cookie);