You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ap...@apache.org on 2013/07/25 14:28:36 UTC
[3/4] 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<String, String> 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<String, String> environment = new Hashtable<String, String>();
+
+ 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<LdapUser> getUsers() throws NoLdapUserMatchingQueryException;
+
+ Pair<List<? extends LdapConfigurationVO>, Integer> listConfigurations(LdapListConfigurationCmd cmd);
+
+ List<LdapUser> 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<Class<?>> getCommands() {
+ final List<Class<?>> cmdList = new ArrayList<Class<?>>();
+ 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<LdapUser> 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<List<? extends LdapConfigurationVO>, Integer> listConfigurations(final LdapListConfigurationCmd cmd) {
+ final String hostname = cmd.getHostname();
+ final int port = cmd.getPort();
+ final Pair<List<LdapConfigurationVO>, Integer> result = _ldapConfigurationDao.searchConfigurations(hostname, port);
+ return new Pair<List<? extends LdapConfigurationVO>, Integer>(result.first(), result.second());
+ }
+
+ @Override
+ public List<LdapUser> 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<LdapUser> {
+ 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<SearchResult> result = searchUsers(username, context);
+ if (result.hasMoreElements()) {
+ return createUser(result.nextElement());
+ } else {
+ throw new NamingException("No user found for username " + username);
+ }
+ }
+
+ public List<LdapUser> getUsers(final DirContext context) throws NamingException {
+ return getUsers(null, context);
+ }
+
+ public List<LdapUser> getUsers(final String username, final DirContext context) throws NamingException {
+ final NamingEnumeration<SearchResult> results = searchUsers(username, context);
+
+ final List<LdapUser> users = new ArrayList<LdapUser>();
+
+ while (results.hasMoreElements()) {
+ final SearchResult result = results.nextElement();
+ users.add(createUser(result));
+ }
+
+ Collections.sort(users);
+
+ return users;
+ }
+
+ public NamingEnumeration<SearchResult> searchUsers(final DirContext context) throws NamingException {
+ return searchUsers(null, context);
+ }
+
+ public NamingEnumeration<SearchResult> 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, Long> {
+ LdapConfigurationVO findByHostname(String hostname);
+
+ Pair<List<LdapConfigurationVO>, 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<LdapConfigurationVO, Long> implements LdapConfigurationDao {
+ private final SearchBuilder<LdapConfigurationVO> hostnameSearch;
+ private final SearchBuilder<LdapConfigurationVO> 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<LdapConfigurationVO> sc = hostnameSearch.create();
+ sc.setParameters("hostname", hostname);
+ return findOneBy(sc);
+ }
+
+ @Override
+ public Pair<List<LdapConfigurationVO>, Integer> searchConfigurations(final String hostname, final int port) {
+ final SearchCriteria<LdapConfigurationVO> 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<String> items = new LinkedList<SearchResult>();
+
+ @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<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
+ Pair<List<LdapConfigurationVO>, Integer> ldapConfigurations = new Pair<List<LdapConfigurationVO>, 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<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
+ ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
+ Pair<List<LdapConfigurationVO>, Integer> ldapConfigurations = new Pair<List<LdapConfigurationVO>, 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<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
+ ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
+ Pair<List<LdapConfigurationVO>, Integer> result = new Pair<List<LdapConfigurationVO>, Integer>();
+ result.set(ldapConfigurationList, ldapConfigurationList.size())
+ ldapManager.listConfigurations(_) >> result
+
+ 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<LdapUser> 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<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
+ ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
+ Pair<List<LdapConfigurationVO>, Integer> ldapConfigurations = new Pair<List<LdapConfigurationVO>, 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<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
+ Pair<List<LdapConfigurationVO>, Integer> ldapConfigurations = new Pair<List<LdapConfigurationVO>, 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"
+ }
+}