Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4907510142 for ; Thu, 11 Jul 2013 14:04:35 +0000 (UTC) Received: (qmail 42993 invoked by uid 500); 11 Jul 2013 14:04:34 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 42886 invoked by uid 500); 11 Jul 2013 14:04:34 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 42865 invoked by uid 99); 11 Jul 2013 14:04:33 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 11 Jul 2013 14:04:33 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 15DCA88F769; Thu, 11 Jul 2013 14:04:33 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: sebgoa@apache.org To: commits@cloudstack.apache.org Date: Thu, 11 Jul 2013 14:04:34 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [2/3] Add LDAP Plugin Implementation http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/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 new file mode 100644 index 0000000..77dd33e --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java @@ -0,0 +1,185 @@ +package org.apache.cloudstack.ldap; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.NamingException; +import javax.naming.ldap.LdapContext; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import org.apache.cloudstack.api.command.LdapAddConfigurationCmd; +import org.apache.cloudstack.api.command.LdapDeleteConfigurationCmd; +import org.apache.cloudstack.api.command.LdapListAllUsersCmd; +import org.apache.cloudstack.api.command.LdapListConfigurationCmd; +import org.apache.cloudstack.api.command.LdapUserSearchCmd; +import org.apache.cloudstack.api.response.LdapConfigurationResponse; +import org.apache.cloudstack.api.response.LdapUserResponse; +import org.apache.cloudstack.ldap.dao.LdapConfigurationDao; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.utils.Pair; + +@Component +@Local(value = LdapManager.class) +public class LdapManagerImpl implements LdapManager { + private static final Logger s_logger = Logger.getLogger(LdapManagerImpl.class.getName()); + + @Inject + private LdapConfigurationDao _ldapConfigurationDao; + + @Inject + private LdapContextFactory _ldapContextFactory; + + @Inject + private LdapUserManager _ldapUserManager; + + public LdapManagerImpl() { + super(); + } + + public LdapManagerImpl(final LdapConfigurationDao ldapConfigurationDao, final LdapContextFactory ldapContextFactory, final LdapUserManager ldapUserManager) { + super(); + _ldapConfigurationDao = ldapConfigurationDao; + _ldapContextFactory = ldapContextFactory; + _ldapUserManager = ldapUserManager; + } + + @Override + public LdapConfigurationResponse addConfiguration(final String hostname, final int port) throws InvalidParameterValueException { + LdapConfigurationVO configuration = _ldapConfigurationDao.findByHostname(hostname); + if (configuration == null) { + try { + final String providerUrl = "ldap://" + hostname + ":" + port; + _ldapContextFactory.createBindContext(providerUrl); + configuration = new LdapConfigurationVO(hostname, port); + _ldapConfigurationDao.persist(configuration); + s_logger.info("Added new ldap server with hostname: " + hostname); + return new LdapConfigurationResponse(hostname, port); + } catch (final NamingException e) { + throw new InvalidParameterValueException("Unable to bind to the given LDAP server"); + } + } else { + throw new InvalidParameterValueException("Duplicate configuration"); + } + } + + @Override + public boolean canAuthenticate(final String username, final String password) { + final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username); + try { + final LdapUser user = getUser(escapedUsername); + final String principal = user.getPrincipal(); + final LdapContext context = _ldapContextFactory.createUserContext(principal, password); + closeContext(context); + return true; + } catch (final NamingException e) { + s_logger.info("Failed to authenticate user: " + username + ". incorrent password."); + return false; + } + } + + private void closeContext(final LdapContext context) { + try { + if (context != null) { + context.close(); + } + } catch (final NamingException e) { + s_logger.warn(e.getMessage()); + } + } + + @Override + public LdapConfigurationResponse createLdapConfigurationResponse(final LdapConfigurationVO configuration) { + final LdapConfigurationResponse response = new LdapConfigurationResponse(); + response.setHostname(configuration.getHostname()); + response.setPort(configuration.getPort()); + return response; + } + + @Override + public LdapUserResponse createLdapUserResponse(final LdapUser user) { + final LdapUserResponse response = new LdapUserResponse(); + response.setUsername(user.getUsername()); + response.setRealname(user.getRealname()); + response.setEmail(user.getEmail()); + response.setPrincipal(user.getPrincipal()); + return response; + } + + @Override + public LdapConfigurationResponse deleteConfiguration(final String hostname) throws InvalidParameterValueException { + final LdapConfigurationVO configuration = _ldapConfigurationDao.findByHostname(hostname); + if (configuration == null) { + throw new InvalidParameterValueException("Cannot find configuration with hostname " + hostname); + } else { + _ldapConfigurationDao.remove(configuration.getId()); + s_logger.info("Removed ldap server with hostname: " + hostname); + return new LdapConfigurationResponse(configuration.getHostname(), configuration.getPort()); + } + } + + @Override + public List> getCommands() { + final List> cmdList = new ArrayList>(); + cmdList.add(LdapUserSearchCmd.class); + cmdList.add(LdapListAllUsersCmd.class); + cmdList.add(LdapAddConfigurationCmd.class); + cmdList.add(LdapDeleteConfigurationCmd.class); + cmdList.add(LdapListConfigurationCmd.class); + return cmdList; + } + + public LdapUser getUser(final String username) throws NamingException { + LdapContext context = null; + try { + context = _ldapContextFactory.createBindContext(); + + final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username); + return _ldapUserManager.getUser(escapedUsername, context); + + } catch (final NamingException e) { + throw e; + } finally { + closeContext(context); + } + } + + @Override + public List getUsers() throws NoLdapUserMatchingQueryException { + LdapContext context = null; + try { + context = _ldapContextFactory.createBindContext(); + return _ldapUserManager.getUsers(context); + } catch (final NamingException e) { + throw new NoLdapUserMatchingQueryException("*"); + } finally { + closeContext(context); + } + } + + @Override + public Pair, Integer> listConfigurations(final LdapListConfigurationCmd cmd) { + final String hostname = cmd.getHostname(); + final int port = cmd.getPort(); + final Pair, Integer> result = _ldapConfigurationDao.searchConfigurations(hostname, port); + return new Pair, Integer>(result.first(), result.second()); + } + + @Override + public List searchUsers(final String username) throws NoLdapUserMatchingQueryException { + LdapContext context = null; + try { + context = _ldapContextFactory.createBindContext(); + final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username); + return _ldapUserManager.getUsers("*" + escapedUsername + "*", context); + } catch (final NamingException e) { + throw new NoLdapUserMatchingQueryException(username); + } finally { + closeContext(context); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUser.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUser.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUser.java new file mode 100644 index 0000000..046447f --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUser.java @@ -0,0 +1,53 @@ +package org.apache.cloudstack.ldap; + +public class LdapUser implements Comparable { + private final String email; + private final String principal; + private final String realname; + private final String username; + + public LdapUser(final String username, final String email, final String realname, final String principal) { + this.username = username; + this.email = email; + this.realname = realname; + this.principal = principal; + } + + @Override + public int compareTo(final LdapUser other) { + return getUsername().compareTo(other.getUsername()); + } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (other instanceof LdapUser) { + final LdapUser otherLdapUser = (LdapUser)other; + return getUsername().equals(otherLdapUser.getUsername()); + } + return false; + } + + public String getEmail() { + return email; + } + + public String getPrincipal() { + return principal; + } + + public String getRealname() { + return realname; + } + + public String getUsername() { + return username; + } + + @Override + public int hashCode() { + return getUsername().hashCode(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/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 new file mode 100644 index 0000000..e53a320 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java @@ -0,0 +1,81 @@ +package org.apache.cloudstack.ldap; + +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.Attributes; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.naming.ldap.LdapContext; + +public class LdapUserManager { + + @Inject + private LdapConfiguration _ldapConfiguration; + + public LdapUserManager() { + } + + public LdapUserManager(final LdapConfiguration ldapConfiguration) { + _ldapConfiguration = ldapConfiguration; + } + + private 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 realname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getRealnameAttribute()); + final String principal = result.getName() + "," + _ldapConfiguration.getBaseDn(); + + return new LdapUser(username, email, realname, principal); + } + + public LdapUser getUser(final String username, final LdapContext context) throws NamingException { + final NamingEnumeration result = searchUsers(username, context); + if (result.hasMoreElements()) { + return createUser(result.nextElement()); + } else { + throw new NamingException("No user found for username " + username); + } + } + + public List getUsers(final LdapContext context) throws NamingException { + return getUsers(null, context); + } + + public List getUsers(final String username, final LdapContext context) throws NamingException { + final NamingEnumeration results = searchUsers(username, context); + + final List users = new ArrayList(); + + while (results.hasMoreElements()) { + final SearchResult result = results.nextElement(); + users.add(createUser(result)); + } + + Collections.sort(users); + + return users; + } + + public NamingEnumeration searchUsers(final LdapContext context) throws NamingException { + return searchUsers(null, context); + } + + public NamingEnumeration searchUsers(final String username, final LdapContext context) throws NamingException { + final SearchControls controls = new SearchControls(); + + controls.setSearchScope(_ldapConfiguration.getScope()); + controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes()); + + final String filter = "(&(objectClass=" + _ldapConfiguration.getUserObject() + ")" + "(" + + _ldapConfiguration.getUsernameAttribute() + "=" + (username == null ? "*" : username) + "))"; + + return context.search(_ldapConfiguration.getBaseDn(), filter, controls); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUtils.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUtils.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUtils.java new file mode 100644 index 0000000..d7c4831 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUtils.java @@ -0,0 +1,46 @@ +package org.apache.cloudstack.ldap; + +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; + +public final class LdapUtils { + + public static String escapeLDAPSearchFilter(final String filter) { + final StringBuilder sb = new StringBuilder(); + for (char character : filter.toCharArray()) { + switch (character) { + case '\\': + sb.append("\\5c"); + break; + case '*': + sb.append("\\2a"); + break; + case '(': + sb.append("\\28"); + break; + case ')': + sb.append("\\29"); + break; + case '\u0000': + sb.append("\\00"); + break; + default: + sb.append(character); + } + } + return sb.toString(); + } + + public static String getAttributeValue(final Attributes attributes, final String attributeName) throws NamingException { + final Attribute attribute = attributes.get(attributeName); + if (attribute != null) { + final Object value = attribute.get(); + return String.valueOf(value); + } + return null; + } + + private LdapUtils() { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java new file mode 100644 index 0000000..3194653 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java @@ -0,0 +1,16 @@ +package org.apache.cloudstack.ldap; + +public class NoLdapUserMatchingQueryException extends Exception { + private static final long serialVersionUID = 7124360347208388174L; + + private final String query; + + public NoLdapUserMatchingQueryException(final String query) { + super("No users matching: " + query); + this.query = query; + } + + public String getQuery() { + return query; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoSuchLdapUserException.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoSuchLdapUserException.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoSuchLdapUserException.java new file mode 100644 index 0000000..c089664 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoSuchLdapUserException.java @@ -0,0 +1,15 @@ +package org.apache.cloudstack.ldap; + +public class NoSuchLdapUserException extends Exception { + private static final long serialVersionUID = 6782938919658010900L; + private final String username; + + public NoSuchLdapUserException(final String username) { + super("No such user: " + username); + this.username = username; + } + + public String getUsername() { + return username; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java new file mode 100644 index 0000000..14f9947 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java @@ -0,0 +1,14 @@ +package org.apache.cloudstack.ldap.dao; + +import java.util.List; + +import org.apache.cloudstack.ldap.LdapConfigurationVO; + +import com.cloud.utils.Pair; +import com.cloud.utils.db.GenericDao; + +public interface LdapConfigurationDao extends GenericDao { + LdapConfigurationVO findByHostname(String hostname); + + Pair, Integer> searchConfigurations(String hostname, int port); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java new file mode 100644 index 0000000..eaeae99 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java @@ -0,0 +1,50 @@ +package org.apache.cloudstack.ldap.dao; + +import java.util.List; + +import javax.ejb.Local; + +import org.springframework.stereotype.Component; + +import org.apache.cloudstack.ldap.LdapConfigurationVO; + +import com.cloud.utils.Pair; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +@Component +@Local(value = {LdapConfigurationDao.class}) +public class LdapConfigurationDaoImpl extends GenericDaoBase implements LdapConfigurationDao { + private final SearchBuilder hostnameSearch; + private final SearchBuilder listAllConfigurationsSearch; + + public LdapConfigurationDaoImpl() { + super(); + hostnameSearch = createSearchBuilder(); + hostnameSearch.and("hostname", hostnameSearch.entity().getHostname(), SearchCriteria.Op.EQ); + hostnameSearch.done(); + + listAllConfigurationsSearch = createSearchBuilder(); + listAllConfigurationsSearch.and("hostname", listAllConfigurationsSearch.entity().getHostname(), Op.EQ); + listAllConfigurationsSearch.and("port", listAllConfigurationsSearch.entity().getPort(), Op.EQ); + listAllConfigurationsSearch.done(); + } + + @Override + public LdapConfigurationVO findByHostname(final String hostname) { + final SearchCriteria sc = hostnameSearch.create(); + sc.setParameters("hostname", hostname); + return findOneBy(sc); + } + + @Override + public Pair, Integer> searchConfigurations(final String hostname, final int port) { + final SearchCriteria sc = listAllConfigurationsSearch.create(); + if (hostname != null) { + sc.setParameters("hostname", hostname); + } + return searchAndCount(sc, null); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy new file mode 100644 index 0000000..6dd81b8 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy @@ -0,0 +1,40 @@ +package groovy.org.apache.cloudstack.ldap + +import javax.naming.NamingEnumeration +import javax.naming.NamingException +import javax.naming.directory.SearchResult + +class BasicNamingEnumerationImpl implements NamingEnumeration { + + private LinkedList items = new LinkedList(); + + @Override + public boolean hasMoreElements() { + return items.size != 0; + } + + @Override + public Object nextElement() { + SearchResult result = items.getFirst(); + items.removeFirst(); + return result; + } + + @Override + public void close() throws NamingException { + } + + @Override + public boolean hasMore() throws NamingException { + return hasMoreElements(); + } + + @Override + public Object next() throws NamingException { + return nextElement(); + } + + public void add(SearchResult item) { + items.add(item) + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy new file mode 100644 index 0000000..225d660 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy @@ -0,0 +1,73 @@ +package groovy.org.apache.cloudstack.ldap + +import com.cloud.exception.InvalidParameterValueException +import org.apache.cloudstack.api.ServerApiException +import org.apache.cloudstack.api.command.LdapAddConfigurationCmd +import org.apache.cloudstack.api.response.LdapConfigurationResponse +import org.apache.cloudstack.ldap.LdapManager + +class LdapAddConfigurationCmdSpec extends spock.lang.Specification { + + def "Test successful response from execute"() { + given: + def ldapManager = Mock(LdapManager) + ldapManager.addConfiguration(_, _) >> new LdapConfigurationResponse("localhost", 389) + def ldapAddConfigurationCmd = new LdapAddConfigurationCmd(ldapManager) + when: + ldapAddConfigurationCmd.execute() + then: + ldapAddConfigurationCmd.responseObject.hostname == "localhost" + ldapAddConfigurationCmd.responseObject.port == 389 + } + + def "Test failed response from execute"() { + given: + def ldapManager = Mock(LdapManager) + ldapManager.addConfiguration(_, _) >> { throw new InvalidParameterValueException() } + def ldapAddConfigurationCmd = new LdapAddConfigurationCmd(ldapManager) + when: + ldapAddConfigurationCmd.execute() + then: + thrown ServerApiException + } + + def "Test successful setting of hostname"() { + given: + def ldapManager = Mock(LdapManager) + def ldapAddConfigurationCmd = new LdapAddConfigurationCmd(ldapManager) + when: + ldapAddConfigurationCmd.setHostname("localhost") + then: + ldapAddConfigurationCmd.getHostname() == "localhost" + } + + def "Test successful setting of port"() { + given: + def ldapManager = Mock(LdapManager) + def ldapAddConfigurationCmd = new LdapAddConfigurationCmd(ldapManager) + when: + ldapAddConfigurationCmd.setPort(389) + then: + ldapAddConfigurationCmd.getPort() == 389 + } + + def "Test getEntityOwnerId is 0"() { + given: + def ldapManager = Mock(LdapManager) + def ldapAddConfigurationCmd = new LdapAddConfigurationCmd(ldapManager) + when: + long ownerId = ldapAddConfigurationCmd.getEntityOwnerId() + then: + ownerId == 0 + } + + def "Test successful return of getCommandName"() { + given: + def ldapManager = Mock(LdapManager) + def ldapAddConfigurationCmd = new LdapAddConfigurationCmd(ldapManager) + when: + String commandName = ldapAddConfigurationCmd.getCommandName() + then: + commandName == "ldapconfigurationresponse" + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy new file mode 100644 index 0000000..912df30 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy @@ -0,0 +1,74 @@ +package groovy.org.apache.cloudstack.ldap + +import com.cloud.user.UserAccountVO +import com.cloud.user.dao.UserAccountDao +import com.cloud.utils.Pair +import org.apache.cloudstack.ldap.LdapAuthenticator +import org.apache.cloudstack.ldap.LdapConfigurationVO +import org.apache.cloudstack.ldap.LdapManager + +class LdapAuthenticatorSpec extends spock.lang.Specification { + + def "Test a failed authentication due to user not being found within cloudstack"() { + given: + LdapManager ldapManager = Mock(LdapManager) + UserAccountDao userAccountDao = Mock(UserAccountDao) + userAccountDao.getUserAccount(_, _) >> null + def ldapAuthenticator = new LdapAuthenticator(ldapManager, userAccountDao) + when: + def result = ldapAuthenticator.authenticate("rmurphy", "password", 0, null) + then: + result == false + } + + def "Test failed authentication due to ldap not being configured"() { + given: + def ldapManager = Mock(LdapManager) + List ldapConfigurationList = new ArrayList() + Pair, Integer> ldapConfigurations = new Pair, Integer>(); + ldapConfigurations.set(ldapConfigurationList, ldapConfigurationList.size()) + ldapManager.listConfigurations(_) >> ldapConfigurations + + UserAccountDao userAccountDao = Mock(UserAccountDao) + userAccountDao.getUserAccount(_, _) >> new UserAccountVO() + + def ldapAuthenticator = new LdapAuthenticator(ldapManager, userAccountDao) + when: + def result = ldapAuthenticator.authenticate("rmurphy", "password", 0, null) + then: + result == false + } + + def "Test failed authentication due to ldap bind being unsuccessful"() { + given: + + def ldapManager = Mock(LdapManager) + List ldapConfigurationList = new ArrayList() + ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389)) + Pair, Integer> ldapConfigurations = new Pair, Integer>(); + ldapConfigurations.set(ldapConfigurationList, ldapConfigurationList.size()) + ldapManager.listConfigurations(_) >> ldapConfigurations + ldapManager.canAuthenticate(_, _) >> false + + UserAccountDao userAccountDao = Mock(UserAccountDao) + userAccountDao.getUserAccount(_, _) >> new UserAccountVO() + def ldapAuthenticator = new LdapAuthenticator(ldapManager, userAccountDao) + + when: + def result = ldapAuthenticator.authenticate("rmurphy", "password", 0, null) + + then: + result == false + } + + def "Test that encode doesn't change the input"() { + given: + LdapManager ldapManager = Mock(LdapManager) + UserAccountDao userAccountDao = Mock(UserAccountDao) + def ldapAuthenticator = new LdapAuthenticator(ldapManager, userAccountDao) + when: + def result = ldapAuthenticator.encode("password") + then: + result == "password" + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy new file mode 100644 index 0000000..2ceae5d --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy @@ -0,0 +1,13 @@ +package groovy.org.apache.cloudstack.ldap + +import org.apache.cloudstack.ldap.dao.LdapConfigurationDaoImpl + +class LdapConfigurationDaoImplSpec extends spock.lang.Specification { + def "Test setting up of a LdapConfigurationDao"() { + given: + def ldapConfigurationDaoImpl = new LdapConfigurationDaoImpl(); + expect: + ldapConfigurationDaoImpl.hostnameSearch != null; + ldapConfigurationDaoImpl.listAllConfigurationsSearch != null + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy new file mode 100644 index 0000000..899267a --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy @@ -0,0 +1,33 @@ +package groovy.org.apache.cloudstack.ldap + +import org.apache.cloudstack.api.response.LdapConfigurationResponse + +class LdapConfigurationResponseSpec extends spock.lang.Specification { + def "Testing succcessful setting of LdapConfigurationResponse hostname"() { + given: + LdapConfigurationResponse response = new LdapConfigurationResponse(); + when: + response.setHostname("localhost"); + then: + response.getHostname() == "localhost"; + } + + def "Testing successful setting of LdapConfigurationResponse port"() { + given: + LdapConfigurationResponse response = new LdapConfigurationResponse() + when: + response.setPort(389) + then: + response.getPort() == 389 + } + + def "Testing successful setting of LdapConfigurationResponse hostname and port via constructor"() { + given: + LdapConfigurationResponse response + when: + response = new LdapConfigurationResponse("localhost", 389) + then: + response.getHostname() == "localhost" + response.getPort() == 389 + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/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 new file mode 100644 index 0000000..c0208a8 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy @@ -0,0 +1,167 @@ +package groovy.org.apache.cloudstack.ldap + +import com.cloud.configuration.dao.ConfigurationDao +import com.cloud.utils.Pair +import org.apache.cloudstack.api.ServerApiException +import org.apache.cloudstack.ldap.LdapConfiguration +import org.apache.cloudstack.ldap.LdapConfigurationVO +import org.apache.cloudstack.ldap.LdapManager + +import javax.naming.directory.SearchControls + +class LdapConfigurationSpec extends spock.lang.Specification { + def "Test that providerUrl successfully returns a URL when a configuration is available"() { + given: + def configDao = Mock(ConfigurationDao) + + def ldapManager = Mock(LdapManager) + List ldapConfigurationList = new ArrayList() + ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389)) + Pair, Integer> result = new Pair, Integer>(); + result.set(ldapConfigurationList, ldapConfigurationList.size()) + ldapManager.listConfigurations(_) >> result + + LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + + when: + String providerUrl = ldapConfiguration.getProviderUrl() + + then: + providerUrl == "ldap://localhost:389" + } + + def "Test that exception is thrown when no configuration is found"() { + given: + def configDao = Mock(ConfigurationDao) + def ldapManager = Mock(LdapManager) + List ldapConfigurationList = new ArrayList() + Pair, Integer> result = new Pair, Integer>(); + result.set(ldapConfigurationList, ldapConfigurationList.size()) + ldapManager.listConfigurations(_) >> result + LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + ldapConfiguration.getProviderUrl() + then: + thrown ServerApiException + } + + def "Test that getAuthentication returns simple"() { + given: + def configDao = Mock(ConfigurationDao) + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + configDao.getValue("ldap.bind.password") >> "password" + configDao.getValue("ldap.bind.principal") >> "cn=rmurphy,dc=cloudstack,dc=org" + when: + String authentication = ldapConfiguration.getAuthentication() + then: + authentication == "simple" + } + + def "Test that getAuthentication returns none"() { + given: + def configDao = Mock(ConfigurationDao) + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String authentication = ldapConfiguration.getAuthentication() + then: + authentication == "none" + } + + def "Test that getEmailAttribute returns mail"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.email.attribute") >> "mail" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String emailAttribute = ldapConfiguration.getEmailAttribute() + then: + emailAttribute == "mail" + } + + def "Test that getUsernameAttribute returns uid"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.username.attribute") >> "uid" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String usernameAttribute = ldapConfiguration.getUsernameAttribute() + then: + usernameAttribute == "uid" + } + + def "Test that getRealnameAttribute returns cn"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.realname.attribute") >> "cn" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String realname = ldapConfiguration.getRealnameAttribute() + then: + realname == "cn" + } + + def "Test that getUserObject returns inetOrgPerson"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.user.object") >> "inetOrgPerson" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String realname = ldapConfiguration.getUserObject() + then: + realname == "inetOrgPerson" + } + + def "Test that getReturnAttributes returns the correct data"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.realname.attribute") >> "cn" + configDao.getValue("ldap.username.attribute") >> "uid" + configDao.getValue("ldap.email.attribute") >> "mail" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String[] returnAttributes = ldapConfiguration.getReturnAttributes() + then: + returnAttributes == ["uid", "mail", "cn"] + } + + def "Test that getScope returns SearchControls.SUBTREE_SCOPE"() { + given: + def configDao = Mock(ConfigurationDao) + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + int scope = ldapConfiguration.getScope() + then: + scope == SearchControls.SUBTREE_SCOPE; + } + + def "Test that getBaseDn returns dc=cloudstack,dc=org"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.basedn") >> "dc=cloudstack,dc=org" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String baseDn = ldapConfiguration.getBaseDn(); + then: + baseDn == "dc=cloudstack,dc=org" + } + + def "Test that getFactory returns com.sun.jndi.ldap.LdapCtxFactory"() { + given: + def configDao = Mock(ConfigurationDao) + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String factory = ldapConfiguration.getFactory(); + then: + factory == "com.sun.jndi.ldap.LdapCtxFactory" + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy new file mode 100644 index 0000000..dabf805 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy @@ -0,0 +1,36 @@ +package groovy.org.apache.cloudstack.ldap + +import org.apache.cloudstack.ldap.LdapConfigurationVO + + +class LdapConfigurationVOSpec extends spock.lang.Specification { + def "Testing that the hostname is correctly set with the LDAP configuration VO"() { + given: "You have created a LDAP configuration VO with a hostname set" + def configuration = new LdapConfigurationVO() + configuration.setHostname(hostname) + expect: "The hostname is equal to the given data source" + configuration.getHostname() == hostname + where: "The hostname is set to " + hostname << ["", null, "localhost"] + } + + def "Testing that the port is correctly set within the LDAP configuration VO"() { + given: "You have created a LDAP configuration VO with a port set" + def configuration = new LdapConfigurationVO() + configuration.setPort(port) + expect: "The port is equal to the given data source" + configuration.getPort() == port + where: "The port is set to " + port << [0, 1000, -1000, -0] + } + + def "Testing that the ID is correctly set within the LDAP configuration VO"() { + given: "You have created an LDAP Configuration VO" + def configuration = new LdapConfigurationVO("localhost", 389); + configuration.setId(id); + expect: "The id is equal to the given data source" + configuration.getId() == id; + where: "The id is set to " + id << [0, 1000, -1000, -0] + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy new file mode 100644 index 0000000..1f97012 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy @@ -0,0 +1,117 @@ +package groovy.org.apache.cloudstack.ldap + +import org.apache.cloudstack.ldap.LdapConfiguration +import org.apache.cloudstack.ldap.LdapContextFactory +import spock.lang.Shared + +import javax.naming.NamingException +import javax.naming.directory.SearchControls +import javax.naming.ldap.LdapContext + +class LdapContextFactorySpec extends spock.lang.Specification { + @Shared + private def ldapConfiguration + + @Shared + private def username + + @Shared + private def principal + + @Shared + private def password + + def setupSpec() { + ldapConfiguration = Mock(LdapConfiguration) + + ldapConfiguration.getFactory() >> "com.sun.jndi.ldap.LdapCtxFactory" + ldapConfiguration.getProviderUrl() >> "ldap://localhost:389" + ldapConfiguration.getAuthentication() >> "none" + ldapConfiguration.getScope() >> SearchControls.SUBTREE_SCOPE + ldapConfiguration.getReturnAttributes() >> ["uid", "mail", "cn"] + ldapConfiguration.getUsernameAttribute() >> "uid" + ldapConfiguration.getEmailAttribute() >> "mail" + ldapConfiguration.getRealnameAttribute() >> "cn" + ldapConfiguration.getBaseDn() >> "dc=cloudstack,dc=org" + + username = "rmurphy" + principal = "cn=" + username + "," + ldapConfiguration.getBaseDn() + password = "password" + } + + def "Test successfully creating a system environment with anon bind"() { + given: + def ldapContextFactory = new LdapContextFactory(ldapConfiguration) + + when: + def result = ldapContextFactory.getEnvironment(principal, password, null, false) + + then: + result['java.naming.provider.url'] == ldapConfiguration.getProviderUrl() + result['java.naming.factory.initial'] == ldapConfiguration.getFactory() + result['java.naming.security.principal'] == principal + result['java.naming.security.authentication'] == "simple" + result['java.naming.security.credentials'] == password + } + + def "Test successfully creating a environment with username and password"() { + given: + def ldapContextFactory = new LdapContextFactory(ldapConfiguration) + + when: + def result = ldapContextFactory.getEnvironment(null, null, null, true) + + then: + result['java.naming.provider.url'] == ldapConfiguration.getProviderUrl() + result['java.naming.factory.initial'] == ldapConfiguration.getFactory() + result['java.naming.security.principal'] == null + result['java.naming.security.authentication'] == ldapConfiguration.getAuthentication() + result['java.naming.security.credentials'] == null + } + + def "Test successfully binding as a user"() { + given: + def ldapContextFactory = new LdapContextFactory(ldapConfiguration) + when: + ldapContextFactory.createUserContext(principal, password) + then: + thrown NamingException + } + + def "Test successully binding as system"() { + given: + def ldapContextFactory = new LdapContextFactory(ldapConfiguration) + when: + ldapContextFactory.createBindContext() + then: + thrown NamingException + } + + def "Test succcessfully creating a initial context"() { + given: + def ldapContextFactory = new LdapContextFactory(ldapConfiguration) + when: + ldapContextFactory.createInitialDirContext(null, null, true) + then: + thrown NamingException + } + + def "Test successful failed connection"() { + given: + def ldapContextFactory = Spy(LdapContextFactory, constructorArgs: [ldapConfiguration]) + when: + ldapContextFactory.testConnection(ldapConfiguration.getProviderUrl()) + then: + thrown NamingException + } + + def "Test successful connection"() { + given: + def ldapContextFactory = Spy(LdapContextFactory, constructorArgs: [ldapConfiguration]) + ldapContextFactory.createBindContext(_) >> Mock(LdapContext) + when: + ldapContextFactory.testConnection(ldapConfiguration.getProviderUrl()) + then: + notThrown NamingException + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy new file mode 100644 index 0000000..31a2047 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy @@ -0,0 +1,62 @@ +package groovy.org.apache.cloudstack.ldap + +import com.cloud.exception.InvalidParameterValueException +import org.apache.cloudstack.api.ServerApiException +import org.apache.cloudstack.api.command.LdapDeleteConfigurationCmd +import org.apache.cloudstack.api.response.LdapConfigurationResponse +import org.apache.cloudstack.ldap.LdapManager + +class LdapDeleteConfigurationCmdSpec extends spock.lang.Specification { + + def "Test successful response from execute"() { + given: + def ldapManager = Mock(LdapManager) + ldapManager.deleteConfiguration(_) >> new LdapConfigurationResponse("localhost") + def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager) + when: + ldapDeleteConfigurationCmd.execute() + then: + ldapDeleteConfigurationCmd.responseObject.hostname == "localhost" + } + + def "Test failed response from execute"() { + given: + def ldapManager = Mock(LdapManager) + ldapManager.deleteConfiguration(_) >> { throw new InvalidParameterValueException() } + def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager) + when: + ldapDeleteConfigurationCmd.execute() + then: + thrown ServerApiException + } + + def "Test successful setting of hostname"() { + given: + def ldapManager = Mock(LdapManager) + def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager) + when: + ldapDeleteConfigurationCmd.setHostname("localhost") + then: + ldapDeleteConfigurationCmd.getHostname() == "localhost" + } + + def "Test getEntityOwnerId is 0"() { + given: + def ldapManager = Mock(LdapManager) + def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager) + when: + long ownerId = ldapDeleteConfigurationCmd.getEntityOwnerId() + then: + ownerId == 0 + } + + def "Test successful return of getCommandName"() { + given: + def ldapManager = Mock(LdapManager) + def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager) + when: + String commandName = ldapDeleteConfigurationCmd.getCommandName() + then: + commandName == "ldapconfigurationresponse" + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy new file mode 100644 index 0000000..ee0808e --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy @@ -0,0 +1,56 @@ +package groovy.org.apache.cloudstack.ldap + +import org.apache.cloudstack.api.ServerApiException +import org.apache.cloudstack.api.command.LdapListAllUsersCmd +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 LdapListAllUsersCmdSpec extends spock.lang.Specification { + def "Test successful response from execute"() { + given: + def ldapManager = Mock(LdapManager) + List users = new ArrayList() + users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan Murphy", "cn=rmurphy,dc=cloudstack,dc=org")) + ldapManager.getUsers() >> users + LdapUserResponse response = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan Murphy", "cn=rmurphy,dc=cloudstack,dc=org") + ldapManager.createLdapUserResponse(_) >> response + def ldapListAllUsersCmd = new LdapListAllUsersCmd(ldapManager) + when: + ldapListAllUsersCmd.execute() + then: + ldapListAllUsersCmd.responseObject.getResponses().size() != 0 + } + + def "Test successful empty response from execute"() { + given: + def ldapManager = Mock(LdapManager) + ldapManager.getUsers() >> {throw new NoLdapUserMatchingQueryException()} + def ldapListAllUsersCmd = new LdapListAllUsersCmd(ldapManager) + when: + ldapListAllUsersCmd.execute() + then: + thrown ServerApiException + } + + def "Test getEntityOwnerId is 0"() { + given: + def ldapManager = Mock(LdapManager) + def ldapListAllUsersCmd = new LdapListAllUsersCmd(ldapManager) + when: + long ownerId = ldapListAllUsersCmd.getEntityOwnerId() + then: + ownerId == 0 + } + + def "Test successful return of getCommandName"() { + given: + def ldapManager = Mock(LdapManager) + def ldapListAllUsersCmd = new LdapListAllUsersCmd(ldapManager) + when: + String commandName = ldapListAllUsersCmd.getCommandName() + then: + commandName == "ldapuserresponse" + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy new file mode 100644 index 0000000..c3ca237 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy @@ -0,0 +1,85 @@ +package groovy.org.apache.cloudstack.ldap + +import org.apache.cloudstack.api.ServerApiException +import org.apache.cloudstack.api.command.LdapListConfigurationCmd +import org.apache.cloudstack.api.response.LdapConfigurationResponse +import org.apache.cloudstack.ldap.LdapConfigurationVO +import org.apache.cloudstack.ldap.LdapManager + +import com.cloud.utils.Pair + +class LdapListConfigurationCmdSpec extends spock.lang.Specification { + + def "Test successful response from execute"() { + given: + def ldapManager = Mock(LdapManager) + List ldapConfigurationList = new ArrayList() + ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389)) + Pair, Integer> ldapConfigurations = new Pair, Integer>(); + ldapConfigurations.set(ldapConfigurationList, ldapConfigurationList.size()) + ldapManager.listConfigurations(_) >> ldapConfigurations + ldapManager.createLdapConfigurationResponse(_) >> new LdapConfigurationResponse("localhost", 389) + def ldapListConfigurationCmd = new LdapListConfigurationCmd(ldapManager) + when: + ldapListConfigurationCmd.execute() + then: + ldapListConfigurationCmd.getResponseObject().getResponses().size() != 0 + } + + def "Test failed response from execute"() { + given: + + def ldapManager = Mock(LdapManager) + List ldapConfigurationList = new ArrayList() + Pair, Integer> ldapConfigurations = new Pair, Integer>(); + ldapConfigurations.set(ldapConfigurationList, ldapConfigurationList.size()) + ldapManager.listConfigurations(_) >> ldapConfigurations + + def ldapListConfigurationCmd = new LdapListConfigurationCmd(ldapManager) + when: + ldapListConfigurationCmd.execute() + then: + thrown ServerApiException + } + + def "Test successful setting of hostname"() { + given: + def ldapManager = Mock(LdapManager) + def ldapListConfigurationCmd = new LdapListConfigurationCmd(ldapManager) + when: + ldapListConfigurationCmd.setHostname("localhost") + then: + ldapListConfigurationCmd.getHostname() == "localhost" + } + + def "Test successful setting of Port"() { + given: + def ldapManager = Mock(LdapManager) + def ldapListConfigurationCmd = new LdapListConfigurationCmd(ldapManager) + when: + ldapListConfigurationCmd.setPort(389) + then: + ldapListConfigurationCmd.getPort() == 389 + } + + def "Test getEntityOwnerId is 0"() { + given: + def ldapManager = Mock(LdapManager) + def ldapListConfigurationCmd = new LdapListConfigurationCmd(ldapManager) + when: + long ownerId = ldapListConfigurationCmd.getEntityOwnerId() + then: + ownerId == 0 + } + + def "Test successful return of getCommandName"() { + given: + def ldapManager = Mock(LdapManager) + def ldapListConfigurationCmd = new LdapListConfigurationCmd(ldapManager) + when: + String commandName = ldapListConfigurationCmd.getCommandName() + then: + commandName == "ldapconfigurationresponse" + } +} + http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/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..689c52b --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy @@ -0,0 +1,301 @@ +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.realname == "Ryan 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.realname == "Ryan 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 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 ldapConfigurationList = new ArrayList() + ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389)) + Pair, Integer> configurations = new Pair, Integer>(); + configurations.set(ldapConfigurationList, ldapConfigurationList.size()) + ldapConfigurationDao.searchConfigurations(_, _) >> configurations + def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager) + 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 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.searchUsers("rmurphy"); + then: + result.size() > 0; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/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..64f55c3 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy @@ -0,0 +1,66 @@ +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 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: + thrown ServerApiException + } + + def "Test getEntityOwnerId is 0"() { + given: + def ldapManager = Mock(LdapManager) + def ldapUserSearchCmd = new LdapUserSearchCmd(ldapManager) + when: + long ownerId = ldapUserSearchCmd.getEntityOwnerId() + then: + ownerId == 0 + } + + def "Test successful setting of ldapUserSearchCmd Query"() { + given: + def ldapManager = Mock(LdapManager) + def ldapUserSearchCmd = new LdapUserSearchCmd(ldapManager) + when: + ldapUserSearchCmd.setQuery("") + then: + ldapUserSearchCmd.getQuery() == "" + } + + 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/a90affe4/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..1ee7d6f --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy @@ -0,0 +1,179 @@ +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 realname + + @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.getRealnameAttribute() >> "cn" + ldapConfiguration.getBaseDn() >> "dc=cloudstack,dc=org" + + username = "rmurphy" + email = "rmurphy@test.com" + realname = "Ryan 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, realname) + def search = createSearchResult(attributes) + def userManager = new LdapUserManager(ldapConfiguration) + def result = userManager.createUser(search) + + expect: + + result.username == username + result.email == email + result.realname == realname + 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.realname == realname + 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, realname) + 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 realname) { + 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 cnAttribute = Mock(Attribute) + cnAttribute.getId() >> "cn" + cnAttribute.get() >> realname + attributes.get("cn") >> cnAttribute + + return attributes + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/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..f96f33d --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy @@ -0,0 +1,42 @@ +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 realname"() { + given: + LdapUserResponse response = new LdapUserResponse() + when: + response.setRealname("Ryan Murphy") + then: + response.getRealname() == "Ryan Murphy" + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a90affe4/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..1293a0e --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy @@ -0,0 +1,54 @@ +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 realname" + 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 realname is correctly set with the ldap object"() { + given: "You have created a LDAP user object with a realname" + def user = new LdapUser("", "", realname, "") + expect: "The realname is equal to the given data source" + user.getRealname() == realname + where: "The realname is set to " + realname << ["", null, "Ryan 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/a90affe4/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..3133493 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy @@ -0,0 +1,52 @@ +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/a90affe4/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..e2b78dd --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy @@ -0,0 +1,14 @@ +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