diff --git a/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml b/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml
index 34a2befe971..8ae4009367f 100644
--- a/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml
+++ b/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml
@@ -30,7 +30,7 @@
-
+
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java
new file mode 100644
index 00000000000..e5e20c54fb2
--- /dev/null
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java
@@ -0,0 +1,81 @@
+/*
+ * 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
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.ldap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+public class ADLdapUserManagerImpl extends OpenLdapUserManagerImpl implements LdapUserManager {
+ public static final Logger s_logger = Logger.getLogger(ADLdapUserManagerImpl.class.getName());
+
+ @Override
+ public List getUsersInGroup(String groupName, LdapContext context) throws NamingException {
+ final SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(_ldapConfiguration.getScope());
+ searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
+
+ String basedn = _ldapConfiguration.getBaseDn();
+ if (StringUtils.isBlank(basedn)) {
+ throw new IllegalArgumentException("ldap basedn is not configured");
+ }
+
+ if (StringUtils.isBlank(groupName)) {
+ throw new IllegalArgumentException("ldap group name cannot be blank");
+ }
+
+ NamingEnumeration results = context.search(basedn, generateADGroupSearchFilter(groupName), searchControls);
+ final List users = new ArrayList();
+ while (results.hasMoreElements()) {
+ final SearchResult result = results.nextElement();
+ users.add(createUser(result));
+ }
+ return users;
+ }
+
+ private String generateADGroupSearchFilter(String groupName) {
+ final StringBuilder userObjectFilter = new StringBuilder();
+ userObjectFilter.append("(objectClass=");
+ userObjectFilter.append(_ldapConfiguration.getUserObject());
+ userObjectFilter.append(")");
+
+ final StringBuilder memberOfFilter = new StringBuilder();
+ String groupCnName = _ldapConfiguration.getCommonNameAttribute() + "=" +groupName + "," + _ldapConfiguration.getBaseDn();
+ memberOfFilter.append("(memberOf:1.2.840.113556.1.4.1941:=");
+ memberOfFilter.append(groupCnName);
+ memberOfFilter.append(")");
+
+ final StringBuilder result = new StringBuilder();
+ result.append("(&");
+ result.append(userObjectFilter);
+ result.append(memberOfFilter);
+ result.append(")");
+
+ s_logger.debug("group search filter = " + result);
+ return result.toString();
+ }
+}
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java
index c171ebfcc0b..f247f40001e 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java
@@ -21,12 +21,12 @@ import java.util.List;
import javax.inject.Inject;
import javax.naming.directory.SearchControls;
-import org.apache.cloudstack.api.command.LdapListConfigurationCmd;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import com.cloud.utils.Pair;
+import org.apache.cloudstack.ldap.dao.LdapConfigurationDao;
public class LdapConfiguration implements Configurable{
private final static String factory = "com.sun.jndi.ldap.LdapCtxFactory";
@@ -36,6 +36,8 @@ public class LdapConfiguration implements Configurable{
private static final ConfigKey ldapPageSize = new ConfigKey(Integer.class, "ldap.request.page.size", "Advanced", "1000",
"page size sent to ldap server on each request to get user", true, ConfigKey.Scope.Global, 1);
+ private static final ConfigKey ldapProvider = new ConfigKey(String.class, "ldap.provider", "Advanced", "openldap", "ldap provider ex:openldap, microsoftad",
+ true, ConfigKey.Scope.Global, null);
private final static int scope = SearchControls.SUBTREE_SCOPE;
@@ -43,14 +45,14 @@ public class LdapConfiguration implements Configurable{
private ConfigurationDao _configDao;
@Inject
- private LdapManager _ldapManager;
+ private LdapConfigurationDao _ldapConfigurationDao;
public LdapConfiguration() {
}
- public LdapConfiguration(final ConfigurationDao configDao, final LdapManager ldapManager) {
+ public LdapConfiguration(final ConfigurationDao configDao, final LdapConfigurationDao ldapConfigurationDao) {
_configDao = configDao;
- _ldapManager = ldapManager;
+ _ldapConfigurationDao = ldapConfigurationDao;
}
public String getAuthentication() {
@@ -94,7 +96,7 @@ public class LdapConfiguration implements Configurable{
public String getProviderUrl() {
final String protocol = getSSLStatus() == true ? "ldaps://" : "ldap://";
- final Pair, Integer> result = _ldapManager.listConfigurations(new LdapListConfigurationCmd(_ldapManager));
+ final Pair, Integer> result = _ldapConfigurationDao.searchConfigurations(null, 0);
final StringBuilder providerUrls = new StringBuilder();
String delim = "";
for (final LdapConfigurationVO resource : result.first()) {
@@ -165,6 +167,8 @@ public class LdapConfiguration implements Configurable{
return ldapPageSize.value();
}
+ public String getLdapProvider() { return ldapProvider.value();}
+
@Override
public String getConfigComponentName() {
return LdapConfiguration.class.getSimpleName();
@@ -172,6 +176,6 @@ public class LdapConfiguration implements Configurable{
@Override
public ConfigKey>[] getConfigKeys() {
- return new ConfigKey>[] {ldapReadTimeout, ldapPageSize};
+ return new ConfigKey>[] {ldapReadTimeout, ldapPageSize, ldapProvider};
}
}
\ No newline at end of file
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
index dfd39a3c7c1..8e912b8b030 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
@@ -57,17 +57,22 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
private LdapContextFactory _ldapContextFactory;
@Inject
- private LdapUserManager _ldapUserManager;
+ private LdapConfiguration _ldapConfiguration;
+
+ @Inject LdapUserManagerFactory _ldapUserManagerFactory;
+
public LdapManagerImpl() {
super();
}
- public LdapManagerImpl(final LdapConfigurationDao ldapConfigurationDao, final LdapContextFactory ldapContextFactory, final LdapUserManager ldapUserManager) {
+ public LdapManagerImpl(final LdapConfigurationDao ldapConfigurationDao, final LdapContextFactory ldapContextFactory, final LdapUserManagerFactory ldapUserManagerFactory,
+ final LdapConfiguration ldapConfiguration) {
super();
_ldapConfigurationDao = ldapConfigurationDao;
_ldapContextFactory = ldapContextFactory;
- _ldapUserManager = ldapUserManager;
+ _ldapUserManagerFactory = ldapUserManagerFactory;
+ _ldapConfiguration = ldapConfiguration;
}
@Override
@@ -173,7 +178,7 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
context = _ldapContextFactory.createBindContext();
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
- return _ldapUserManager.getUser(escapedUsername, context);
+ return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUser(escapedUsername, context);
} catch (NamingException | IOException e) {
s_logger.debug("ldap Exception: ",e);
@@ -188,7 +193,7 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
LdapContext context = null;
try {
context = _ldapContextFactory.createBindContext();
- return _ldapUserManager.getUsers(context);
+ return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsers(context);
} catch (NamingException | IOException e) {
s_logger.debug("ldap Exception: ",e);
throw new NoLdapUserMatchingQueryException("*");
@@ -202,7 +207,7 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
LdapContext context = null;
try {
context = _ldapContextFactory.createBindContext();
- return _ldapUserManager.getUsersInGroup(groupName, context);
+ return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsersInGroup(groupName, context);
} catch (NamingException | IOException e) {
s_logger.debug("ldap NamingException: ",e);
throw new NoLdapUserMatchingQueryException("groupName=" + groupName);
@@ -230,7 +235,7 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
try {
context = _ldapContextFactory.createBindContext();
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
- return _ldapUserManager.getUsers("*" + escapedUsername + "*", context);
+ return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsers("*" + escapedUsername + "*", context);
} catch (NamingException | IOException e) {
s_logger.debug("ldap Exception: ",e);
throw new NoLdapUserMatchingQueryException(username);
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
index 654a601a476..28fc74e947b 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
@@ -1,227 +1,40 @@
-// 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
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "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
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
+/*
+ * 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
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.cloudstack.ldap;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import javax.inject.Inject;
-import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-import javax.naming.ldap.Control;
import javax.naming.ldap.LdapContext;
-import javax.naming.ldap.PagedResultsControl;
-import javax.naming.ldap.PagedResultsResponseControl;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
+public interface LdapUserManager {
-public class LdapUserManager {
- private static final Logger s_logger = Logger.getLogger(LdapUserManager.class.getName());
+ public LdapUser getUser(final String username, final LdapContext context) throws NamingException, IOException;
- @Inject
- private LdapConfiguration _ldapConfiguration;
+ public List getUsers(final LdapContext context) throws NamingException, IOException;
- public LdapUserManager() {
- }
+ public List getUsers(final String username, final LdapContext context) throws NamingException, IOException;
- public LdapUserManager(final LdapConfiguration ldapConfiguration) {
- _ldapConfiguration = ldapConfiguration;
- }
+ public List getUsersInGroup(String groupName, LdapContext context) throws NamingException;
- private LdapUser createUser(final SearchResult result) throws NamingException {
- final Attributes attributes = result.getAttributes();
+ public List searchUsers(final LdapContext context) throws NamingException, IOException;
- final String username = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getUsernameAttribute());
- final String email = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getEmailAttribute());
- final String firstname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getFirstnameAttribute());
- final String lastname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getLastnameAttribute());
- final String principal = result.getNameInNamespace();
-
- String domain = principal.replace("cn=" + LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getCommonNameAttribute()) + ",", "");
- domain = domain.replace("," + _ldapConfiguration.getBaseDn(), "");
- domain = domain.replace("ou=", "");
-
- return new LdapUser(username, email, firstname, lastname, principal, domain);
- }
-
- private String generateSearchFilter(final String username) {
- final StringBuilder userObjectFilter = new StringBuilder();
- userObjectFilter.append("(objectClass=");
- userObjectFilter.append(_ldapConfiguration.getUserObject());
- userObjectFilter.append(")");
-
- final StringBuilder usernameFilter = new StringBuilder();
- usernameFilter.append("(");
- usernameFilter.append(_ldapConfiguration.getUsernameAttribute());
- usernameFilter.append("=");
- usernameFilter.append((username == null ? "*" : username));
- usernameFilter.append(")");
-
- final StringBuilder memberOfFilter = new StringBuilder();
- if (_ldapConfiguration.getSearchGroupPrinciple() != null) {
- memberOfFilter.append("(memberof=");
- memberOfFilter.append(_ldapConfiguration.getSearchGroupPrinciple());
- memberOfFilter.append(")");
- }
-
- final StringBuilder result = new StringBuilder();
- result.append("(&");
- result.append(userObjectFilter);
- result.append(usernameFilter);
- result.append(memberOfFilter);
- result.append(")");
-
- return result.toString();
- }
-
- private String generateGroupSearchFilter(final String groupName) {
- final StringBuilder groupObjectFilter = new StringBuilder();
- groupObjectFilter.append("(objectClass=");
- groupObjectFilter.append(_ldapConfiguration.getGroupObject());
- groupObjectFilter.append(")");
-
- final StringBuilder groupNameFilter = new StringBuilder();
- groupNameFilter.append("(");
- groupNameFilter.append(_ldapConfiguration.getCommonNameAttribute());
- groupNameFilter.append("=");
- groupNameFilter.append((groupName == null ? "*" : groupName));
- groupNameFilter.append(")");
-
- final StringBuilder result = new StringBuilder();
- result.append("(&");
- result.append(groupObjectFilter);
- result.append(groupNameFilter);
- result.append(")");
-
- return result.toString();
- }
-
- public LdapUser getUser(final String username, final LdapContext context) throws NamingException, IOException {
- List result = searchUsers(username, context);
- if (result!= null && result.size() == 1) {
- return result.get(0);
- } else {
- throw new NamingException("No user found for username " + username);
- }
- }
-
- public List getUsers(final LdapContext context) throws NamingException, IOException {
- return getUsers(null, context);
- }
-
- public List getUsers(final String username, final LdapContext context) throws NamingException, IOException {
- List users = searchUsers(username, context);
-
- if (CollectionUtils.isNotEmpty(users)) {
- Collections.sort(users);
- }
- return users;
- }
-
- public List getUsersInGroup(String groupName, LdapContext context) throws NamingException {
- String attributeName = _ldapConfiguration.getGroupUniqueMemeberAttribute();
- final SearchControls controls = new SearchControls();
- controls.setSearchScope(_ldapConfiguration.getScope());
- controls.setReturningAttributes(new String[] {attributeName});
-
- NamingEnumeration result = context.search(_ldapConfiguration.getBaseDn(), generateGroupSearchFilter(groupName), controls);
-
- final List users = new ArrayList();
- //Expecting only one result which has all the users
- if (result.hasMoreElements()) {
- Attribute attribute = result.nextElement().getAttributes().get(attributeName);
- NamingEnumeration> values = attribute.getAll();
-
- while (values.hasMoreElements()) {
- String userdn = String.valueOf(values.nextElement());
- try{
- users.add(getUserForDn(userdn, context));
- } catch (NamingException e){
- s_logger.info("Userdn: " + userdn + " Not Found:: Exception message: " + e.getMessage());
- }
- }
- }
-
- Collections.sort(users);
-
- return users;
- }
-
- private LdapUser getUserForDn(String userdn, LdapContext context) throws NamingException {
- final SearchControls controls = new SearchControls();
- controls.setSearchScope(_ldapConfiguration.getScope());
- controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
-
- NamingEnumeration result = context.search(userdn, "(objectClass=" + _ldapConfiguration.getUserObject() + ")", controls);
- if (result.hasMoreElements()) {
- return createUser(result.nextElement());
- } else {
- throw new NamingException("No user found for dn " + userdn);
- }
- }
-
- public List searchUsers(final LdapContext context) throws NamingException, IOException {
- return searchUsers(null, context);
- }
-
- public List searchUsers(final String username, final LdapContext context) throws NamingException, IOException {
-
- final SearchControls searchControls = new SearchControls();
-
- searchControls.setSearchScope(_ldapConfiguration.getScope());
- searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
-
- String basedn = _ldapConfiguration.getBaseDn();
- if (StringUtils.isBlank(basedn)) {
- throw new IllegalArgumentException("ldap basedn is not configured");
- }
- byte[] cookie = null;
- int pageSize = _ldapConfiguration.getLdapPageSize();
- context.setRequestControls(new Control[]{new PagedResultsControl(pageSize, Control.NONCRITICAL)});
- final List users = new ArrayList();
- NamingEnumeration results;
- do {
- results = context.search(basedn, generateSearchFilter(username), searchControls);
- while (results.hasMoreElements()) {
- final SearchResult result = results.nextElement();
- users.add(createUser(result));
- }
- Control[] contextControls = context.getResponseControls();
- if (contextControls != null) {
- for (Control control : contextControls) {
- if (control instanceof PagedResultsResponseControl) {
- PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
- cookie = prrc.getCookie();
- }
- }
- } else {
- s_logger.info("No controls were sent from the ldap server");
- }
- context.setRequestControls(new Control[] {new PagedResultsControl(pageSize, cookie, Control.CRITICAL)});
- } while (cookie != null);
-
- return users;
- }
-}
\ No newline at end of file
+ public List searchUsers(final String username, final LdapContext context) throws NamingException, IOException;
+}
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManagerFactory.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManagerFactory.java
new file mode 100644
index 00000000000..35652fb8f30
--- /dev/null
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManagerFactory.java
@@ -0,0 +1,55 @@
+/*
+ * 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
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.ldap;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class LdapUserManagerFactory implements ApplicationContextAware {
+ public static final Logger s_logger = Logger.getLogger(LdapUserManagerFactory.class.getName());
+
+ private static LdapUserManager adUserManager;
+ private static LdapUserManager openLdapUserManager;
+
+ static ApplicationContext applicationCtx;
+
+ public LdapUserManager getInstance(String id) {
+ if ("microsoftad".equalsIgnoreCase(id)) {
+ if (adUserManager == null) {
+ adUserManager = new ADLdapUserManagerImpl();
+ applicationCtx.getAutowireCapableBeanFactory().autowireBeanProperties(adUserManager, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ }
+ return adUserManager;
+ }
+ //defaults to opendldap
+ if (openLdapUserManager == null) {
+ openLdapUserManager = new OpenLdapUserManagerImpl();
+ applicationCtx.getAutowireCapableBeanFactory().autowireBeanProperties(openLdapUserManager, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ }
+ return openLdapUserManager;
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ applicationCtx = applicationContext;
+ }
+}
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java
new file mode 100644
index 00000000000..11e6bcfc92a
--- /dev/null
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java
@@ -0,0 +1,233 @@
+// 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
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "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
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.ldap;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.Control;
+import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.PagedResultsControl;
+import javax.naming.ldap.PagedResultsResponseControl;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+public class OpenLdapUserManagerImpl implements LdapUserManager {
+ private static final Logger s_logger = Logger.getLogger(OpenLdapUserManagerImpl.class.getName());
+
+ @Inject
+ protected LdapConfiguration _ldapConfiguration;
+
+ public OpenLdapUserManagerImpl() {
+ }
+
+ public OpenLdapUserManagerImpl(final LdapConfiguration ldapConfiguration) {
+ _ldapConfiguration = ldapConfiguration;
+ }
+
+ protected LdapUser createUser(final SearchResult result) throws NamingException {
+ final Attributes attributes = result.getAttributes();
+
+ final String username = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getUsernameAttribute());
+ final String email = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getEmailAttribute());
+ final String firstname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getFirstnameAttribute());
+ final String lastname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getLastnameAttribute());
+ final String principal = result.getNameInNamespace();
+
+ String domain = principal.replace("cn=" + LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getCommonNameAttribute()) + ",", "");
+ domain = domain.replace("," + _ldapConfiguration.getBaseDn(), "");
+ domain = domain.replace("ou=", "");
+
+ return new LdapUser(username, email, firstname, lastname, principal, domain);
+ }
+
+ private String generateSearchFilter(final String username) {
+ final StringBuilder userObjectFilter = new StringBuilder();
+ userObjectFilter.append("(objectClass=");
+ userObjectFilter.append(_ldapConfiguration.getUserObject());
+ userObjectFilter.append(")");
+
+ final StringBuilder usernameFilter = new StringBuilder();
+ usernameFilter.append("(");
+ usernameFilter.append(_ldapConfiguration.getUsernameAttribute());
+ usernameFilter.append("=");
+ usernameFilter.append((username == null ? "*" : username));
+ usernameFilter.append(")");
+
+ final StringBuilder memberOfFilter = new StringBuilder();
+ if (_ldapConfiguration.getSearchGroupPrinciple() != null) {
+ memberOfFilter.append("(memberof=");
+ memberOfFilter.append(_ldapConfiguration.getSearchGroupPrinciple());
+ memberOfFilter.append(")");
+ }
+
+ final StringBuilder result = new StringBuilder();
+ result.append("(&");
+ result.append(userObjectFilter);
+ result.append(usernameFilter);
+ result.append(memberOfFilter);
+ result.append(")");
+
+ return result.toString();
+ }
+
+ private String generateGroupSearchFilter(final String groupName) {
+ final StringBuilder groupObjectFilter = new StringBuilder();
+ groupObjectFilter.append("(objectClass=");
+ groupObjectFilter.append(_ldapConfiguration.getGroupObject());
+ groupObjectFilter.append(")");
+
+ final StringBuilder groupNameFilter = new StringBuilder();
+ groupNameFilter.append("(");
+ groupNameFilter.append(_ldapConfiguration.getCommonNameAttribute());
+ groupNameFilter.append("=");
+ groupNameFilter.append((groupName == null ? "*" : groupName));
+ groupNameFilter.append(")");
+
+ final StringBuilder result = new StringBuilder();
+ result.append("(&");
+ result.append(groupObjectFilter);
+ result.append(groupNameFilter);
+ result.append(")");
+
+ return result.toString();
+ }
+
+ @Override
+ public LdapUser getUser(final String username, final LdapContext context) throws NamingException, IOException {
+ List result = searchUsers(username, context);
+ if (result!= null && result.size() == 1) {
+ return result.get(0);
+ } else {
+ throw new NamingException("No user found for username " + username);
+ }
+ }
+
+ @Override
+ public List getUsers(final LdapContext context) throws NamingException, IOException {
+ return getUsers(null, context);
+ }
+
+ @Override
+ public List getUsers(final String username, final LdapContext context) throws NamingException, IOException {
+ List users = searchUsers(username, context);
+
+ if (CollectionUtils.isNotEmpty(users)) {
+ Collections.sort(users);
+ }
+ return users;
+ }
+
+ @Override
+ public List getUsersInGroup(String groupName, LdapContext context) throws NamingException {
+ String attributeName = _ldapConfiguration.getGroupUniqueMemeberAttribute();
+ final SearchControls controls = new SearchControls();
+ controls.setSearchScope(_ldapConfiguration.getScope());
+ controls.setReturningAttributes(new String[] {attributeName});
+
+ NamingEnumeration result = context.search(_ldapConfiguration.getBaseDn(), generateGroupSearchFilter(groupName), controls);
+
+ final List users = new ArrayList();
+ //Expecting only one result which has all the users
+ if (result.hasMoreElements()) {
+ Attribute attribute = result.nextElement().getAttributes().get(attributeName);
+ NamingEnumeration> values = attribute.getAll();
+
+ while (values.hasMoreElements()) {
+ String userdn = String.valueOf(values.nextElement());
+ try{
+ users.add(getUserForDn(userdn, context));
+ } catch (NamingException e){
+ s_logger.info("Userdn: " + userdn + " Not Found:: Exception message: " + e.getMessage());
+ }
+ }
+ }
+
+ Collections.sort(users);
+
+ return users;
+ }
+
+ private LdapUser getUserForDn(String userdn, LdapContext context) throws NamingException {
+ final SearchControls controls = new SearchControls();
+ controls.setSearchScope(_ldapConfiguration.getScope());
+ controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
+
+ NamingEnumeration result = context.search(userdn, "(objectClass=" + _ldapConfiguration.getUserObject() + ")", controls);
+ if (result.hasMoreElements()) {
+ return createUser(result.nextElement());
+ } else {
+ throw new NamingException("No user found for dn " + userdn);
+ }
+ }
+
+ @Override
+ public List searchUsers(final LdapContext context) throws NamingException, IOException {
+ return searchUsers(null, context);
+ }
+
+ @Override
+ public List searchUsers(final String username, final LdapContext context) throws NamingException, IOException {
+
+ final SearchControls searchControls = new SearchControls();
+
+ searchControls.setSearchScope(_ldapConfiguration.getScope());
+ searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
+
+ String basedn = _ldapConfiguration.getBaseDn();
+ if (StringUtils.isBlank(basedn)) {
+ throw new IllegalArgumentException("ldap basedn is not configured");
+ }
+ byte[] cookie = null;
+ int pageSize = _ldapConfiguration.getLdapPageSize();
+ context.setRequestControls(new Control[]{new PagedResultsControl(pageSize, Control.NONCRITICAL)});
+ final List users = new ArrayList();
+ NamingEnumeration results;
+ do {
+ results = context.search(basedn, generateSearchFilter(username), searchControls);
+ while (results.hasMoreElements()) {
+ final SearchResult result = results.nextElement();
+ users.add(createUser(result));
+ }
+ Control[] contextControls = context.getResponseControls();
+ if (contextControls != null) {
+ for (Control control : contextControls) {
+ if (control instanceof PagedResultsResponseControl) {
+ PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
+ cookie = prrc.getCookie();
+ }
+ }
+ } else {
+ s_logger.info("No controls were sent from the ldap server");
+ }
+ context.setRequestControls(new Control[] {new PagedResultsControl(pageSize, cookie, Control.CRITICAL)});
+ } while (cookie != null);
+
+ return users;
+ }
+}
\ No newline at end of file
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/ADLdapUserManagerImplSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/ADLdapUserManagerImplSpec.groovy
new file mode 100644
index 00000000000..6fafa3edf22
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/ADLdapUserManagerImplSpec.groovy
@@ -0,0 +1,70 @@
+/*
+ * 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
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.org.apache.cloudstack.ldap
+
+import org.apache.cloudstack.ldap.ADLdapUserManagerImpl
+import org.apache.cloudstack.ldap.LdapConfiguration
+import spock.lang.Shared
+
+import javax.naming.directory.SearchControls
+import javax.naming.ldap.LdapContext
+
+class ADLdapUserManagerImplSpec extends spock.lang.Specification {
+
+ @Shared
+ ADLdapUserManagerImpl adLdapUserManager;
+
+ @Shared
+ LdapConfiguration ldapConfiguration;
+
+ def setup() {
+ adLdapUserManager = new ADLdapUserManagerImpl();
+ ldapConfiguration = Mock(LdapConfiguration);
+ adLdapUserManager._ldapConfiguration = ldapConfiguration;
+ }
+
+ def "test generate AD search filter"() {
+ ldapConfiguration.getUserObject() >> "user"
+ ldapConfiguration.getCommonNameAttribute() >> "CN"
+ ldapConfiguration.getBaseDn() >> "DC=cloud,DC=citrix,DC=com"
+
+ def result = adLdapUserManager.generateADGroupSearchFilter(group);
+ expect:
+ assert result.contains("memberOf:1.2.840.113556.1.4.1941:=")
+ result == "(&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=" + group + ",DC=cloud,DC=citrix,DC=com))"
+ where:
+ group << ["dev", "dev-hyd"]
+ }
+
+ def "test getUsersInGroup null group"() {
+ ldapConfiguration.getScope() >> SearchControls.SUBTREE_SCOPE
+ ldapConfiguration.getReturnAttributes() >> ["username", "firstname", "lastname", "email"]
+ ldapConfiguration.getBaseDn() >>> [null, null, "DC=cloud,DC=citrix,DC=com"]
+
+ LdapContext context = Mock(LdapContext);
+
+ when:
+ def result = adLdapUserManager.getUsersInGroup(group, context)
+ then:
+ thrown(IllegalArgumentException)
+ where:
+ group << [null, "group", null]
+
+ }
+}
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy
index adc3463afde..a4cf3c2878b 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy
@@ -25,6 +25,7 @@ import org.apache.cloudstack.framework.config.impl.ConfigurationVO
import org.apache.cloudstack.ldap.LdapConfiguration
import org.apache.cloudstack.ldap.LdapConfigurationVO
import org.apache.cloudstack.ldap.LdapManager
+import org.apache.cloudstack.ldap.dao.LdapConfigurationDao
import org.apache.cxf.common.util.StringUtils
import javax.naming.directory.SearchControls
@@ -33,8 +34,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
def "Test that getAuthentication returns none"() {
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
def configDao = Mock(ConfigurationDao)
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get authentication is called"
String authentication = ldapConfiguration.getAuthentication()
then: "none should be returned"
@@ -44,8 +45,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
def "Test that getAuthentication returns simple"() {
given: "We have a configDao, LdapManager and LdapConfiguration with bind principle and password set"
def configDao = Mock(ConfigurationDao)
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
configDao.getValue("ldap.bind.password") >> "password"
configDao.getValue("ldap.bind.principal") >> "cn=rmurphy,dc=cloudstack,dc=org"
when: "Get authentication is called"
@@ -58,8 +59,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
given: "We have a ConfigDao, LdapManager and ldapConfiguration with a baseDn value set."
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.basedn") >> "dc=cloudstack,dc=org"
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get basedn is called"
String baseDn = ldapConfiguration.getBaseDn();
then: "The set baseDn should be returned"
@@ -70,8 +71,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
given: "Given that we have a ConfigDao, LdapManager and LdapConfiguration"
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.email.attribute") >> "mail"
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get Email Attribute is called"
String emailAttribute = ldapConfiguration.getEmailAttribute()
then: "mail should be returned"
@@ -81,8 +82,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
def "Test that getFactory returns com.sun.jndi.ldap.LdapCtxFactory"() {
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
def configDao = Mock(ConfigurationDao)
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get Factory is scalled"
String factory = ldapConfiguration.getFactory();
then: "com.sun.jndi.ldap.LdapCtxFactory is returned"
@@ -93,8 +94,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.firstname.attribute") >> "givenname"
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get firstname attribute is called"
String firstname = ldapConfiguration.getFirstnameAttribute()
then: "givennam should be returned"
@@ -105,8 +106,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.lastname.attribute") >> "sn"
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get Lastname Attribute is scalled "
String lastname = ldapConfiguration.getLastnameAttribute()
then: "sn should be returned"
@@ -120,8 +121,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
configDao.getValue("ldap.lastname.attribute") >> "sn"
configDao.getValue("ldap.username.attribute") >> "uid"
configDao.getValue("ldap.email.attribute") >> "mail"
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get return attributes is called"
String[] returnAttributes = ldapConfiguration.getReturnAttributes()
then: "An array containing uid, mail, givenname, sn and cn is returned"
@@ -131,8 +132,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
def "Test that getScope returns SearchControls.SUBTREE_SCOPE"() {
given: "We have ConfigDao, LdapManager and LdapConfiguration"
def configDao = Mock(ConfigurationDao)
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get scope is called"
int scope = ldapConfiguration.getScope()
then: "SearchControls.SUBTRE_SCOPE should be returned"
@@ -143,8 +144,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
given: "We have ConfigDao, LdapManager and LdapConfiguration"
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.username.attribute") >> "uid"
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get Username Attribute is called"
String usernameAttribute = ldapConfiguration.getUsernameAttribute()
then: "uid should be returned"
@@ -155,8 +156,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.user.object") >> "inetOrgPerson"
- def ldapManager = Mock(LdapManager)
- def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "Get user object is called"
String userObject = ldapConfiguration.getUserObject()
then: "inetOrgPerson is returned"
@@ -166,14 +167,14 @@ class LdapConfigurationSpec extends spock.lang.Specification {
def "Test that providerUrl successfully returns a URL when a configuration is available"() {
given: "We have a ConfigDao, LdapManager, LdapConfiguration"
def configDao = Mock(ConfigurationDao)
- def ldapManager = Mock(LdapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
List ldapConfigurationList = new ArrayList()
ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
Pair, Integer> result = new Pair, Integer>();
result.set(ldapConfigurationList, ldapConfigurationList.size())
- ldapManager.listConfigurations(_) >> result
+ ldapConfigurationDao.searchConfigurations(_,_) >> result
- LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "A request is made to get the providerUrl"
String providerUrl = ldapConfiguration.getProviderUrl()
@@ -186,8 +187,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
given: "We have a ConfigDao with a value for ldap.search.group.principle and an LdapConfiguration"
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.search.group.principle") >> "cn=cloudstack,cn=users,dc=cloudstack,dc=org"
- def ldapManager = Mock(LdapManager)
- LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "A request is made to get the search group principle"
String result = ldapConfiguration.getSearchGroupPrinciple();
@@ -200,8 +201,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
given: "We have a ConfigDao with a value for truststore password"
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.truststore.password") >> "password"
- def ldapManager = Mock(LdapManager)
- LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "A request is made to get the truststore password"
String result = ldapConfiguration.getTrustStorePassword()
@@ -215,8 +216,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.truststore") >> "/tmp/ldap.ts"
configDao.getValue("ldap.truststore.password") >> "password"
- def ldapManager = Mock(LdapManager)
- LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
when: "A request is made to get the status of SSL"
boolean result = ldapConfiguration.getSSLStatus();
@@ -230,8 +231,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.group.object") >> groupObject
- def ldapManger = Mock(LdapManager)
- LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
def expectedResult = groupObject == null ? "groupOfUniqueNames" : groupObject
def result = ldapConfiguration.getGroupObject()
@@ -246,8 +247,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
def configDao = Mock(ConfigurationDao)
configDao.getValue("ldap.group.user.uniquemember") >> groupObject
- def ldapManger = Mock(LdapManager)
- LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
def expectedResult = groupObject == null ? "uniquemember" : groupObject
def result = ldapConfiguration.getGroupUniqueMemeberAttribute()
@@ -268,8 +269,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
configDepotImpl.global() >> configDao
ConfigKey.init(configDepotImpl)
- def ldapManger = Mock(LdapManager)
- LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger)
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
def expected = timeout == null ? 1000 : timeout.toLong() //1000 is the default value
@@ -280,4 +281,27 @@ class LdapConfigurationSpec extends spock.lang.Specification {
timeout << ["1000000", "1000", null]
}
+ def "Test getLdapProvider()"() {
+ given: "We have configdao for ldap group object"
+ def configDao = Mock(ConfigurationDao)
+ ConfigurationVO configurationVo = new ConfigurationVO("ldap.read.timeout", LdapConfiguration.ldapProvider);
+ configurationVo.setValue(provider)
+ configDao.findById("ldap.provider") >> configurationVo
+
+ def configDepotImpl = Mock(ConfigDepotImpl)
+ configDepotImpl.global() >> configDao
+ ConfigKey.init(configDepotImpl)
+
+ def ldapConfigurationDao = Mock(LdapConfigurationDao)
+ LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
+
+ def expected = provider == null ? "openldap" : provider //"openldap" is the default value
+
+ def result = ldapConfiguration.getLdapProvider()
+ expect:
+ result == expected
+ where:
+ provider << ["openldap", "microsoftad", null, "xyz"]
+ }
+
}
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
index c57cc7872df..1f17e704f52 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
@@ -57,7 +57,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
AccountService accountService = Mock(AccountService)
def ldapCreateAccountCmd = Spy(LdapCreateAccountCmd, constructorArgs: [ldapManager, accountService])
ldapCreateAccountCmd.getCurrentContext() >> Mock(CallContext)
- ldapCreateAccountCmd.createCloudstackUserAccount(_) >> null
+ ldapCreateAccountCmd.createCloudstackUserAccount(_, _, _) >> null
when: "Cloudstack fail to create the user"
ldapCreateAccountCmd.execute()
then: "An exception is thrown"
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy
index ee317206854..4c62a4eb67e 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy
@@ -41,8 +41,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapContextFactory.createBindContext() >> { throw new NoLdapUserMatchingQueryException() }
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "We search for a user but there is a bind issue"
ldapManager.getUser("rmurphy")
then: "an exception is thrown"
@@ -54,8 +57,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapContextFactory.createBindContext() >> { throw new NamingException() }
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "We search for a group of users but there is a bind issue"
ldapManager.getUsers()
then: "An exception is thrown"
@@ -67,8 +73,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapContextFactory.createBindContext() >> { throw new NamingException() }
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "We search for users"
ldapManager.searchUsers("rmurphy")
then: "An exception is thrown"
@@ -80,7 +89,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "A ldap configuration response is generated"
def result = ldapManager.createLdapConfigurationResponse(new LdapConfigurationVO("localhost", 389))
then: "the result of the response should match the given LdapConfigurationVO"
@@ -93,7 +105,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "A ldap user response is generated"
def result = ldapManager.createLdapUserResponse(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org",
"engineering"))
@@ -111,11 +126,14 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapContextFactory.createBindContext() >> null
List users = new ArrayList<>();
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null))
ldapUserManager.getUsers(_) >> users;
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "We search for a group of users"
def result = ldapManager.getUsers()
then: "A list greater than 0 is returned"
@@ -127,9 +145,12 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapContextFactory.createBindContext() >> null
ldapUserManager.getUser(_, _) >> new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null)
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "We search for a user"
def result = ldapManager.getUser("rmurphy")
then: "The user is returned"
@@ -145,7 +166,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "The context is closed"
def context = Mock(InitialLdapContext)
ldapManager.closeContext(context)
@@ -159,7 +183,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapContextFactory = Mock(LdapContextFactory)
ldapContextFactory.createUserContext(_, _) >> { throw new NamingException() }
def ldapUserManager = Mock(LdapUserManager)
- def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapConfiguration = Mock(LdapConfiguration)
+ def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration])
ldapManager.getUser(_) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null) }
when: "The user attempts to authenticate with a bad password"
def result = ldapManager.canAuthenticate("rmurphy", "password")
@@ -172,7 +199,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
- def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapConfiguration = Mock(LdapConfiguration)
+ def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration])
ldapManager.getUser(_) >> { throw new NamingException() }
when: "The user attempts to authenticate and the user is not found"
def result = ldapManager.canAuthenticate("rmurphy", "password")
@@ -185,8 +215,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapConfigurationDao.findByHostname(_) >> null
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "A ldap configuration that doesn't exist is deleted"
ldapManager.deleteConfiguration("localhost")
then: "A exception is thrown"
@@ -198,7 +231,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "The context is closed"
def context = Mock(InitialLdapContext)
context.close() >> { throw new NamingException() }
@@ -213,7 +249,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapContextFactory = Mock(LdapContextFactory)
ldapContextFactory.createUserContext(_, _) >> null
def ldapUserManager = Mock(LdapUserManager)
- def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration])
ldapManager.getUser(_) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null) }
when: "A user authenticates"
def result = ldapManager.canAuthenticate("rmurphy", "password")
@@ -226,13 +265,16 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapConfiguration = Mock(LdapConfiguration)
ldapConfigurationDao.findByHostname(_) >> {
def configuration = new LdapConfigurationVO("localhost", 389)
configuration.setId(0);
return configuration;
}
ldapConfigurationDao.remove(_) >> null
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "A ldap configuration is deleted"
def result = ldapManager.deleteConfiguration("localhost")
then: "The deleted configuration is returned"
@@ -245,13 +287,16 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapConfiguration = Mock(LdapConfiguration)
ldapContextFactory.createBindContext() >> null;
List users = new ArrayList();
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering"))
ldapUserManager.getUsers(_, _) >> users;
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "We search for users"
def result = ldapManager.searchUsers("rmurphy");
then: "A list of atleast 1 is returned"
@@ -263,9 +308,12 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapContextFactory.createBindContext(_) >> null
ldapConfigurationDao.persist(_) >> null
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "A ldap configuration is added"
def result = ldapManager.addConfiguration("localhost", 389)
then: "the resulting object contain the given hostname and port"
@@ -278,8 +326,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapContextFactory.createBindContext(_) >> { throw new NamingException() }
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "A configuration is added that can not be binded"
ldapManager.addConfiguration("localhost", 389)
then: "An exception is thrown"
@@ -291,8 +342,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapConfigurationDao.findByHostname(_) >> new LdapConfigurationVO("localhost", 389)
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "a configuration that already exists is added"
ldapManager.addConfiguration("localhost", 389)
then: "An exception is thrown"
@@ -318,8 +372,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
+ def ldapConfiguration = Mock(LdapConfiguration)
final List> cmdList = supportedLdapCommands()
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "Get commands is called"
def result = ldapManager.getCommands()
then: "it must return all the commands"
@@ -332,12 +389,15 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
List ldapConfigurationList = new ArrayList()
ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
Pair, Integer> configurations = new Pair, Integer>();
configurations.set(ldapConfigurationList, ldapConfigurationList.size())
ldapConfigurationDao.searchConfigurations(_, _) >> configurations
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "A request for configurations is made"
def result = ldapManager.listConfigurations(new LdapListConfigurationCmd())
then: "Then atleast 1 ldap configuration is returned"
@@ -349,12 +409,15 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
List ldapConfigurationList = new ArrayList()
ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
Pair, Integer> configurations = new Pair, Integer>();
configurations.set(ldapConfigurationList, ldapConfigurationList.size())
ldapConfigurationDao.searchConfigurations(_, _) >> configurations
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "A request to find out is ldap enabled"
def result = ldapManager.isLdapEnabled();
then: "true is returned because a configuration was found"
@@ -366,11 +429,14 @@ class LdapManagerImplSpec extends spock.lang.Specification {
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
def ldapContextFactory = Mock(LdapContextFactory)
def ldapUserManager = Mock(LdapUserManager)
+ def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
+ def ldapConfiguration = Mock(LdapConfiguration)
+ ldapUserManagerFactory.getInstance(_) >> ldapUserManager
ldapContextFactory.createBindContext() >> null
List users = new ArrayList<>();
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", "engineering"))
ldapUserManager.getUsersInGroup("engineering", _) >> users;
- def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+ def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
when: "We search for a group of users"
def result = ldapManager.getUsersInGroup("engineering")
then: "A list greater of size one is returned"
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerFactorySpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerFactorySpec.groovy
new file mode 100644
index 00000000000..7615f9d5305
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerFactorySpec.groovy
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.org.apache.cloudstack.ldap
+
+import org.apache.cloudstack.ldap.ADLdapUserManagerImpl
+import org.apache.cloudstack.ldap.LdapUserManagerFactory
+import org.apache.cloudstack.ldap.OpenLdapUserManagerImpl
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory
+import org.springframework.context.ApplicationContext
+import spock.lang.Shared
+
+class LdapUserManagerFactorySpec extends spock.lang.Specification {
+
+ @Shared
+ def LdapUserManagerFactory ldapUserManagerFactory;
+
+ def setupSpec() {
+ ldapUserManagerFactory = new LdapUserManagerFactory();
+ ApplicationContext applicationContext = Mock(ApplicationContext);
+ AutowireCapableBeanFactory autowireCapableBeanFactory = Mock(AutowireCapableBeanFactory);
+ applicationContext.getAutowireCapableBeanFactory() >> autowireCapableBeanFactory;
+ ldapUserManagerFactory.setApplicationContext(applicationContext);
+ }
+
+ def "Test getInstance() from factory"() {
+ def result = ldapUserManagerFactory.getInstance(id);
+
+ def expected;
+ if(id == "microsoftad") {
+ expected = ADLdapUserManagerImpl.class;
+ } else {
+ expected = OpenLdapUserManagerImpl.class;
+ }
+
+ expect:
+ assert result.class.is(expected)
+ where:
+ id << ["openldap", "microsoftad", null, "xyz"]
+ }
+}
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/OpenLdapUserManagerSpec.groovy
similarity index 92%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy
rename to plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/OpenLdapUserManagerSpec.groovy
index d1f3667b8c6..cb08c8fd47c 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/OpenLdapUserManagerSpec.groovy
@@ -18,6 +18,7 @@ package groovy.org.apache.cloudstack.ldap
import org.apache.cloudstack.ldap.LdapConfiguration
import org.apache.cloudstack.ldap.LdapUserManager
+import org.apache.cloudstack.ldap.OpenLdapUserManagerImpl
import spock.lang.Shared
import javax.naming.NamingException
@@ -29,7 +30,7 @@ import javax.naming.directory.SearchResult
import javax.naming.ldap.InitialLdapContext
import javax.naming.ldap.LdapContext
-class LdapUserManagerSpec extends spock.lang.Specification {
+class OpenLdapUserManagerSpec extends spock.lang.Specification {
@Shared
private def ldapConfiguration
@@ -184,7 +185,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
given: "We have attributes, a search and a user manager"
def attributes = createUserAttributes(username, email, firstname, lastname)
def search = createSearchResult(attributes)
- def userManager = new LdapUserManager(ldapConfiguration)
+ def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
def result = userManager.createUser(search)
expect: "The crated user the data supplied from LDAP"
@@ -199,7 +200,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def "Test successfully returning a list from get users"() {
given: "We have a LdapUserManager"
- def userManager = new LdapUserManager(ldapConfiguration)
+ def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
when: "A request for users is made"
def result = userManager.getUsers(username, createContext())
@@ -211,7 +212,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def "Test successfully returning a list from get users when no username is given"() {
given: "We have a LdapUserManager"
- def userManager = new LdapUserManager(ldapConfiguration)
+ def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
when: "Get users is called without a username"
def result = userManager.getUsers(createContext())
@@ -222,7 +223,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def "Test successfully returning a ldap user from searchUsers"() {
given: "We have a LdapUserManager"
- def userManager = new LdapUserManager(ldapConfiguration)
+ def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
when: "We search for users"
def result = userManager.searchUsers(createContext())
@@ -234,7 +235,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def "Test successfully returning an Ldap user from a get user request"() {
given: "We have a LdapUserMaanger"
- def userManager = new LdapUserManager(ldapConfiguration)
+ def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
when: "A request for a user is made"
def result = userManager.getUser(username, createContext())
@@ -255,7 +256,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def context = Mock(LdapContext)
context.search(_, _, _) >> searchUsersResults;
- def userManager = new LdapUserManager(ldapConfiguration)
+ def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
when: "a get user request is made and no user is found"
def result = userManager.getUser(username, context)
@@ -266,14 +267,14 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def "Test that a newly created Ldap User Manager is not null"() {
given: "You have created a new Ldap user manager object"
- def result = new LdapUserManager();
+ def result = new OpenLdapUserManagerImpl();
expect: "The result is not null"
result != null
}
def "test successful generateGroupSearchFilter"() {
given: "ldap user manager and ldap config"
- def ldapUserManager = new LdapUserManager(ldapConfiguration)
+ def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
def groupName = varGroupName == null ? "*" : varGroupName
def expectedResult = "(&(objectClass=groupOfUniqueNames)(cn=" + groupName + "))";
@@ -286,7 +287,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def "test successful getUsersInGroup one user"() {
given: "ldap user manager and ldap config"
- def ldapUserManager = new LdapUserManager(ldapConfiguration)
+ def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
when: "A request for users is made"
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextOneUser())
@@ -296,7 +297,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def "test successful getUsersInGroup no user"() {
given: "ldap user manager and ldap config"
- def ldapUserManager = new LdapUserManager(ldapConfiguration)
+ def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
when: "A request for users is made"
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextNoUser())
@@ -306,7 +307,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
def "test successful getUserForDn"() {
given: "ldap user manager and ldap config"
- def ldapUserManager = new LdapUserManager(ldapConfiguration)
+ def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
when: "A request for users is made"
def result = ldapUserManager.getUserForDn("cn=Ryan Murphy,ou=engineering,dc=cloudstack,dc=org", createContext())
@@ -324,7 +325,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
given: "ldap configuration where basedn is not set"
def ldapconfig = Mock(LdapConfiguration)
ldapconfig.getBaseDn() >> null
- def ldapUserManager = new LdapUserManager(ldapconfig)
+ def ldapUserManager = new OpenLdapUserManagerImpl(ldapconfig)
when: "A request for search users is made"
def result = ldapUserManager.searchUsers(new InitialLdapContext())