You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ap...@apache.org on 2013/07/25 14:28:35 UTC

[2/4] Merge LDAPPlugin

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/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
new file mode 100644
index 0000000..548057c
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy
@@ -0,0 +1,319 @@
+// 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 javax.naming.NamingException
+import javax.naming.ldap.InitialLdapContext
+
+import org.apache.cloudstack.api.command.LdapListConfigurationCmd
+import org.apache.cloudstack.ldap.*
+import org.apache.cloudstack.ldap.dao.LdapConfigurationDaoImpl
+
+import com.cloud.exception.InvalidParameterValueException
+import com.cloud.utils.Pair
+
+class LdapManagerImplSpec extends spock.lang.Specification {
+    def "Test that addConfiguration fails when a duplicate configuration exists"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapConfigurationDao.findByHostname(_) >> new LdapConfigurationVO("localhost", 389)
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        ldapManager.addConfiguration("localhost", 389)
+        then:
+        thrown InvalidParameterValueException
+    }
+
+    def "Test that addConfiguration fails when a binding fails"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapContextFactory.createBindContext(_) >> { throw new NamingException() }
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        ldapManager.addConfiguration("localhost", 389)
+        then:
+        thrown InvalidParameterValueException
+    }
+
+    def "Test successfully addConfiguration"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapContextFactory.createBindContext(_) >> null
+        ldapConfigurationDao.persist(_) >> null
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def result = ldapManager.addConfiguration("localhost", 389)
+        then:
+        result.hostname == "localhost"
+        result.port == 389
+    }
+
+    def "Test successful failed result from deleteConfiguration due to configuration not existing"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapConfigurationDao.findByHostname(_) >> null
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        ldapManager.deleteConfiguration("localhost")
+        then:
+        thrown InvalidParameterValueException
+    }
+
+    def "Test successful result from deleteConfiguration"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapConfigurationDao.findByHostname(_) >> {
+            def configuration = new LdapConfigurationVO("localhost", 389)
+            configuration.setId(0);
+            return configuration;
+        }
+        ldapConfigurationDao.remove(_) >> null
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def result = ldapManager.deleteConfiguration("localhost")
+        then:
+        result.hostname == "localhost"
+        result.port == 389
+    }
+
+    def "Test successful failed result from canAuthenticate due to user not found"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
+        ldapManager.getUser(_) >> { throw new NamingException() }
+        when:
+        def result = ldapManager.canAuthenticate("rmurphy", "password")
+        then:
+        result == false
+    }
+
+    def "Test successful failed result from canAuthenticate due to bad password"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        ldapContextFactory.createUserContext(_, _) >> { throw new NamingException() }
+        def ldapUserManager = Mock(LdapUserManager)
+        def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
+        ldapManager.getUser(_) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org") }
+        when:
+        def result = ldapManager.canAuthenticate("rmurphy", "password")
+        then:
+        result == false
+    }
+
+    def "Test successful result from canAuthenticate"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        ldapContextFactory.createUserContext(_, _) >> null
+        def ldapUserManager = Mock(LdapUserManager)
+        def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
+        ldapManager.getUser(_) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org") }
+        when:
+        def result = ldapManager.canAuthenticate("rmurphy", "password")
+        then:
+        result == true
+    }
+
+    def "Test successful closing of context"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def context = Mock(InitialLdapContext)
+        ldapManager.closeContext(context)
+        then:
+        context.defaultInitCtx == null
+    }
+
+    def "Test successful failing to close of context"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def context = Mock(InitialLdapContext)
+        context.close() >> { throw new NamingException() }
+        ldapManager.closeContext(context)
+        then:
+        context.defaultInitCtx == null
+    }
+
+    def "Test LdapConfigurationResponse generation"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def result = ldapManager.createLdapConfigurationResponse(new LdapConfigurationVO("localhost", 389))
+        then:
+        result.hostname == "localhost"
+        result.port == 389
+    }
+
+    def "Test LdapUserResponse generation"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def result = ldapManager.createLdapUserResponse(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org"))
+        then:
+        result.username == "rmurphy"
+        result.email == "rmurphy@test.com"
+        result.firstname == "Ryan"
+        result.lastname == "Murphy"
+        result.principal == "cn=rmurphy,dc=cloudstack,dc=org"
+    }
+
+    def "Test that getCommands isn't empty"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def result = ldapManager.getCommands()
+        then:
+        result.size() > 0
+    }
+
+    def "Test failing of getUser due to bind issue"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapContextFactory.createBindContext() >> { throw new NamingException() }
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        ldapManager.getUser("rmurphy")
+        then:
+        thrown NamingException
+    }
+
+    def "Test success of getUser"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapContextFactory.createBindContext() >> null
+        ldapUserManager.getUser(_, _) >> new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org")
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def result = ldapManager.getUser("rmurphy")
+        then:
+        result.username == "rmurphy"
+        result.email == "rmurphy@test.com"
+        result.firstname == "Ryan"
+        result.lastname == "Murphy"
+        result.principal == "cn=rmurphy,dc=cloudstack,dc=org"
+    }
+
+    def "Test failing of getUsers due to bind issue"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapContextFactory.createBindContext() >> { throw new NamingException() }
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        ldapManager.getUsers()
+        then:
+        thrown NoLdapUserMatchingQueryException
+    }
+
+    def "Test success getUsers"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(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"))
+        ldapUserManager.getUsers(_) >> users;
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def result = ldapManager.getUsers()
+        then:
+        result.size() > 0;
+    }
+
+    def "Testing of listConfigurations"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(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)
+        when:
+        def result = ldapManager.listConfigurations(new LdapListConfigurationCmd())
+        then:
+        result.second() > 0
+    }
+
+    def "Test failing of searchUsers due to a failure to bind"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapContextFactory.createBindContext() >> { throw new NamingException() }
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        ldapManager.searchUsers("rmurphy")
+        then:
+        thrown NoLdapUserMatchingQueryException
+    }
+
+    def "Test successful result from searchUsers"() {
+        given:
+        def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
+        def ldapContextFactory = Mock(LdapContextFactory)
+        def ldapUserManager = Mock(LdapUserManager)
+        ldapContextFactory.createBindContext() >> null;
+
+        List<LdapUser> users = new ArrayList<LdapUser>();
+        users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org"))
+        ldapUserManager.getUsers(_, _) >> users;
+
+        def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
+        when:
+        def result = ldapManager.searchUsers("rmurphy");
+        then:
+        result.size() > 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy
new file mode 100644
index 0000000..b23d7c2
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy
@@ -0,0 +1,72 @@
+// 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.api.ServerApiException
+import org.apache.cloudstack.api.command.LdapUserSearchCmd
+import org.apache.cloudstack.api.response.LdapUserResponse
+import org.apache.cloudstack.ldap.LdapManager
+import org.apache.cloudstack.ldap.LdapUser
+import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException
+
+class LdapSearchUserCmdSpec extends spock.lang.Specification {
+    def "Test successful response from execute"() {
+        given:
+        def ldapManager = Mock(LdapManager)
+        List<LdapUser> users = new ArrayList()
+        users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org"))
+        ldapManager.searchUsers(_) >> users
+        LdapUserResponse response = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org")
+        ldapManager.createLdapUserResponse(_) >> response
+        def ldapUserSearchCmd = new LdapUserSearchCmd(ldapManager)
+        when:
+        ldapUserSearchCmd.execute()
+        then:
+        ldapUserSearchCmd.responseObject.getResponses().size() != 0
+    }
+
+    def "Test successful empty response from execute"() {
+        given:
+        def ldapManager = Mock(LdapManager)
+        ldapManager.searchUsers(_) >> {throw new NoLdapUserMatchingQueryException()}
+        def ldapUserSearchCmd = new LdapUserSearchCmd(ldapManager)
+        when:
+        ldapUserSearchCmd.execute()
+        then:
+        ldapUserSearchCmd.responseObject.getResponses().size() == 0
+    }
+
+    def "Test getEntityOwnerId is 0"() {
+        given:
+        def ldapManager = Mock(LdapManager)
+        def ldapUserSearchCmd = new LdapUserSearchCmd(ldapManager)
+        when:
+        long ownerId = ldapUserSearchCmd.getEntityOwnerId()
+        then:
+        ownerId == 1
+    }
+
+    def "Test successful return of getCommandName"() {
+        given:
+        def ldapManager = Mock(LdapManager)
+        def ldapUserSearchCmd = new LdapUserSearchCmd(ldapManager)
+        when:
+        String commandName = ldapUserSearchCmd.getCommandName()
+        then:
+        commandName == "ldapuserresponse"
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy
----------------------------------------------------------------------
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/LdapUserManagerSpec.groovy
new file mode 100644
index 0000000..2d31aa6
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy
@@ -0,0 +1,207 @@
+// 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.LdapConfiguration
+import org.apache.cloudstack.ldap.LdapUserManager
+import spock.lang.Shared
+
+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.LdapContext
+
+class LdapUserManagerSpec extends spock.lang.Specification {
+
+    @Shared
+    private def ldapConfiguration
+
+    @Shared
+    private def username
+
+    @Shared
+    private def email
+
+    @Shared
+    private def firstname
+
+    @Shared
+    private def lastname
+
+    @Shared
+    private def principal
+
+    def setupSpec() {
+        ldapConfiguration = Mock(LdapConfiguration)
+
+        ldapConfiguration.getScope() >> SearchControls.SUBTREE_SCOPE
+        ldapConfiguration.getReturnAttributes() >> ["uid", "mail", "cn"]
+        ldapConfiguration.getUsernameAttribute() >> "uid"
+        ldapConfiguration.getEmailAttribute() >> "mail"
+        ldapConfiguration.getFirstnameAttribute() >> "givenname"
+        ldapConfiguration.getLastnameAttribute() >> "sn"
+        ldapConfiguration.getBaseDn() >> "dc=cloudstack,dc=org"
+
+        username = "rmurphy"
+        email = "rmurphy@test.com"
+        firstname = "Ryan"
+        lastname = "Murphy"
+        principal = "cn=" + username + "," + ldapConfiguration.getBaseDn()
+    }
+
+    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();
+        expect: "The result is not null"
+        result != null
+    }
+
+    def "Test successfully creating an Ldap User from Search result"() {
+        given:
+        def attributes = createUserAttributes(username, email, firstname, lastname)
+        def search = createSearchResult(attributes)
+        def userManager = new LdapUserManager(ldapConfiguration)
+        def result = userManager.createUser(search)
+
+        expect:
+
+        result.username == username
+        result.email == email
+        result.firstname == firstname
+        result.lastname == lastname
+        result.principal == principal
+    }
+
+    def "Test successfully returning an Ldap user from a get user request"() {
+        given:
+
+        def userManager = new LdapUserManager(ldapConfiguration)
+
+        when:
+        def result = userManager.getUser(username, createContext())
+
+        then:
+        result.username == username
+        result.email == email
+        result.firstname == firstname
+        result.lastname == lastname
+        result.principal == principal
+    }
+
+    def "Test successfully returning a list from get users"() {
+        given:
+
+        def userManager = new LdapUserManager(ldapConfiguration)
+
+        when:
+        def result = userManager.getUsers(username, createContext())
+
+        then:
+        result.size() == 1
+    }
+
+    def "Test successfully returning a list from get users when no username is given"() {
+        given:
+
+        def userManager = new LdapUserManager(ldapConfiguration)
+
+        when:
+        def result = userManager.getUsers(createContext())
+
+        then:
+        result.size() == 1
+    }
+
+    def "Test successfully throwing an exception when no users are found with getUser"() {
+        given:
+
+        def searchUsersResults = new BasicNamingEnumerationImpl()
+
+        def context = Mock(LdapContext)
+        context.search(_, _, _) >> searchUsersResults;
+
+        def userManager = new LdapUserManager(ldapConfiguration)
+
+        when:
+        def result = userManager.getUser(username, context)
+
+        then:
+        thrown NamingException
+    }
+
+    def "Test successfully returning a NamingEnumeration from searchUsers"() {
+        given:
+        def userManager = new LdapUserManager(ldapConfiguration)
+
+        when:
+        def result = userManager.searchUsers(createContext())
+
+        then:
+        result.next().getName() + "," + ldapConfiguration.getBaseDn() == principal
+    }
+
+    private def createContext() {
+
+        Attributes attributes = createUserAttributes(username, email, firstname, lastname)
+        SearchResult searchResults = createSearchResult(attributes)
+        def searchUsersResults = new BasicNamingEnumerationImpl()
+        searchUsersResults.add(searchResults);
+
+        def context = Mock(LdapContext)
+        context.search(_, _, _) >> searchUsersResults;
+
+        return context
+    }
+
+    private SearchResult createSearchResult(attributes) {
+        def search = Mock(SearchResult)
+
+        search.getName() >> "cn=" + attributes.getAt("uid").get();
+
+        search.getAttributes() >> attributes
+
+        return search
+    }
+
+    private Attributes createUserAttributes(String username, String email, String firstname, String lastname) {
+        def attributes = Mock(Attributes)
+
+        def nameAttribute = Mock(Attribute)
+        nameAttribute.getId() >> "uid"
+        nameAttribute.get() >> username
+        attributes.get("uid") >> nameAttribute
+
+        def mailAttribute = Mock(Attribute)
+        mailAttribute.getId() >> "mail"
+        mailAttribute.get() >> email
+        attributes.get("mail") >> mailAttribute
+
+        def givennameAttribute = Mock(Attribute)
+        givennameAttribute.getId() >> "givenname"
+        givennameAttribute.get() >> firstname
+        attributes.get("givenname") >> givennameAttribute
+
+        def snAttribute = Mock(Attribute)
+        snAttribute.getId() >> "sn"
+        snAttribute.get() >> lastname
+        attributes.get("sn") >> snAttribute
+
+        return attributes
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy
new file mode 100644
index 0000000..aa7d5a3
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy
@@ -0,0 +1,67 @@
+// 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.api.response.LdapUserResponse
+
+
+class LdapUserResponseSpec extends spock.lang.Specification {
+    def "Testing succcessful setting of LdapUserResponse email"() {
+        given:
+        LdapUserResponse response = new LdapUserResponse();
+        when:
+        response.setEmail("rmurphy@test.com");
+        then:
+        response.getEmail() == "rmurphy@test.com";
+    }
+
+    def "Testing successful setting of LdapUserResponse principal"() {
+        given:
+        LdapUserResponse response = new LdapUserResponse()
+        when:
+        response.setPrincipal("dc=cloudstack,dc=org")
+        then:
+        response.getPrincipal() == "dc=cloudstack,dc=org"
+    }
+
+    def "Testing successful setting of LdapUserResponse username"() {
+        given:
+        LdapUserResponse response = new LdapUserResponse()
+        when:
+        response.setUsername("rmurphy")
+        then:
+        response.getUsername() == "rmurphy"
+    }
+
+    def "Testing successful setting of LdapUserResponse firstname"() {
+        given:
+        LdapUserResponse response = new LdapUserResponse()
+        when:
+        response.setFirstname("Ryan")
+        then:
+        response.getFirstname() == "Ryan"
+    }
+
+    def "Testing successful setting of LdapUserResponse lastname"() {
+        given:
+        LdapUserResponse response = new LdapUserResponse()
+        when:
+        response.setLastname("Murphy")
+        then:
+        response.getLastname() == "Murphy"
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
new file mode 100644
index 0000000..cf2f9ec
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
@@ -0,0 +1,79 @@
+// 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.LdapUser
+
+class LdapUserSpec extends spock.lang.Specification {
+
+    def "Testing that the username is correctly set with the ldap object"() {
+        given: "You have created a LDAP user object with a username"
+        def user = new LdapUser(username, "", "", "","")
+        expect: "The username is equal to the given data source"
+        user.getUsername() == username
+        where: "The username is set to "
+        username << ["", null, "rmurphy"]
+    }
+
+    def "Testing the email is correctly set with the ldap object"() {
+        given: "You have created a LDAP user object with a email"
+        def user = new LdapUser("", email, "", "","")
+        expect: "The email is equal to the given data source"
+        user.getEmail() == email
+        where: "The email is set to "
+        email << ["", null, "test@test.com"]
+    }
+
+    def "Testing the firstname is correctly set with the ldap object"() {
+        given: "You have created a LDAP user object with a firstname"
+        def user = new LdapUser("", "", firstname, "", "")
+        expect: "The firstname is equal to the given data source"
+        user.getFirstname() == firstname
+        where: "The firstname is set to "
+        firstname << ["", null, "Ryan"]
+    }
+
+    def "Testing the lastname is correctly set with the ldap object"() {
+        given: "You have created a LDAP user object with a lastname"
+        def user = new LdapUser("", "", "", lastname, "")
+        expect: "The lastname is equal to the given data source"
+        user.getLastname() == lastname
+        where: "The lastname is set to "
+        lastname << ["", null, "Murphy"]
+    }
+
+    def "Testing the principal is correctly set with the ldap object"() {
+        given: "You have created a LDAP user object with a principal"
+        def user = new LdapUser("", "", "", "", principal)
+        expect: "The principal is equal to the given data source"
+        user.getPrincipal() == principal
+        where: "The username is set to "
+        principal << ["", null, "cn=rmurphy,dc=cloudstack,dc=org"]
+    }
+
+    def "Testing that LdapUser successfully gives the correct result for a compare to"() {
+        given: "You have created two LDAP user objects"
+        def userA = new LdapUser(usernameA, "", "", "", "")
+        def userB = new LdapUser(usernameB, "", "", "", "")
+        expect: "That when compared the result is less than or equal to 0"
+        userA.compareTo(userB) <= 0
+        where: "The following values are used"
+        usernameA | usernameB
+        "A"       | "B"
+        "A"       | "A"
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy
new file mode 100644
index 0000000..7fc05a9
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy
@@ -0,0 +1,68 @@
+// 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.LdapUtils
+
+import javax.naming.directory.Attribute
+import javax.naming.directory.Attributes
+
+class LdapUtilsSpec extends spock.lang.Specification {
+    def "Testing that a Ldap Search Filter is correctly escaped"() {
+        given: "You have some input from a user"
+
+        expect: "That the input is escaped"
+        LdapUtils.escapeLDAPSearchFilter(input) == result
+
+        where: "The following inputs are given "
+        input                                       | result
+        "Hi This is a test #çà"                     | "Hi This is a test #çà"
+        "Hi (This) = is * a \\ test # ç à ô \u0000" | "Hi \\28This\\29 = is \\2a a \\5c test # ç à ô \\00"
+    }
+
+    def "Testing than an attribute is successfully returned"() {
+        given: "You have an attributes object with some attribute"
+        def attributes = Mock(Attributes)
+        def attribute = Mock(Attribute)
+        attribute.getId() >> name
+        attribute.get() >> value
+        attributes.get(name) >> attribute
+
+        when: "You get the attribute"
+        String foundValue = LdapUtils.getAttributeValue(attributes, name)
+
+        then: "Its value equals uid"
+        foundValue == value
+
+        where:
+        name    | value
+        "uid"   | "rmurphy"
+        "email" | "rmurphy@test.com"
+    }
+
+    def "Testing than an attribute is not successfully returned"() {
+        given: "You have an attributes object with some attribute"
+        def attributes = Mock(Attributes)
+        attributes.get("uid") >> null
+
+        when: "You get the attribute"
+        String foundValue = LdapUtils.getAttributeValue(attributes, "uid")
+
+        then: "Its value equals uid"
+        foundValue == null
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy
new file mode 100644
index 0000000..4c0cc4b
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy
@@ -0,0 +1,30 @@
+// 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.NoLdapUserMatchingQueryException
+
+class NoLdapUserMatchingQueryExceptionSpec extends spock.lang.Specification {
+    def "Test that the query is correctly set within the No LDAP user matching query exception object"() {
+        given: "You have created an No LDAP user matching query exception object with a query set"
+        def exception = new NoLdapUserMatchingQueryException(query)
+        expect: "The username is equal to the given data source"
+        exception.getQuery() == query
+        where: "The username is set to "
+        query << ["", null, "murp*"]
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoSuchLdapUserExceptionSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoSuchLdapUserExceptionSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoSuchLdapUserExceptionSpec.groovy
new file mode 100644
index 0000000..dbdf646
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoSuchLdapUserExceptionSpec.groovy
@@ -0,0 +1,30 @@
+// 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.NoSuchLdapUserException;
+
+class NoSuchLdapUserExceptionSpec extends spock.lang.Specification {
+    def "Test that the username is correctly set within the No such LDAP user exception object"() {
+        given: "You have created an No such LDAP user exception object with the username set"
+        def exception = new NoSuchLdapUserException(username)
+        expect: "The username is equal to the given data source"
+        exception.getUsername() == username
+        where: "The username is set to "
+        username << ["", null, "rmurphy"]
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif b/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif
new file mode 100644
index 0000000..b20de81
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif
@@ -0,0 +1,19 @@
+version: 1
+
+dn: dc=cloudstack,dc=org
+objectClass: dcObject
+objectClass: organization
+dc: cloudstack
+o: cloudstack
+
+dn: cn=Ryan Murphy,dc=cloudstack,dc=org
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+objectClass: top
+cn: Ryan Murphy
+sn: Murphy
+givenName: Ryan
+mail: rmurphy@cloudstack.org
+uid: rmurphy
+userpassword:: cGFzc3dvcmQ=

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index e49e169..f98a3ef 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -78,7 +78,6 @@ import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse;
 import org.apache.cloudstack.api.response.LBHealthCheckResponse;
 import org.apache.cloudstack.api.response.LBStickinessPolicyResponse;
 import org.apache.cloudstack.api.response.LBStickinessResponse;
-import org.apache.cloudstack.api.response.LDAPConfigResponse;
 import org.apache.cloudstack.api.response.LoadBalancerResponse;
 import org.apache.cloudstack.api.response.NetworkACLItemResponse;
 import org.apache.cloudstack.api.response.NetworkACLResponse;
@@ -2808,20 +2807,6 @@ public class ApiResponseHelper implements ResponseGenerator {
     }
 
     @Override
-    public LDAPConfigResponse createLDAPConfigResponse(String hostname, Integer port, Boolean useSSL, String queryFilter, String searchBase,
-            String bindDN) {
-        LDAPConfigResponse lr = new LDAPConfigResponse();
-        lr.setHostname(hostname);
-        lr.setPort(port.toString());
-        lr.setUseSSL(useSSL.toString());
-        lr.setQueryFilter(queryFilter);
-        lr.setBindDN(bindDN);
-        lr.setSearchBase(searchBase);
-        lr.setObjectName("ldapconfig");
-        return lr;
-    }
-
-    @Override
     public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) {
         StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse();
         response.setUuid(result.getUuid());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index c815c77..1ec0576 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -424,6 +424,16 @@ public enum Config {
     // object store
     S3EnableRRS("Advanced", ManagementServer.class, Boolean.class, "s3.rrs.enabled", "false", "enable s3 reduced redundancy storage", null),
 
+        // Ldap
+    LdapBasedn("Advanced", ManagementServer.class, String.class, "ldap.basedn", null, "Sets the basedn for LDAP", null),
+    LdapBindPassword("Advanced", ManagementServer.class, String.class, "ldap.bind.password", null, "Sets the bind password for LDAP", null),
+    LdapBindPrincipal("Advanced", ManagementServer.class, String.class, "ldap.bind.principal", null, "Sets the bind principal for LDAP", null),
+    LdapEmailAttribute("Advanced", ManagementServer.class, String.class, "ldap.email.attribute", "mail", "Sets the email attribute used within LDAP", null),
+    LdapFirstnameAttribute("Advanced", ManagementServer.class, String.class, "ldap.firstname.attribute", "givenname", "Sets the firstname attribute used within LDAP", null),
+    LdapLastnameAttribute("Advanced", ManagementServer.class, String.class, "ldap.lastname.attribute", "sn", "Sets the lastname attribute used within LDAP", null),
+    LdapUsernameAttribute("Advanced", ManagementServer.class, String.class, "ldap.username.attribute", "uid", "Sets the username attribute used within LDAP", null),
+    LdapUserObject("Advanced", ManagementServer.class, String.class, "ldap.user.object", "inetOrgPerson", "Sets the object type of users within LDAP", null),
+
 	// VMSnapshots
     VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null),
     VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "1800", "In second, timeout for create vm snapshot", null),
@@ -616,4 +626,4 @@ public enum Config {
     public static List<Config> getConfigListByScope(String scope) {
         return _scopeLevelConfigsMap.get(scope);
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index b2dedb3..1243fb8 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -43,10 +43,7 @@ import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.api.ApiConstants.LDAPParams;
 import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
-import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd;
-import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd;
 import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
 import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
 import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
@@ -1544,175 +1541,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
 
     @Override
     @DB
-    public boolean removeLDAP(LDAPRemoveCmd cmd) {
-        _configDao.expunge(LDAPParams.hostname.toString());
-        _configDao.expunge(LDAPParams.port.toString());
-        _configDao.expunge(LDAPParams.queryfilter.toString());
-        _configDao.expunge(LDAPParams.searchbase.toString());
-        _configDao.expunge(LDAPParams.usessl.toString());
-        _configDao.expunge(LDAPParams.dn.toString());
-        _configDao.expunge(LDAPParams.passwd.toString());
-        _configDao.expunge(LDAPParams.truststore.toString());
-        _configDao.expunge(LDAPParams.truststorepass.toString());
-        return true;
-    }
-
-    @Override
-    @DB
-    public LDAPConfigCmd listLDAPConfig(LDAPConfigCmd cmd) {
-        String hostname = _configDao.getValue(LDAPParams.hostname.toString());
-        cmd.setHostname(hostname == null ? "" : hostname);
-        String port = _configDao.getValue(LDAPParams.port.toString());
-        cmd.setPort(port == null ? 0 : Integer.valueOf(port));
-        String queryFilter = _configDao.getValue(LDAPParams.queryfilter.toString());
-        cmd.setQueryFilter(queryFilter == null ? "" : queryFilter);
-        String searchBase = _configDao.getValue(LDAPParams.searchbase.toString());
-        cmd.setSearchBase(searchBase == null ? "" : searchBase);
-        String useSSL = _configDao.getValue(LDAPParams.usessl.toString());
-        cmd.setUseSSL(useSSL == null ? Boolean.FALSE : Boolean.valueOf(useSSL));
-        String binddn = _configDao.getValue(LDAPParams.dn.toString());
-        cmd.setBindDN(binddn == null ? "" : binddn);
-        String truststore = _configDao.getValue(LDAPParams.truststore.toString());
-        cmd.setTrustStore(truststore == null ? "" : truststore);
-        return cmd;
-    }
-
-    @Override
-    @DB
-    public boolean updateLDAP(LDAPConfigCmd cmd) {
-        try {
-            // set the ldap details in the zone details table with a zone id of
-            // -12
-            String hostname = cmd.getHostname();
-            Integer port = cmd.getPort();
-            String queryFilter = cmd.getQueryFilter();
-            String searchBase = cmd.getSearchBase();
-            Boolean useSSL = cmd.getUseSSL();
-            String bindDN = cmd.getBindDN();
-            String bindPasswd = cmd.getBindPassword();
-            String trustStore = cmd.getTrustStore();
-            String trustStorePassword = cmd.getTrustStorePassword();
-
-            if (bindDN != null && bindPasswd == null) {
-                throw new InvalidParameterValueException(
-                        "If you specify a bind name then you need to provide bind password too.");
-            }
-
-            // check query filter if it contains valid substitution
-            if (!queryFilter.contains("%u") && !queryFilter.contains("%n") && !queryFilter.contains("%e")) {
-                throw new InvalidParameterValueException(
-                        "QueryFilter should contain at least one of the substitutions: %u, %n or %e: " + queryFilter);
-            }
-
-            // check if the info is correct
-            Hashtable<String, String> env = new Hashtable<String, String>(11);
-            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
-            String protocol = "ldap://";
-            if (useSSL) {
-                env.put(Context.SECURITY_PROTOCOL, "ssl");
-                protocol = "ldaps://";
-                if (trustStore == null || trustStorePassword == null) {
-                    throw new InvalidParameterValueException(
-                            "If you plan to use SSL then you need to configure the trust store.");
-                }
-                System.setProperty("javax.net.ssl.trustStore", trustStore);
-                System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
-            }
-            env.put(Context.PROVIDER_URL, protocol + hostname + ":" + port);
-            if (bindDN != null && bindPasswd != null) {
-                env.put(Context.SECURITY_AUTHENTICATION, "simple");
-                env.put(Context.SECURITY_PRINCIPAL, bindDN);
-                env.put(Context.SECURITY_CREDENTIALS, bindPasswd);
-            }
-            // Create the initial context
-            DirContext ctx = new InitialDirContext(env);
-            ctx.close();
-
-            // store the result in DB Configuration
-            ConfigurationVO cvo = _configDao.findByName(LDAPParams.hostname.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.hostname.toString(),
-                        null, "Hostname or ip address of the ldap server eg: my.ldap.com");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(hostname));
-            _configDao.persist(cvo);
-
-            cvo = _configDao.findByName(LDAPParams.port.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.port.toString(), null,
-                        "Specify the LDAP port if required, default is 389");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(port.toString()));
-            _configDao.persist(cvo);
-
-            cvo = _configDao.findByName(LDAPParams.queryfilter.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.queryfilter.toString(),
-                        null,
-                        "You specify a query filter here, which narrows down the users, who can be part of this domain");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(queryFilter));
-            _configDao.persist(cvo);
-
-            cvo = _configDao.findByName(LDAPParams.searchbase.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.searchbase.toString(),
-                        null,
-                        "The search base defines the starting point for the search in the directory tree Example:  dc=cloud,dc=com.");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(searchBase));
-            _configDao.persist(cvo);
-
-            cvo = _configDao.findByName(LDAPParams.usessl.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.usessl.toString(), null,
-                        "Check Use SSL if the external LDAP server is configured for LDAP over SSL.");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(useSSL.toString()));
-            _configDao.persist(cvo);
-
-            cvo = _configDao.findByName(LDAPParams.dn.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.dn.toString(), null,
-                        "Specify the distinguished name of a user with the search permission on the directory");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(bindDN));
-            _configDao.persist(cvo);
-
-            cvo = _configDao.findByName(LDAPParams.passwd.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.passwd.toString(), null,
-                        "Enter the password");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(bindPasswd));
-            _configDao.persist(cvo);
-
-            cvo = _configDao.findByName(LDAPParams.truststore.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.truststore.toString(),
-                        null, "Enter the path to trusted keystore");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(trustStore));
-            _configDao.persist(cvo);
-
-            cvo = _configDao.findByName(LDAPParams.truststorepass.toString());
-            if (cvo == null) {
-                cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server",
-                        LDAPParams.truststorepass.toString(), null, "Enter the password for trusted keystore");
-            }
-            cvo.setValue(DBEncryptionUtil.encrypt(trustStorePassword));
-            _configDao.persist(cvo);
-
-            s_logger.debug("The ldap server is configured: " + hostname);
-        } catch (NamingException ne) {
-            throw new InvalidParameterValueException("Naming Exception, check you ldap data ! " + ne.getMessage()
-                    + (ne.getCause() != null ? ("; Caused by:" + ne.getCause().getMessage()) : ""));
-        }
-        return true;
-    }
-
-    @Override
-    @DB
     @ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "editing zone", async = false)
     public DataCenter editZone(UpdateZoneCmd cmd) {
         // Parameter validation as from execute() method in V1

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 7ac1254..2a203b4 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -87,8 +87,6 @@ import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
 import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd;
 import org.apache.cloudstack.api.command.admin.internallb.StartInternalLBVMCmd;
 import org.apache.cloudstack.api.command.admin.internallb.StopInternalLBVMCmd;
-import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd;
-import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd;
 import org.apache.cloudstack.api.command.admin.network.AddNetworkDeviceCmd;
 import org.apache.cloudstack.api.command.admin.network.AddNetworkServiceProviderCmd;
 import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
@@ -2504,8 +2502,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         cmdList.add(ReconnectHostCmd.class);
         cmdList.add(UpdateHostCmd.class);
         cmdList.add(UpdateHostPasswordCmd.class);
-        cmdList.add(LDAPConfigCmd.class);
-        cmdList.add(LDAPRemoveCmd.class);
         cmdList.add(AddNetworkDeviceCmd.class);
         cmdList.add(AddNetworkServiceProviderCmd.class);
         cmdList.add(CreateNetworkOfferingCmd.class);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
index 80b9e23..29b899c 100755
--- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -26,8 +26,6 @@ import javax.naming.ConfigurationException;
 import javax.naming.NamingException;
 
 import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
-import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd;
-import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd;
 import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
 import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
 import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
@@ -87,8 +85,6 @@ import com.cloud.user.Account;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.vm.VirtualMachine.Type;
 import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
-import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd;
-import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd;
 import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
 import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
 import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
@@ -384,33 +380,6 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
     }
 
     /* (non-Javadoc)
-     * @see com.cloud.configuration.ConfigurationService#updateLDAP(org.apache.cloudstack.api.commands.LDAPConfigCmd)
-     */
-    @Override
-    public boolean updateLDAP(LDAPConfigCmd cmd) throws NamingException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.configuration.ConfigurationService#removeLDAP(org.apache.cloudstack.api.commands.LDAPRemoveCmd)
-     */
-    @Override
-    public boolean removeLDAP(LDAPRemoveCmd cmd) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.configuration.ConfigurationService#listLDAPConfig(org.apache.cloudstack.api.commands.LDAPConfigCmd)
-     */
-    @Override
-    public LDAPConfigCmd listLDAPConfig(LDAPConfigCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
      * @see com.cloud.configuration.ConfigurationService#isOfferingForVpc(com.cloud.offering.NetworkOffering)
      */
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index 82ca403..f4cd1b1 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -1462,7 +1462,7 @@ CREATE VIEW `cloud`.`disk_offering_view` AS
         disk_offering.iops_write_rate,
         disk_offering.sort_key,
         disk_offering.type,
-	disk_offering.display_offering,
+  disk_offering.display_offering,
         domain.id domain_id,
         domain.uuid domain_uuid,
         domain.name domain_name,
@@ -1516,7 +1516,7 @@ CREATE VIEW `cloud`.`user_vm_view` AS
         data_center.uuid data_center_uuid,
         data_center.name data_center_name,
         data_center.is_security_group_enabled security_group_enabled,
-		data_center.networktype data_center_type,
+    data_center.networktype data_center_type,
         host.id host_id,
         host.uuid host_uuid,
         host.name host_name,
@@ -1672,7 +1672,7 @@ CREATE VIEW `cloud`.`volume_view` AS
         volumes.attached,
         volumes.removed,
         volumes.pod_id,
-	volumes.display_volume,
+  volumes.display_volume,
         volumes.format,
         account.id account_id,
         account.uuid account_uuid,
@@ -1688,7 +1688,7 @@ CREATE VIEW `cloud`.`volume_view` AS
         data_center.id data_center_id,
         data_center.uuid data_center_uuid,
         data_center.name data_center_name,
-	data_center.networktype data_center_type,
+  data_center.networktype data_center_type,
         vm_instance.id vm_id,
         vm_instance.uuid vm_uuid,
         vm_instance.name vm_name,
@@ -1820,7 +1820,7 @@ CREATE VIEW `cloud`.`template_view` AS
         data_center.name data_center_name,
         launch_permission.account_id lp_account_id,
         template_store_ref.store_id,
-		image_store.scope as store_scope,
+    image_store.scope as store_scope,
         template_store_ref.state,
         template_store_ref.download_state,
         template_store_ref.download_pct,
@@ -1840,7 +1840,7 @@ CREATE VIEW `cloud`.`template_view` AS
         resource_tags.resource_uuid tag_resource_uuid,
         resource_tags.resource_type tag_resource_type,
         resource_tags.customer tag_customer,
-		CONCAT(vm_template.id, '_', IFNULL(data_center.id, 0)) as temp_zone_pair
+    CONCAT(vm_template.id, '_', IFNULL(data_center.id, 0)) as temp_zone_pair
     from
         `cloud`.`vm_template`
             inner join
@@ -1859,7 +1859,7 @@ CREATE VIEW `cloud`.`template_view` AS
         `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id and template_store_ref.store_role = 'Image'
             left join
         `cloud`.`image_store` ON image_store.removed is NULL AND template_store_ref.store_id is not NULL AND image_store.id = template_store_ref.store_id 
-        	left join
+          left join
         `cloud`.`template_zone_ref` ON template_zone_ref.template_id = vm_template.id AND template_store_ref.store_id is NULL AND template_zone_ref.removed is null    
             left join
         `cloud`.`data_center` ON (image_store.data_center_id = data_center.id OR template_zone_ref.zone_id = data_center.id)
@@ -2048,7 +2048,7 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag
 INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.bytes_write_rate', 0, 'Default disk I/O write rate in bytes per second allowed in User vm\'s disk. ');
 
 -- Re-enable foreign key checking, at the end of the upgrade path
-SET foreign_key_checks = 1;			
+SET foreign_key_checks = 1;
 
 UPDATE `cloud`.`snapshot_policy` set uuid=id WHERE uuid is NULL;
 #update shared sg enabled network with not null name in Advance Security Group enabled network
@@ -2142,10 +2142,25 @@ CREATE VIEW `cloud`.`project_view` AS
             left join
         `cloud`.`project_account` pacct ON projects.id = pacct.project_id;
 
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.bind.principal', NULL, 'Specifies the bind principal to use for bind to LDAP');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.bind.password', NULL, 'Specifies the password to use for binding to LDAP');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.username.attribute', 'uid', 'Sets the username attribute used within LDAP');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.email.attribute', 'mail', 'Sets the email attribute used within LDAP');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.firstname.attribute', 'givenname', 'Sets the firstname attribute used within LDAP');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.lastname.attribute', 'sn', 'Sets the lastname attribute used within LDAP');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.user.object', 'inetOrgPerson', 'Sets the object type of users within LDAP');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.basedn', NULL, 'Sets the basedn for LDAP');
+
+CREATE TABLE `cloud`.`ldap_configuration` (
+  `id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
+  `hostname` varchar(255) NOT NULL COMMENT 'the hostname of the ldap server',
+  `port` int(10) COMMENT 'port that the ldap server is listening on',
+  PRIMARY KEY  (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
 INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'network.loadbalancer.haproxy.max.conn', '4096', 'Load Balancer(haproxy) maximum number of concurrent connections(global max)');
 
 ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `concurrent_connections` int(10) unsigned COMMENT 'Load Balancer(haproxy) maximum number of concurrent connections(global max)';
-
         
 ALTER TABLE `cloud`.`sync_queue` MODIFY `queue_size` smallint(6) NOT NULL DEFAULT '0' COMMENT 'number of items being processed by the queue';
 ALTER TABLE `cloud`.`sync_queue` MODIFY `queue_size_limit` smallint(6) NOT NULL DEFAULT '1' COMMENT 'max number of items the queue can process concurrently';

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/test/integration/component/test_ldap.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_ldap.py b/test/integration/component/test_ldap.py
index fc3bd48..83f970b 100644
--- a/test/integration/component/test_ldap.py
+++ b/test/integration/component/test_ldap.py
@@ -44,78 +44,30 @@ class Services:
     def __init__(self):
         self.services = {
             "account": {
-                "email": "test@test.com",
-                "firstname": "test",
-                "lastname": "t",
-                "username": "test",
-                "password": "password",
+                "email": "rmurphy@cloudstack.org",
+                "firstname": "Ryan",
+                "lastname": "Murphy",
+                "username": "rmurphy",
+                "password": "internalcloudstackpassword",
                 },
-            "ldapCon_1":#valid values&Query filter as email.
+            "ldapConfiguration_1":
                 {
-                    "ldapHostname": "10.147.38.163",
-                    "port": "389",
-                    "binddn": "CN=test,CN=Users,DC=hyd-qa,DC=com",
-                    "bindpass": "aaaa_1111",
-                    "queryfilter": "(&(mail=%e))",
-                    "searchbase": "CN=Users,DC=hyd-qa,DC=com",
-                    "ldapusername": "test",
-                    "ldappasswd": "aaaa_1111"
-                },
-            "ldapCon_2": ##valid values&Query filter as displayName.
-                {
-                    "ldapHostname": "10.147.38.163",
-                    "port": "389",
-                    "binddn": "CN=test,CN=Users,DC=hyd-qa,DC=com",
-                    "bindpass": "aaaa_1111",
-                    "queryfilter": "(&(displayName=%u))",
-                    "searchbase": "CN=Users,DC=hyd-qa,DC=com",
-                    "ldapusername": "test",
-                    "ldappasswd": "aaaa_1111"
-                },
-            "ldapCon_3": #Configuration with missing parameters value(queryfilter)
-                {
-                    "ldapHostname": "10.147.38.163",
-                    "port": "389",
-                    "binddn": "CN=test,CN=Users,DC=hyd-qa,DC=com",
-                    "bindpass": "aaaa_1111",
-                    "queryfilter": "",
-                    "searchbase": "CN=Users,DC=hyd-qa,DC=com",
-                    "ldapusername": "test",
-                    "ldappasswd": "aaaa_1111"
-                },
-
-            "ldapCon_4": #invalid configuration-wrong query filter
-                {
-                    "ldapHostname": "10.147.38.163",
-                    "port": "389",
-                    "binddn": "CN=test,CN=Users,DC=hyd-qa,DC=com",
-                    "bindpass": "aaaa_1111",
-                    "queryfilter": "(&(displayName=%p))",
-                    "searchbase":"CN=Users,DC=hyd-qa,DC=com",
-                    "ldapusername": "test",
-                    "ldappasswd": "aaaa_1111"
-                },
-            "ldapCon_5": #Configuration with invalid ldap credentials
-                {
-                    "ldapHostname": "10.147.38.163",
-                    "port": "389",
-                    "binddn": "CN=test,CN=Users,DC=hyd-qa,DC=com",
-                    "bindpass": "aaaa_1111",
-                    "queryfilter": "(&(displayName=%u))",
-                    "searchbase": "CN=Users,DC=hyd-qa,DC=com",
-                    "ldapusername": "test",
-                    "ldappasswd": "aaaa"
+                "basedn": "dc=cloudstack,dc=org",
+                "emailAttribute": "mail",
+                "realnameAttribute": "cn",
+                "userObject": "inetOrgPerson",
+                "usernameAttribute": "uid",
+                "hostname": "localhost",
+                "port": "10389",
+                "ldapUsername": "rmurphy",
+                "ldapPassword": "password"
                 }
-
-
-
         }
 
 
 class TestLdap(cloudstackTestCase):
     """
-    This test perform registering ldap configuration details in CS and create a user[ldap user] in CS
-     and  validate user credentials against LDAP server:AD
+    This tests attempts to register a LDAP server and authenticate as an LDAP user.
     """
 
     @classmethod
@@ -134,8 +86,6 @@ class TestLdap(cloudstackTestCase):
     @classmethod
     def tearDownClass(cls):
         try:
-            #Cleanup resources used
-            #print "tear down class"
             cleanup_resources(cls.api_client, cls._cleanup)
 
         except Exception as tde:
@@ -144,10 +94,10 @@ class TestLdap(cloudstackTestCase):
 
     def setUp(self):
 
-        self.apiclient = self.testClient.getApiClient()
+        self.apiClient = self.testClient.getApiClient()
 
         self.acct = createAccount.createAccountCmd()
-        self.acct.accounttype = 0 #We need a regular user. admins have accounttype=1
+        self.acct.accounttype = 0
         self.acct.firstname = self.services["account"]["firstname"]
         self.acct.lastname = self.services["account"]["lastname"]
         self.acct.password = self.services["account"]["password"]
@@ -155,208 +105,153 @@ class TestLdap(cloudstackTestCase):
         self.acct.email = self.services["account"]["email"]
         self.acct.account = self.services["account"]["username"]
         self.acct.domainid = 1
-        # mapping ldap user  by creating same user in  cloudstack
-
-        self.acctRes = self.apiclient.createAccount(self.acct)
 
+        self.acctRes = self.apiClient.createAccount(self.acct)
 
         return
 
     def tearDown(self):
 
         try:
-            #Clean up, terminate the created accounts, domains etc
-
             deleteAcct = deleteAccount.deleteAccountCmd()
             deleteAcct.id = self.acctRes.id
 
             acct_name=self.acctRes.name
 
-            self.apiclient.deleteAccount(deleteAcct)
+            self.apiClient.deleteAccount(deleteAcct)
 
             self.debug("Deleted the the following account name %s:" %acct_name)
-            #delete only if ldapconfig registered  in CS
-            if(self.ldapconfRes):
-                deleteldapconfg=ldapRemove.ldapRemoveCmd()
-                res=self.apiclient.ldapRemove(deleteldapconfg)
 
+            if(self.ldapconfRes==1):
+                self._deleteLdapConfiguration(self.services["ldapConfiguration_1"])
 
         except Exception as e:
             raise Exception("Warning: Exception during cleanup : %s" % e)
         return
 
     @attr(tags=["advanced", "basic"])
-    def test_01_configLDAP(self):
-        '''
-        This test is to verify ldapConfig API  with valid  values.(i.e query fileter as email)
-        '''
-        # 1. This test covers ldapConfig  & login API with valid ldap credentials..
-        # require ldap configuration:ldapCon_1
+    def test_01_addLdapConfiguration(self):
+        """
+        This test configures LDAP and attempts to authenticate as a user.
+        """
+
 
         self.debug("start test")
 
-        self.ldapconfRes=self._testldapConfig(self.services["ldapCon_1"])
+        self.ldapconfRes=self._addLdapConfiguration(self.services["ldapConfiguration_1"])
 
         if(self.ldapconfRes==1):
 
+            self.debug("Ldap Configuration was succcessful")
 
-            self.debug("configure ldap successful")
-
-            #validating the user credentials with ldap Server
-            loginRes = self.chkLogin(self.services["ldapCon_1"]["ldapusername"], self.services["ldapCon_1"]["ldappasswd"])
-            self.assertEquals(loginRes,1,"ldap Authentication failed")
+            loginRes = self._checkLogin(self.services["ldapConfiguration_1"]["ldapUsername"],self.services["ldapConfiguration_1"]["ldapPassword"])
+            self.debug(loginRes)
+            self.assertEquals(loginRes,1,"Ldap Authentication")
 
         else:
 
             self.debug("LDAP Configuration failed with exception")
 
-            self.assertEquals(self.ldapconfRes,1,"ldapConfig API failed")
+            self.assertEquals(self.ldapconfRes,1,"addLdapConfiguration failed")
 
 
         self.debug("end test")
 
-    @attr(tags=["advanced", "basic"])
-    def test_02_configLDAP(self):
-        '''
-        This test is to verify ldapConfig API  with valid  values.(i.e query fileter as displayName)
-        '''
-
-        # 1. This test covers ldapConfig  & login API with valid ldap credentials.
-        # 2. require ldap configuration:ldapCon_2
+    def _addLdapConfiguration(self,ldapConfiguration):
 
-        self.debug("start test")
-        self.ldapconfRes=self._testldapConfig(self.services["ldapCon_2"])
-        self.assertEquals(self.ldapconfRes,1,"ldapConfig API failed")
-        if(self.ldapconfRes==1):
-            self.debug("configure ldap successful")
-            #validating the user credentials with ldap Server
-            loginRes = self.chkLogin(self.services["ldapCon_2"]["ldapusername"], self.services["ldapCon_2"]["ldappasswd"])
-            self.assertEquals(loginRes,1,"ldap Authentication failed")
-        else:
-            self.debug("LDAP Configuration failed with exception")
-        self.debug("end test")
+        """
 
-    @attr(tags=["advanced", "basic"])
-    def test_03_configLDAP(self):
+        :param ldapConfiguration
 
-        '''
-        This test is to verify ldapConfig API  with missing config parameters value(i.queryfilter)
-        '''
+        """
 
-        # 1. Issue ldapConfig API with no ldap config parameter value and check behavior
-        # 2. require ldap configuration:ldapCon_3
+        # Setup Global settings
 
-        self.debug("start test...")
-        self.ldapconfRes=self._testldapConfig(self.services["ldapCon_3"])
-        self.assertEquals(self.ldapconfRes,0,"LDAP configuration successful with invalid value.API failed")
-        self.debug("end test")
-    @attr(tags=["advanced", "basic"])
-    def test_04_configLDAP(self):
-        '''
-        This test is to verify ldapConfig API with invalid configuration values(by passing wrong query filter)
-        '''
-        # 1. calling ldapConfig API with invalid query filter value and check behavior
-        # 2. require ldap configuration:ldapCon_4
+        updateConfigurationCmd = updateConfiguration.updateConfigurationCmd()
+        updateConfigurationCmd.name = "ldap.basedn"
+        updateConfigurationCmd.value = ldapConfiguration['basedn']
+        updateConfigurationResponse = self.apiClient.updateConfiguration(updateConfigurationCmd)
+        self.debug("updated the parameter %s with value %s"%(updateConfigurationResponse.name, updateConfigurationResponse.value))
 
-        self.debug("start test...")
-        self.ldapconfRes=self._testldapConfig(self.services["ldapCon_4"])
-        self.assertEquals(self.ldapconfRes,0,"API failed")
+        updateConfigurationCmd = updateConfiguration.updateConfigurationCmd()
+        updateConfigurationCmd.name = "ldap.email.attribute"
+        updateConfigurationCmd.value = ldapConfiguration['emailAttribute']
+        updateConfigurationResponse = self.apiClient.updateConfiguration(updateConfigurationCmd)
+        self.debug("updated the parameter %s with value %s"%(updateConfigurationResponse.name, updateConfigurationResponse.value))
 
 
-    @attr(tags=["advanced", "basic"])
-    def test_05_configLDAP(self):
+        updateConfigurationCmd = updateConfiguration.updateConfigurationCmd()
+        updateConfigurationCmd.name = "ldap.realname.attribute"
+        updateConfigurationCmd.value = ldapConfiguration['realnameAttribute']
+        updateConfigurationResponse = self.apiClient.updateConfiguration(updateConfigurationCmd)
+        self.debug("updated the parameter %s with value %s"%(updateConfigurationResponse.name, updateConfigurationResponse.value))
 
-        '''
-        This test is to verify login API functionality by passing wrong ldap credentials
-        '''
-        # 1.This script first  configure the ldap and validates the user credentials using login API
-        # 2. require ldap configuration:ldapCon_5
 
+        updateConfigurationCmd = updateConfiguration.updateConfigurationCmd()
+        updateConfigurationCmd.name = "ldap.user.object"
+        updateConfigurationCmd.value = ldapConfiguration['userObject']
+        updateConfigurationResponse = self.apiClient.updateConfiguration(updateConfigurationCmd)
+        self.debug("updated the parameter %s with value %s"%(updateConfigurationResponse.name, updateConfigurationResponse.value))
 
-        self.debug("start test")
-        self.ldapconfRes=self._testldapConfig(self.services["ldapCon_5"])
-        self.assertEquals(self.ldapconfRes,1,"API failed")
-        #validating the cloudstack user credentials with ldap Server
-        loginRes = self.chkLogin(self.services["ldapCon_5"]["ldapusername"], self.services["ldapCon_5"]["ldappasswd"])
-        self.assertNotEqual(loginRes,1,"login API failed")
-        self.debug("end test")
 
-    @attr(tags=["advanced", "basic"])
-    def test_06_removeLDAP(self):
-        '''
-        This test is to verify ldapRemove API functionality
-        '''
-        # 1. This script fist configures ldap and removes the configured ldap values
-        # 2. require ldap configuration:ldapCon_1
+        updateConfigurationCmd = updateConfiguration.updateConfigurationCmd()
+        updateConfigurationCmd.name = "ldap.username.attribute"
+        updateConfigurationCmd.value = ldapConfiguration['usernameAttribute']
+        updateConfigurationResponse = self.apiClient.updateConfiguration(updateConfigurationCmd)
+        self.debug("updated the parameter %s with value %s"%(updateConfigurationResponse.name, updateConfigurationResponse.value))
 
+        self.debug("start addLdapConfiguration test")
 
-        self.debug("start test")
-        self.ldapconfRes=self._testldapConfig(self.services["ldapCon_1"])
-        if(self.ldapconfRes==1):
-            self.debug("ldap configured successfully")
-            deleteldapconfg=ldapRemove.ldapRemoveCmd()
-            res=self.apiclient.ldapRemove(deleteldapconfg)
-            self.debug("ldap removed successfully")
-            self.ldapconfRes=0
-        else:
+        ldapServer = addLdapConfiguration.addLdapConfigurationCmd()
+        ldapServer.hostname = ldapConfiguration['hostname']
+        ldapServer.port = ldapConfiguration['port']
 
-            self.debug("LDAP Configuration failed with exception")
-            self.assertEquals(self.ldapconfRes,0,"ldapconfig API failed")
-        self.debug("end test")
+        self.debug("calling addLdapConfiguration API command")
+        try:
+            self.apiClient.addLdapConfiguration(ldapServer)
+            self.debug("addLdapConfiguration was successful")
+            return 1
+        except Exception, e:
+            self.debug("addLdapConfiguration failed %s" %e)
+            return 0
 
-    def _testldapConfig(self,ldapSrvD):
+    def _deleteLdapConfiguration(self,ldapConfiguration):
 
         """
 
-        :param ldapSrvD
-
+        :param ldapConfiguration
 
         """
-        #This Method takes dictionary as parameter,
-        # reads the ldap configuration values from the passed dictionary and
-        # register the ldapconfig detail in cloudstack
-        # & return true or false based on ldapconfig API response
-
-        self.debug("start ldapconfig  test")
-        #creating the  ldapconfig cmd object
-        lpconfig = ldapConfig.ldapConfigCmd()
-        #Config the ldap server by assigning the ldapconfig dict variable values to ldapConfig object
-        lpconfig.hostname = ldapSrvD["ldapHostname"]
-        lpconfig.port = ldapSrvD["port"]
-        lpconfig.binddn = ldapSrvD["binddn"]
-        lpconfig.bindpass = ldapSrvD["bindpass"]
-        lpconfig.searchbase = ldapSrvD["searchbase"]
-        lpconfig.queryfilter = ldapSrvD["queryfilter"]
-
-        #end of assigning the variables
-
-        #calling the ldapconfig Api
-        self.debug("calling ldapconfig API")
+
+        ldapServer = deleteLdapConfiguration.deleteLdapConfigurationCmd()
+        ldapServer.hostname = ldapConfiguration["hostname"]
+
         try:
-            lpconfig1 = self.apiclient.ldapConfig(lpconfig)
-            self.debug("ldapconfig API succesfful")
+            self.apiClient.deleteLdapConfiguration(ldapServer)
+            self.debug("deleteLdapConfiguration was successful")
             return 1
         except Exception, e:
-            self.debug("ldapconfig API failed %s" %e)
+            self.debug("deleteLdapConfiguration failed %s" %e)
             return 0
 
-    def chkLogin(self, username, password):
+    def _checkLogin(self, username, password):
         """
 
         :param username:
         :param password:
 
         """
-        self.debug("login test")
+        self.debug("Attempting to login.")
 
         try:
-            login1 = login.loginCmd()
-            login1.username = username
-            login1.password = password
-            loginRes = self.apiclient.login(login1)
+            loginParams = login.loginCmd()
+            loginParams.username = username
+            loginParams.password = password
+            loginRes = self.apiClient.login(loginParams)
             self.debug("login response %s" % loginRes)
             if loginRes is None:
                 self.debug("login not successful")
+                return 0
             else:
                 self.debug("login successful")
                 return 1

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/tools/apidoc/gen_toc.py
----------------------------------------------------------------------
diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py
index 33a7e75..f582340 100644
--- a/tools/apidoc/gen_toc.py
+++ b/tools/apidoc/gen_toc.py
@@ -118,7 +118,7 @@ known_categories = {
     'TrafficType': 'Usage',
     'Product': 'Product',
     'LB': 'Load Balancer',
-    'ldap': 'LDAP',
+    'Ldap': 'LDAP',
     'Swift': 'Swift',
     'S3' : 'S3',
     'SecondaryStorage': 'Host',

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/ui/css/cloudstack3.css
----------------------------------------------------------------------
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index 50cfbd4..93658db 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -5834,7 +5834,7 @@ label.error {
 .multi-wizard .buttons {
   width: 100%;
   position: absolute;
-  top: 519px;
+  bottom: 10px;
   left: 0px;
 }
 
@@ -12267,3 +12267,85 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
   color: #0000FF !important;
 }
 
+.accounts-wizard table {
+  margin: 0;
+  width: 100%;
+  table-layout: fixed;
+}
+
+.accounts-wizard td:last-child {
+  border: none;
+}
+
+.accounts-wizard tbody tr:nth-child(even) {
+  background: #DFE1E3;
+}
+
+.accounts-wizard tbody tr:nth-child(odd) {
+  background: #F2F0F0;
+}
+
+.accounts-wizard .content {
+  display: inline-block;
+}
+
+.accounts-wizard .content:last-child {
+  margin-left: 14px;
+}
+
+.accounts-wizard .select-container {
+  overflow: auto;
+}
+
+.accounts-wizard .input-area{
+  width: 320px;
+  font-size: 15px;
+  color: #485867;
+  text-shadow: 0px 2px 1px #FFFFFF;
+}
+
+.ldap-account-choice {
+  border: none !important;
+  border-radius: 0 0 0 0 !important;
+}
+
+.manual-account-details .name {
+  margin-top: 2px;
+  width: 100px;
+  float: left;
+  padding-bottom:10px;
+}
+
+.manual-account-details .value {
+  float: left;
+}
+
+.manual-account-details .form-item:after {
+  content: ".";
+  display: block;
+  clear: both;
+  visibility: hidden;
+  line-height: 0;
+  height: 0;
+}
+
+.manual-account-details .form-item {
+  padding: 10px;
+  width: 278px;
+}
+
+.manual-account-details select, .manual-account-details input {
+  width: 150px;
+}
+
+.manual-account-details > *:nth-child(even) {
+  background: #DFE1E3;
+}
+
+.manual-account-details > *:nth-child(odd) {
+  background: #F2F0F0;
+}
+
+.manual-account-details .value {
+  display: inline-block;
+}
\ No newline at end of file