support multiple OUs in LDAP component
LDAPConfig class has been enhanced to support a new parameter
"subDNs" which is a collection of prefixes to add to "baseDN"
parameter.
LDAPUserComponent has been modified to take into account the new
parameters and search in a loop.
Setting multiple OUs enables the usage of users from different LDAP
Organization Units.
Change-Id: I22fc321b4938590d717784c7eb200f3aa8c1d206
Signed-off-by: Calin CRECEA <calin.crecea@sap.com>
diff --git a/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPConfig.java b/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPConfig.java
index 1706019..9b55640 100644
--- a/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPConfig.java
+++ b/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPConfig.java
@@ -18,6 +18,7 @@
private String providerId;
private String destination;
private String baseDN;
+ private LDAPSubDNs subDNs;
private String searchScope;
private String cacheSize;
@@ -61,6 +62,14 @@
this.baseDN = baseDN;
}
+ public LDAPSubDNs getLDAPSubDNs() {
+ return subDNs;
+ }
+
+ public void setLDAPSubDNs(LDAPSubDNs subDNs) {
+ this.subDNs = subDNs;
+ }
+
public String getCacheSize() {
return cacheSize;
}
diff --git a/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPSubDNs.java b/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPSubDNs.java
new file mode 100644
index 0000000..6976af7
--- /dev/null
+++ b/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPSubDNs.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2017 SAP AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * SAP AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.skalli.core.user.ldap;
+
+import java.util.List;
+
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
+public class LDAPSubDNs {
+
+ @XStreamImplicit(itemFieldName="subDN")
+ private List<String> listSubDNs;
+
+ // do not remove: required by xstream
+ public LDAPSubDNs() {
+ }
+
+ public List<String> getList() {
+ return listSubDNs;
+ }
+
+ public void setList(List<String> items) {
+ this.listSubDNs = items;
+ }
+
+ public int size(){
+ return this.listSubDNs.size();
+ }
+
+}
diff --git a/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPUserComponent.java b/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPUserComponent.java
index 2784a24..6c91056 100644
--- a/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPUserComponent.java
+++ b/org.eclipse.skalli.core/src/main/java/org/eclipse/skalli/core/user/ldap/LDAPUserComponent.java
@@ -72,6 +72,7 @@
private LdapContextProvider ctxProvider;
private String destination;
private String baseDN;
+ private LDAPSubDNs subDNs;
private String searchScope;
private EventService eventService;
@@ -134,6 +135,7 @@
ctxProvider = ctxProviders.get(providerId);
destination = ldapConfig.getDestination();
baseDN = ldapConfig.getBaseDN();
+ subDNs = ldapConfig.getLDAPSubDNs();
searchScope = ldapConfig.getSearchScope();
cacheSize = NumberUtils.toInt(ldapConfig.getCacheSize(), DEFAULT_CACHE_SIZE);
}
@@ -249,7 +251,7 @@
try {
ctx = ctxProvider.getLdapContext(destination);
return searchUserById(ctx, userId);
- } catch (Exception e) {
+ } catch (Exception e) {
LOG.debug(MessageFormat.format("Failed to retrieve user ''{0}''", userId), e);
return new User(userId);
} finally {
@@ -296,24 +298,19 @@
private User searchUserById(LdapContext ctx, String userId) throws NamingException {
SearchControls sc = getSearchControls();
- NamingEnumeration<SearchResult> results = null;
- try {
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(sAMAccountName={0}))", userId), sc); //$NON-NLS-1$
- while (results != null && results.hasMore()) {
- SearchResult entry = results.next();
- User user = processEntry(entry);
- if (user != null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(MessageFormat.format("Success reading from LDAP: {0}, {1} <{2}>", //$NON-NLS-1$
- user.getUserId(), user.getDisplayName(), user.getEmail()));
- }
- return user;
+ ArrayList<SearchResult> results = null;
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(sAMAccountName={0}))", userId), sc, ctx);//$NON-NLS-1$
+ for (SearchResult entry : results) {
+ User user = processEntry(entry);
+ if (user != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(MessageFormat.format("Success reading from LDAP: {0}, {1} <{2}>", //$NON-NLS-1$
+ user.getUserId(), user.getDisplayName(), user.getEmail()));
}
+ return user;
}
- } finally {
- closeQuietly(results);
}
+
return new User(userId);
}
@@ -323,46 +320,33 @@
boolean somethingAdded = false;
SearchControls sc = getSearchControls();
String[] parts = StringUtils.split(NormalizeUtil.normalize(name), " ,"); //$NON-NLS-1$
+
if (parts.length == 1) {
somethingAdded = search(parts[0], ret, ctx, sc);
- }
- else if (parts.length > 1) {
+ } else if (parts.length > 1) {
+
// givenname surname ('Michael Ochmann'), or surname givenname('Ochmann, Michael')
- NamingEnumeration<SearchResult> results = null;
- try {
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(givenName={0}*)(sn={1}*))", //$NON-NLS-1$
- parts[0], parts[1]), sc);
- somethingAdded |= addLDAPSearchResult(ret, results);
- } finally {
- closeQuietly(results);
- }
- try {
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(sn={0}*)(givenName={1}*))", //$NON-NLS-1$
- parts[0], parts[1]), sc);
- somethingAdded |= addLDAPSearchResult(ret, results);
- } finally {
- closeQuietly(results);
- }
+ ArrayList<SearchResult> results = null;
+
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(givenName={0}*)(sn={1}*))", //$NON-NLS-1$
+ parts[0], parts[1]), sc, ctx);
+ somethingAdded |= addLDAPSearchResult(ret, results);
+
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(sn={0}*)(givenName={1}*))", //$NON-NLS-1$
+ parts[0], parts[1]), sc, ctx);
+ somethingAdded |= addLDAPSearchResult(ret, results);
+
// givenname initial surname, e.g. 'Michael R. Ochmann'
if (parts.length > 2) {
- try {
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(givenName={0}*)(sn={1}*))", //$NON-NLS-1$
- parts[0], parts[2]), sc);
- somethingAdded |= addLDAPSearchResult(ret, results);
- } finally {
- closeQuietly(results);
- }
- try {
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(sn={0}*)(givenName={1}*))", //$NON-NLS-1$
- parts[0], parts[2]), sc);
- somethingAdded |= addLDAPSearchResult(ret, results);
- } finally {
- closeQuietly(results);
- }
+
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(givenName={0}*)(sn={1}*))", //$NON-NLS-1$
+ parts[0], parts[2]), sc, ctx);
+ somethingAdded |= addLDAPSearchResult(ret, results);
+
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(sn={0}*)(givenName={1}*))", //$NON-NLS-1$
+ parts[0], parts[2]), sc, ctx);
+ somethingAdded |= addLDAPSearchResult(ret, results);
+
}
if (!somethingAdded) {
// try to match each part individually
@@ -381,53 +365,65 @@
private boolean search(String s, List<User> ret, LdapContext ctx, SearchControls sc) throws NamingException {
// try a match with surname*
boolean somethingAdded = false;
- NamingEnumeration<SearchResult> results = null;
- try {
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(|(sn={0}*)(givenName={1}*)))", s, s), sc); //$NON-NLS-1$
- somethingAdded = addLDAPSearchResult(ret, results);
- } finally {
- closeQuietly(results);
+ ArrayList<SearchResult> results = null;
+
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(|(sn={0}*)(givenName={1}*)))", s, s), sc, //$NON-NLS-1$
+ ctx);
+ somethingAdded = addLDAPSearchResult(ret, results);
+
+ if (!somethingAdded) {
+ // try a match with the account name and mail address
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(sAMAccountName={0}*))", s), sc, ctx); //$NON-NLS-1$
+ somethingAdded |= addLDAPSearchResult(ret, results);
}
if (!somethingAdded) {
- try {
- // try a match with the account name and mail address
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(sAMAccountName={0}*))", s), sc); //$NON-NLS-1$
- somethingAdded |= addLDAPSearchResult(ret, results);
- } finally {
- closeQuietly(results);
- }
- if (!somethingAdded) {
- try {
- // try to match surname~= or givenname~=
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(|(sn~={0})(givenName~={1})))", s, s), sc); //$NON-NLS-1$
- somethingAdded |= addLDAPSearchResult(ret, results);
- } finally {
- closeQuietly(results);
- }
- if (!somethingAdded) {
- try {
- results = ctx.search(baseDN,
- MessageFormat.format("(&(objectClass=user)(mail={0}*))", s), sc); //$NON-NLS-1$
- somethingAdded |= addLDAPSearchResult(ret, results);
- } finally {
- closeQuietly(results);
- }
- }
- }
+ // try to match surname~= or givenname~=
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(|(sn~={0})(givenName~={1})))", s, s), //$NON-NLS-1$
+ sc, ctx);
+ somethingAdded |= addLDAPSearchResult(ret, results);
}
+ if (!somethingAdded) {
+ results = ctxSearch(MessageFormat.format("(&(objectClass=user)(mail={0}*))", s), sc, ctx); //$NON-NLS-1$
+ somethingAdded |= addLDAPSearchResult(ret, results);
+ }
+
return somethingAdded;
}
+ private ArrayList<SearchResult> ctxSearch(String query, SearchControls sc, LdapContext ctx)
+ throws NamingException {
+ ArrayList<SearchResult> result = new ArrayList<SearchResult>();
+ if (subDNs != null && subDNs.size() > 0){
+ for (String subDN : subDNs.getList()) {
+ addSearchResult(result, subDN + "," + baseDN, query, sc, ctx);
+ }
+ }
+ else {
+ //in case subDNs are not set, we search only using baseDN
+ addSearchResult(result, baseDN, query, sc, ctx);
+ }
+ return result;
+ }
+
+ private void addSearchResult(List<SearchResult> result, String dn, String query, SearchControls sc, LdapContext ctx)
+ throws NamingException {
+ NamingEnumeration<SearchResult> resultQuery = ctx.search(dn, query, sc); //$NON-NLS-1$
+ try {
+ if (resultQuery != null && resultQuery.hasMore()) {
+ result.addAll(Collections.list(resultQuery));
+ }
+ }
+ finally {
+ closeQuietly(resultQuery);
+ resultQuery = null;
+ }
+ }
+
// Iterate over a batch of search results sent by the server
- private boolean addLDAPSearchResult(List<User> users, NamingEnumeration<SearchResult> results)
+ private boolean addLDAPSearchResult(List<User> users, ArrayList<SearchResult> results)
throws NamingException {
boolean somethingAdded = false;
- while (results != null && results.hasMore()) {
- // Display an entry
- SearchResult entry = results.next();
+ for (SearchResult entry : results) {
User user = processEntry(entry);
if (user != null) {
if (LOG.isDebugEnabled()) {
@@ -496,7 +492,7 @@
private void closeQuietly(LdapContext ctx) {
if (ctx != null) {
try {
- ctx .close();
+ ctx.close();
} catch (NamingException e) {
LOG.error("Failed to close LDAP connection", e);
}