cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wid...@apache.org
Subject [25/50] [abbrv] git commit: updated refs/heads/reporter to 3e1816d
Date Mon, 27 Jul 2015 08:43:13 GMT
CLOUDSTACK-8596 ability to query nested groups for Microsoft AD

added a new configuration to select the appropriate ldap implementation
incase of microsoft AD enabled nested querying of group members

moved LdapUserManager to an interface and added separate implementations
for openLdap and microsoft AD
Added unit tests


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4e57cc62
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4e57cc62
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4e57cc62

Branch: refs/heads/reporter
Commit: 4e57cc62d0838f74b09f06d741c9b7cf532abd56
Parents: 4bba499
Author: Rajani Karuturi <rajanikaruturi@gmail.com>
Authored: Mon Jul 20 17:56:54 2015 +0530
Committer: Rajani Karuturi <rajanikaruturi@gmail.com>
Committed: Mon Jul 20 18:00:57 2015 +0530

----------------------------------------------------------------------
 .../cloudstack/ldap/spring-ldap-context.xml     |   2 +-
 .../cloudstack/ldap/ADLdapUserManagerImpl.java  |  81 +++++
 .../cloudstack/ldap/LdapConfiguration.java      |  16 +-
 .../apache/cloudstack/ldap/LdapManagerImpl.java |  19 +-
 .../apache/cloudstack/ldap/LdapUserManager.java | 239 ++-----------
 .../cloudstack/ldap/LdapUserManagerFactory.java |  55 +++
 .../ldap/OpenLdapUserManagerImpl.java           | 233 +++++++++++++
 .../ldap/ADLdapUserManagerImplSpec.groovy       |  70 ++++
 .../ldap/LdapConfigurationSpec.groovy           |  98 ++++--
 .../ldap/LdapCreateAccountCmdSpec.groovy        |   2 +-
 .../cloudstack/ldap/LdapManagerImplSpec.groovy  | 110 ++++--
 .../ldap/LdapUserManagerFactorySpec.groovy      |  56 +++
 .../cloudstack/ldap/LdapUserManagerSpec.groovy  | 336 ------------------
 .../ldap/OpenLdapUserManagerSpec.groovy         | 337 +++++++++++++++++++
 14 files changed, 1031 insertions(+), 623 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml
----------------------------------------------------------------------
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 34a2bef..8ae4009 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 @@
     </bean>
 
     <bean id="LdapManager" class="org.apache.cloudstack.ldap.LdapManagerImpl" />
-    <bean id="LdapUserManager" class="org.apache.cloudstack.ldap.LdapUserManager" />
+    <bean id="LdapUserManagerFactory" class="org.apache.cloudstack.ldap.LdapUserManagerFactory" />
     <bean id="LdapContextFactory" class="org.apache.cloudstack.ldap.LdapContextFactory" />
     <bean id="LdapConfigurationDao"
         class="org.apache.cloudstack.ldap.dao.LdapConfigurationDaoImpl" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java
----------------------------------------------------------------------
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 0000000..e5e20c5
--- /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<LdapUser> 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<SearchResult> results = context.search(basedn, generateADGroupSearchFilter(groupName), searchControls);
+        final List<LdapUser> users = new ArrayList<LdapUser>();
+        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();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java
----------------------------------------------------------------------
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 c171ebf..f247f40 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<Integer> ldapPageSize = new ConfigKey<Integer>(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<String> ldapProvider = new ConfigKey<String>(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<List<? extends LdapConfigurationVO>, Integer> result = _ldapManager.listConfigurations(new LdapListConfigurationCmd(_ldapManager));
+        final Pair<List<LdapConfigurationVO>, 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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
----------------------------------------------------------------------
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 dfd39a3..8e912b8 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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
----------------------------------------------------------------------
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 654a601..28fc74e 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<LdapUser> getUsers(final LdapContext context) throws NamingException, IOException;
 
-    public LdapUserManager() {
-    }
+    public List<LdapUser> getUsers(final String username, final LdapContext context) throws NamingException, IOException;
 
-    public LdapUserManager(final LdapConfiguration ldapConfiguration) {
-        _ldapConfiguration = ldapConfiguration;
-    }
+    public List<LdapUser> getUsersInGroup(String groupName, LdapContext context) throws NamingException;
 
-    private LdapUser createUser(final SearchResult result) throws NamingException {
-        final Attributes attributes = result.getAttributes();
+    public List<LdapUser> 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<LdapUser> 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<LdapUser> getUsers(final LdapContext context) throws NamingException, IOException {
-        return getUsers(null, context);
-    }
-
-    public List<LdapUser> getUsers(final String username, final LdapContext context) throws NamingException, IOException {
-        List<LdapUser> users = searchUsers(username, context);
-
-        if (CollectionUtils.isNotEmpty(users)) {
-            Collections.sort(users);
-        }
-        return users;
-    }
-
-    public List<LdapUser> 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<SearchResult> result = context.search(_ldapConfiguration.getBaseDn(), generateGroupSearchFilter(groupName), controls);
-
-        final List<LdapUser> users = new ArrayList<LdapUser>();
-        //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<SearchResult> 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<LdapUser> searchUsers(final LdapContext context) throws NamingException, IOException {
-        return searchUsers(null, context);
-    }
-
-    public List<LdapUser> 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<LdapUser> users = new ArrayList<LdapUser>();
-        NamingEnumeration<SearchResult> 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<LdapUser> searchUsers(final String username, final LdapContext context) throws NamingException, IOException;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManagerFactory.java
----------------------------------------------------------------------
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 0000000..35652fb
--- /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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java
----------------------------------------------------------------------
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 0000000..11e6bcf
--- /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<LdapUser> 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<LdapUser> getUsers(final LdapContext context) throws NamingException, IOException {
+        return getUsers(null, context);
+    }
+
+    @Override
+    public List<LdapUser> getUsers(final String username, final LdapContext context) throws NamingException, IOException {
+        List<LdapUser> users = searchUsers(username, context);
+
+        if (CollectionUtils.isNotEmpty(users)) {
+            Collections.sort(users);
+        }
+        return users;
+    }
+
+    @Override
+    public List<LdapUser> 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<SearchResult> result = context.search(_ldapConfiguration.getBaseDn(), generateGroupSearchFilter(groupName), controls);
+
+        final List<LdapUser> users = new ArrayList<LdapUser>();
+        //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<SearchResult> 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<LdapUser> searchUsers(final LdapContext context) throws NamingException, IOException {
+        return searchUsers(null, context);
+    }
+
+    @Override
+    public List<LdapUser> 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<LdapUser> users = new ArrayList<LdapUser>();
+        NamingEnumeration<SearchResult> 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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/ADLdapUserManagerImplSpec.groovy
----------------------------------------------------------------------
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 0000000..6fafa3ed
--- /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]
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy
----------------------------------------------------------------------
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 adc3463..a4cf3c2 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<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
         ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
         Pair<List<LdapConfigurationVO>, Integer> result = new Pair<List<LdapConfigurationVO>, 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"]
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
----------------------------------------------------------------------
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 c57cc78..1f17e70 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"

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy
----------------------------------------------------------------------
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 ee31720..4c62a4e 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<LdapUser> 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<LdapUser> users = new ArrayList<LdapUser>();
         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<Class<?>> 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<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
         ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
         Pair<List<LdapConfigurationVO>, Integer> configurations = new Pair<List<LdapConfigurationVO>, 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<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
         ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
         Pair<List<LdapConfigurationVO>, Integer> configurations = new Pair<List<LdapConfigurationVO>, 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<LdapUser> 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"

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4e57cc62/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerFactorySpec.groovy
----------------------------------------------------------------------
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 0000000..7615f9d
--- /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"]
+    }
+}


Mime
View raw message