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 5B79E10745 for ; Sat, 31 Aug 2013 21:11:47 +0000 (UTC) Received: (qmail 2707 invoked by uid 500); 31 Aug 2013 21:11:47 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 2665 invoked by uid 500); 31 Aug 2013 21:11:47 -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 2642 invoked by uid 99); 31 Aug 2013 21:11:47 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 31 Aug 2013 21:11:47 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id D33738BA789; Sat, 31 Aug 2013 21:11:46 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: duffy@apache.org To: commits@cloudstack.apache.org Date: Sat, 31 Aug 2013 21:11:48 -0000 Message-Id: <2d31711a36f44ae8b0500046f590b4b7@git.apache.org> In-Reply-To: <743c6db971a149b59edb52e9f3f8fb9f@git.apache.org> References: <743c6db971a149b59edb52e9f3f8fb9f@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [03/20] Merge LDAPPlugin http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfigurationVO.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfigurationVO.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfigurationVO.java new file mode 100644 index 0000000..5a243f2 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfigurationVO.java @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name = "ldap_configuration") +public class LdapConfigurationVO implements InternalIdentity { + @Column(name = "hostname") + private String hostname; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "port") + private int port; + + public LdapConfigurationVO() { + } + + public LdapConfigurationVO(final String hostname, final int port) { + this.hostname = hostname; + this.port = port; + } + + public String getHostname() { + return hostname; + } + + @Override + public long getId() { + return id; + } + + public int getPort() { + return port; + } + + public void setId(long id) { + this.id = id; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java new file mode 100644 index 0000000..fd33e88 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java @@ -0,0 +1,103 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +import java.util.Hashtable; + +import javax.inject.Inject; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; + +import org.apache.log4j.Logger; + +public class LdapContextFactory { + private static final Logger s_logger = Logger.getLogger(LdapContextFactory.class.getName()); + + @Inject + private LdapConfiguration _ldapConfiguration; + + public LdapContextFactory() { + } + + public LdapContextFactory(final LdapConfiguration ldapConfiguration) { + _ldapConfiguration = ldapConfiguration; + } + + public DirContext createBindContext() throws NamingException { + return createBindContext(null); + } + + public DirContext createBindContext(final String providerUrl) throws NamingException { + final String bindPrincipal = _ldapConfiguration.getBindPrincipal(); + final String bindPassword = _ldapConfiguration.getBindPassword(); + return createInitialDirContext(bindPrincipal, bindPassword, providerUrl, true); + } + + private DirContext createInitialDirContext(final String principal, final String password, final boolean isSystemContext) throws NamingException { + return createInitialDirContext(principal, password, null, isSystemContext); + } + + private DirContext createInitialDirContext(final String principal, final String password, final String providerUrl, final boolean isSystemContext) throws NamingException { + return new InitialDirContext(getEnvironment(principal, password, providerUrl, isSystemContext)); + } + + public DirContext createUserContext(final String principal, final String password) throws NamingException { + return createInitialDirContext(principal, password, false); + } + + private Hashtable getEnvironment(final String principal, final String password, final String providerUrl, final boolean isSystemContext) { + final String factory = _ldapConfiguration.getFactory(); + final String url = providerUrl == null ? _ldapConfiguration.getProviderUrl() : providerUrl; + final String authentication = _ldapConfiguration.getAuthentication(); + + final Hashtable environment = new Hashtable(); + + environment.put(Context.INITIAL_CONTEXT_FACTORY, factory); + environment.put(Context.PROVIDER_URL, url); + environment.put("com.sun.jndi.ldap.read.timeout", "500"); + environment.put("com.sun.jndi.ldap.connect.pool", "true"); + + if ("none".equals(authentication) && !isSystemContext) { + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + } else { + environment.put(Context.SECURITY_AUTHENTICATION, authentication); + } + + if (principal != null) { + environment.put(Context.SECURITY_PRINCIPAL, principal); + } + + if (password != null) { + environment.put(Context.SECURITY_CREDENTIALS, password); + } + + return environment; + } + + public void testConnection(final String providerUrl) throws NamingException { + try { + createBindContext(providerUrl); + s_logger.info("LDAP Connection was successful"); + } catch (final NamingException e) { + s_logger.warn("LDAP Connection failed"); + s_logger.error(e.getMessage(), e); + throw e; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java new file mode 100644 index 0000000..aa0b751 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java @@ -0,0 +1,50 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +import java.util.List; + +import javax.naming.NamingException; + +import org.apache.cloudstack.api.command.LdapListConfigurationCmd; +import org.apache.cloudstack.api.response.LdapConfigurationResponse; +import org.apache.cloudstack.api.response.LdapUserResponse; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.utils.Pair; +import com.cloud.utils.component.PluggableService; + +public interface LdapManager extends PluggableService { + + LdapConfigurationResponse addConfiguration(String hostname, int port) throws InvalidParameterValueException; + + boolean canAuthenticate(String username, String password); + + LdapConfigurationResponse createLdapConfigurationResponse(LdapConfigurationVO configuration); + + LdapUserResponse createLdapUserResponse(LdapUser user); + + LdapConfigurationResponse deleteConfiguration(String hostname) throws InvalidParameterValueException; + + LdapUser getUser(final String username) throws NamingException; + + List getUsers() throws NoLdapUserMatchingQueryException; + + Pair, Integer> listConfigurations(LdapListConfigurationCmd cmd); + + List searchUsers(String query) throws NoLdapUserMatchingQueryException; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/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..b6fb3e8 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java @@ -0,0 +1,205 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import org.apache.cloudstack.api.command.LdapAddConfigurationCmd; +import org.apache.cloudstack.api.command.LdapCreateAccount; +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 DirContext context = _ldapContextFactory.createUserContext(principal, password); + closeContext(context); + return true; + } catch (final NamingException e) { + s_logger.info("Failed to authenticate user: " + username + ". incorrect password."); + return false; + } + } + + private void closeContext(final DirContext 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.setFirstname(user.getFirstname()); + response.setLastname(user.getLastname()); + 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); + cmdList.add(LdapCreateAccount.class); + return cmdList; + } + + @Override + public LdapUser getUser(final String username) throws NamingException { + DirContext 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 { + DirContext 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 { + DirContext 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/eaa41433/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..6bc1a78 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUser.java @@ -0,0 +1,75 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +public class LdapUser implements Comparable { + private final String email; + private final String principal; + private final String firstname; + private final String lastname; + private final String username; + + public LdapUser(final String username, final String email, final String firstname, final String lastname, final String principal) { + this.username = username; + this.email = email; + this.firstname = firstname; + this.lastname = lastname; + 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 getFirstname() { + return firstname; + } + + public String getLastname() { + return lastname; + } + + public String getPrincipal() { + return principal; + } + + 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/eaa41433/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..f255752 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java @@ -0,0 +1,98 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +import java.util.ArrayList; +import java.util.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.DirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; + +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 firstname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getFirstnameAttribute()); + final String lastname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getLastnameAttribute()); + final String principal = result.getName() + "," + _ldapConfiguration.getBaseDn(); + + return new LdapUser(username, email, firstname, lastname, principal); + } + + public LdapUser getUser(final String username, final DirContext 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 DirContext context) throws NamingException { + return getUsers(null, context); + } + + public List getUsers(final String username, final DirContext 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 DirContext context) throws NamingException { + return searchUsers(null, context); + } + + public NamingEnumeration searchUsers(final String username, final DirContext 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/eaa41433/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..8e7e93e --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUtils.java @@ -0,0 +1,61 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +import 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/eaa41433/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..0f510c3 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java @@ -0,0 +1,32 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +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/eaa41433/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..d9bf13f --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoSuchLdapUserException.java @@ -0,0 +1,31 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap; + +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/eaa41433/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..a2d5e65 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java @@ -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 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/eaa41433/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..0f2a015 --- /dev/null +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.ldap.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/eaa41433/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..ab7e22a --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy @@ -0,0 +1,56 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package groovy.org.apache.cloudstack.ldap + +import 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/eaa41433/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..3dcb23f --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy @@ -0,0 +1,89 @@ +// 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 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 == 1 + } + + 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/eaa41433/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..573f88c --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy @@ -0,0 +1,90 @@ +// 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 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/eaa41433/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..191b609 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy @@ -0,0 +1,29 @@ +// 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.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/eaa41433/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..4e6bebb --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy @@ -0,0 +1,49 @@ +// 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.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/eaa41433/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..a867fd6 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy @@ -0,0 +1,181 @@ +// 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 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 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 getFirstnameAttribute returns givenname"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.firstname.attribute") >> "givenname" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String firstname = ldapConfiguration.getFirstnameAttribute() + then: + firstname == "givenname" + } + + def "Test that getLastnameAttribute returns givenname"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.lastname.attribute") >> "sn" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String lastname = ldapConfiguration.getLastnameAttribute() + then: + lastname == "sn" + } + + 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 userObject = ldapConfiguration.getUserObject() + then: + userObject == "inetOrgPerson" + } + + def "Test that getReturnAttributes returns the correct data"() { + given: + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.firstname.attribute") >> "givenname" + configDao.getValue("ldap.lastname.attribute") >> "sn" + configDao.getValue("ldap.username.attribute") >> "uid" + configDao.getValue("ldap.email.attribute") >> "mail" + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: + String[] returnAttributes = ldapConfiguration.getReturnAttributes() + then: + returnAttributes == ["uid", "mail", "givenname", "sn"] + } + + 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/eaa41433/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..27f3dfc --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy @@ -0,0 +1,36 @@ +// 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.LdapConfigurationVO + + +class LdapConfigurationVOSpec extends spock.lang.Specification { + def "Testing that the ID hostname and port is correctly set within the LDAP configuration VO"() { + given: "You have created an LDAP Configuration VO" + def configuration = new LdapConfigurationVO(hostname, port) + configuration.setId(id) + expect: "The id hostname and port is equal to the given data source" + configuration.getId() == id + configuration.getHostname() == hostname + configuration.getPort() == port + where: "The id, hostname and port is set to " + hostname << ["", null, "localhost"] + id << [0, 1000, -1000] + port << [0, 1000, -1000] + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eaa41433/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..e9b3b6e --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy @@ -0,0 +1,134 @@ +// 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.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.getFirstnameAttribute() >> "givenname" + ldapConfiguration.getLastnameAttribute() >> "sn" + 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/eaa41433/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..f4d185b --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.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 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 getEntityOwnerId is 0"() { + given: + def ldapManager = Mock(LdapManager) + def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager) + when: + long ownerId = ldapDeleteConfigurationCmd.getEntityOwnerId() + then: + ownerId == 1 + } + + 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/eaa41433/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..2756e92 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.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.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 1"() { + given: + def ldapManager = Mock(LdapManager) + def ldapListAllUsersCmd = new LdapListAllUsersCmd(ldapManager) + when: + long ownerId = ldapListAllUsersCmd.getEntityOwnerId() + then: + ownerId == 1 + } + + 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/eaa41433/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..d83b926 --- /dev/null +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy @@ -0,0 +1,100 @@ +// 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.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: + ldapListConfigurationCmd.getResponseObject().getResponses().size() == 0 + } + + 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 == 1 + } + + def "Test successful return of getCommandName"() { + given: + def ldapManager = Mock(LdapManager) + def ldapListConfigurationCmd = new LdapListConfigurationCmd(ldapManager) + when: + String commandName = ldapListConfigurationCmd.getCommandName() + then: + commandName == "ldapconfigurationresponse" + } +}