mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 11:52:28 +01:00
Merge branch 'CLOUDSTACK-8596' of https://github.com/karuturi/cloudstack
This closes #609
This commit is contained in:
commit
7febdb58b5
@ -24,7 +24,7 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmaven</groupId>
|
||||
<artifactId>gmaven-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
<version>1.3</version>
|
||||
<configuration>
|
||||
<providerSelection>1.7</providerSelection>
|
||||
</configuration>
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
</bean>
|
||||
|
||||
<bean id="LdapManager" class="org.apache.cloudstack.ldap.LdapManagerImpl" />
|
||||
<bean id="LdapUserManager" class="org.apache.cloudstack.ldap.LdapUserManager" />
|
||||
<bean id="LdapUserManagerFactory" class="org.apache.cloudstack.ldap.LdapUserManagerFactory" />
|
||||
<bean id="LdapContextFactory" class="org.apache.cloudstack.ldap.LdapContextFactory" />
|
||||
<bean id="LdapConfigurationDao"
|
||||
class="org.apache.cloudstack.ldap.dao.LdapConfigurationDaoImpl" />
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.ldap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
public class ADLdapUserManagerImpl extends OpenLdapUserManagerImpl implements LdapUserManager {
|
||||
public static final Logger s_logger = Logger.getLogger(ADLdapUserManagerImpl.class.getName());
|
||||
private static final String MICROSOFT_AD_NESTED_MEMBERS_FILTER = "memberOf:1.2.840.113556.1.4.1941";
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context) throws NamingException {
|
||||
if (StringUtils.isBlank(groupName)) {
|
||||
throw new IllegalArgumentException("ldap group name cannot be blank");
|
||||
}
|
||||
|
||||
String basedn = _ldapConfiguration.getBaseDn();
|
||||
if (StringUtils.isBlank(basedn)) {
|
||||
throw new IllegalArgumentException("ldap basedn is not configured");
|
||||
}
|
||||
|
||||
final SearchControls searchControls = new SearchControls();
|
||||
searchControls.setSearchScope(_ldapConfiguration.getScope());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
|
||||
NamingEnumeration<SearchResult> results = context.search(basedn, generateADGroupSearchFilter(groupName), searchControls);
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
while (results.hasMoreElements()) {
|
||||
final SearchResult result = results.nextElement();
|
||||
users.add(createUser(result));
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
private String generateADGroupSearchFilter(String groupName) {
|
||||
final StringBuilder userObjectFilter = new StringBuilder();
|
||||
userObjectFilter.append("(objectClass=");
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject());
|
||||
userObjectFilter.append(")");
|
||||
|
||||
final StringBuilder memberOfFilter = new StringBuilder();
|
||||
String groupCnName = _ldapConfiguration.getCommonNameAttribute() + "=" +groupName + "," + _ldapConfiguration.getBaseDn();
|
||||
memberOfFilter.append("(" + MICROSOFT_AD_NESTED_MEMBERS_FILTER + ":=");
|
||||
memberOfFilter.append(groupCnName);
|
||||
memberOfFilter.append(")");
|
||||
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append("(&");
|
||||
result.append(userObjectFilter);
|
||||
result.append(memberOfFilter);
|
||||
result.append(")");
|
||||
|
||||
s_logger.debug("group search filter = " + result);
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@ -21,12 +21,12 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.directory.SearchControls;
|
||||
|
||||
import org.apache.cloudstack.api.command.LdapListConfigurationCmd;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import org.apache.cloudstack.ldap.dao.LdapConfigurationDao;
|
||||
|
||||
public class LdapConfiguration implements Configurable{
|
||||
private final static String factory = "com.sun.jndi.ldap.LdapCtxFactory";
|
||||
@ -36,6 +36,8 @@ public class LdapConfiguration implements Configurable{
|
||||
|
||||
private static final ConfigKey<Integer> ldapPageSize = new ConfigKey<Integer>(Integer.class, "ldap.request.page.size", "Advanced", "1000",
|
||||
"page size sent to ldap server on each request to get user", true, ConfigKey.Scope.Global, 1);
|
||||
private static final ConfigKey<String> ldapProvider = new ConfigKey<String>(String.class, "ldap.provider", "Advanced", "openldap", "ldap provider ex:openldap, microsoftad",
|
||||
true, ConfigKey.Scope.Global, null);
|
||||
|
||||
private final static int scope = SearchControls.SUBTREE_SCOPE;
|
||||
|
||||
@ -43,14 +45,14 @@ public class LdapConfiguration implements Configurable{
|
||||
private ConfigurationDao _configDao;
|
||||
|
||||
@Inject
|
||||
private LdapManager _ldapManager;
|
||||
private LdapConfigurationDao _ldapConfigurationDao;
|
||||
|
||||
public LdapConfiguration() {
|
||||
}
|
||||
|
||||
public LdapConfiguration(final ConfigurationDao configDao, final LdapManager ldapManager) {
|
||||
public LdapConfiguration(final ConfigurationDao configDao, final LdapConfigurationDao ldapConfigurationDao) {
|
||||
_configDao = configDao;
|
||||
_ldapManager = ldapManager;
|
||||
_ldapConfigurationDao = ldapConfigurationDao;
|
||||
}
|
||||
|
||||
public String getAuthentication() {
|
||||
@ -94,7 +96,7 @@ public class LdapConfiguration implements Configurable{
|
||||
|
||||
public String getProviderUrl() {
|
||||
final String protocol = getSSLStatus() == true ? "ldaps://" : "ldap://";
|
||||
final Pair<List<? extends LdapConfigurationVO>, Integer> result = _ldapManager.listConfigurations(new LdapListConfigurationCmd(_ldapManager));
|
||||
final Pair<List<LdapConfigurationVO>, Integer> result = _ldapConfigurationDao.searchConfigurations(null, 0);
|
||||
final StringBuilder providerUrls = new StringBuilder();
|
||||
String delim = "";
|
||||
for (final LdapConfigurationVO resource : result.first()) {
|
||||
@ -165,6 +167,17 @@ public class LdapConfiguration implements Configurable{
|
||||
return ldapPageSize.value();
|
||||
}
|
||||
|
||||
public LdapUserManager.Provider getLdapProvider() {
|
||||
LdapUserManager.Provider provider;
|
||||
try {
|
||||
provider = LdapUserManager.Provider.valueOf(ldapProvider.value().toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
//openldap is the default
|
||||
provider = LdapUserManager.Provider.OPENLDAP;
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return LdapConfiguration.class.getSimpleName();
|
||||
@ -172,6 +185,6 @@ public class LdapConfiguration implements Configurable{
|
||||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] {ldapReadTimeout, ldapPageSize};
|
||||
return new ConfigKey<?>[] {ldapReadTimeout, ldapPageSize, ldapProvider};
|
||||
}
|
||||
}
|
||||
@ -57,17 +57,22 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
||||
private LdapContextFactory _ldapContextFactory;
|
||||
|
||||
@Inject
|
||||
private LdapUserManager _ldapUserManager;
|
||||
private LdapConfiguration _ldapConfiguration;
|
||||
|
||||
@Inject LdapUserManagerFactory _ldapUserManagerFactory;
|
||||
|
||||
|
||||
public LdapManagerImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
public LdapManagerImpl(final LdapConfigurationDao ldapConfigurationDao, final LdapContextFactory ldapContextFactory, final LdapUserManager ldapUserManager) {
|
||||
public LdapManagerImpl(final LdapConfigurationDao ldapConfigurationDao, final LdapContextFactory ldapContextFactory, final LdapUserManagerFactory ldapUserManagerFactory,
|
||||
final LdapConfiguration ldapConfiguration) {
|
||||
super();
|
||||
_ldapConfigurationDao = ldapConfigurationDao;
|
||||
_ldapContextFactory = ldapContextFactory;
|
||||
_ldapUserManager = ldapUserManager;
|
||||
_ldapUserManagerFactory = ldapUserManagerFactory;
|
||||
_ldapConfiguration = ldapConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -173,7 +178,7 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
|
||||
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
|
||||
return _ldapUserManager.getUser(escapedUsername, context);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUser(escapedUsername, context);
|
||||
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap Exception: ",e);
|
||||
@ -188,7 +193,7 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
||||
LdapContext context = null;
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
return _ldapUserManager.getUsers(context);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsers(context);
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap Exception: ",e);
|
||||
throw new NoLdapUserMatchingQueryException("*");
|
||||
@ -202,7 +207,7 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
||||
LdapContext context = null;
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
return _ldapUserManager.getUsersInGroup(groupName, context);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsersInGroup(groupName, context);
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap NamingException: ",e);
|
||||
throw new NoLdapUserMatchingQueryException("groupName=" + groupName);
|
||||
@ -230,7 +235,7 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
|
||||
return _ldapUserManager.getUsers("*" + escapedUsername + "*", context);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsers("*" + escapedUsername + "*", context);
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap Exception: ",e);
|
||||
throw new NoLdapUserMatchingQueryException(username);
|
||||
|
||||
@ -1,227 +1,44 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.ldap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.ldap.Control;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
import javax.naming.ldap.PagedResultsControl;
|
||||
import javax.naming.ldap.PagedResultsResponseControl;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
public interface LdapUserManager {
|
||||
|
||||
public class LdapUserManager {
|
||||
private static final Logger s_logger = Logger.getLogger(LdapUserManager.class.getName());
|
||||
|
||||
@Inject
|
||||
private LdapConfiguration _ldapConfiguration;
|
||||
|
||||
public LdapUserManager() {
|
||||
public enum Provider {
|
||||
MICROSOFTAD, OPENLDAP;
|
||||
}
|
||||
|
||||
public LdapUserManager(final LdapConfiguration ldapConfiguration) {
|
||||
_ldapConfiguration = ldapConfiguration;
|
||||
}
|
||||
public LdapUser getUser(final String username, final LdapContext context) throws NamingException, IOException;
|
||||
|
||||
private LdapUser createUser(final SearchResult result) throws NamingException {
|
||||
final Attributes attributes = result.getAttributes();
|
||||
public List<LdapUser> getUsers(final LdapContext context) throws NamingException, IOException;
|
||||
|
||||
final String username = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getUsernameAttribute());
|
||||
final String email = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getEmailAttribute());
|
||||
final String firstname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getFirstnameAttribute());
|
||||
final String lastname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getLastnameAttribute());
|
||||
final String principal = result.getNameInNamespace();
|
||||
public List<LdapUser> getUsers(final String username, final LdapContext context) throws NamingException, IOException;
|
||||
|
||||
String domain = principal.replace("cn=" + LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getCommonNameAttribute()) + ",", "");
|
||||
domain = domain.replace("," + _ldapConfiguration.getBaseDn(), "");
|
||||
domain = domain.replace("ou=", "");
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context) throws NamingException;
|
||||
|
||||
return new LdapUser(username, email, firstname, lastname, principal, domain);
|
||||
}
|
||||
public List<LdapUser> searchUsers(final LdapContext context) throws NamingException, IOException;
|
||||
|
||||
private String generateSearchFilter(final String username) {
|
||||
final StringBuilder userObjectFilter = new StringBuilder();
|
||||
userObjectFilter.append("(objectClass=");
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject());
|
||||
userObjectFilter.append(")");
|
||||
|
||||
final StringBuilder usernameFilter = new StringBuilder();
|
||||
usernameFilter.append("(");
|
||||
usernameFilter.append(_ldapConfiguration.getUsernameAttribute());
|
||||
usernameFilter.append("=");
|
||||
usernameFilter.append((username == null ? "*" : username));
|
||||
usernameFilter.append(")");
|
||||
|
||||
final StringBuilder memberOfFilter = new StringBuilder();
|
||||
if (_ldapConfiguration.getSearchGroupPrinciple() != null) {
|
||||
memberOfFilter.append("(memberof=");
|
||||
memberOfFilter.append(_ldapConfiguration.getSearchGroupPrinciple());
|
||||
memberOfFilter.append(")");
|
||||
}
|
||||
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append("(&");
|
||||
result.append(userObjectFilter);
|
||||
result.append(usernameFilter);
|
||||
result.append(memberOfFilter);
|
||||
result.append(")");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String generateGroupSearchFilter(final String groupName) {
|
||||
final StringBuilder groupObjectFilter = new StringBuilder();
|
||||
groupObjectFilter.append("(objectClass=");
|
||||
groupObjectFilter.append(_ldapConfiguration.getGroupObject());
|
||||
groupObjectFilter.append(")");
|
||||
|
||||
final StringBuilder groupNameFilter = new StringBuilder();
|
||||
groupNameFilter.append("(");
|
||||
groupNameFilter.append(_ldapConfiguration.getCommonNameAttribute());
|
||||
groupNameFilter.append("=");
|
||||
groupNameFilter.append((groupName == null ? "*" : groupName));
|
||||
groupNameFilter.append(")");
|
||||
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append("(&");
|
||||
result.append(groupObjectFilter);
|
||||
result.append(groupNameFilter);
|
||||
result.append(")");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public LdapUser getUser(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
List<LdapUser> result = searchUsers(username, context);
|
||||
if (result!= null && result.size() == 1) {
|
||||
return result.get(0);
|
||||
} else {
|
||||
throw new NamingException("No user found for username " + username);
|
||||
}
|
||||
}
|
||||
|
||||
public List<LdapUser> getUsers(final LdapContext context) throws NamingException, IOException {
|
||||
return getUsers(null, context);
|
||||
}
|
||||
|
||||
public List<LdapUser> getUsers(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
List<LdapUser> users = searchUsers(username, context);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(users)) {
|
||||
Collections.sort(users);
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context) throws NamingException {
|
||||
String attributeName = _ldapConfiguration.getGroupUniqueMemeberAttribute();
|
||||
final SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(_ldapConfiguration.getScope());
|
||||
controls.setReturningAttributes(new String[] {attributeName});
|
||||
|
||||
NamingEnumeration<SearchResult> result = context.search(_ldapConfiguration.getBaseDn(), generateGroupSearchFilter(groupName), controls);
|
||||
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
//Expecting only one result which has all the users
|
||||
if (result.hasMoreElements()) {
|
||||
Attribute attribute = result.nextElement().getAttributes().get(attributeName);
|
||||
NamingEnumeration<?> values = attribute.getAll();
|
||||
|
||||
while (values.hasMoreElements()) {
|
||||
String userdn = String.valueOf(values.nextElement());
|
||||
try{
|
||||
users.add(getUserForDn(userdn, context));
|
||||
} catch (NamingException e){
|
||||
s_logger.info("Userdn: " + userdn + " Not Found:: Exception message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(users);
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private LdapUser getUserForDn(String userdn, LdapContext context) throws NamingException {
|
||||
final SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(_ldapConfiguration.getScope());
|
||||
controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
|
||||
NamingEnumeration<SearchResult> result = context.search(userdn, "(objectClass=" + _ldapConfiguration.getUserObject() + ")", controls);
|
||||
if (result.hasMoreElements()) {
|
||||
return createUser(result.nextElement());
|
||||
} else {
|
||||
throw new NamingException("No user found for dn " + userdn);
|
||||
}
|
||||
}
|
||||
|
||||
public List<LdapUser> searchUsers(final LdapContext context) throws NamingException, IOException {
|
||||
return searchUsers(null, context);
|
||||
}
|
||||
|
||||
public List<LdapUser> searchUsers(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
|
||||
final SearchControls searchControls = new SearchControls();
|
||||
|
||||
searchControls.setSearchScope(_ldapConfiguration.getScope());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
|
||||
String basedn = _ldapConfiguration.getBaseDn();
|
||||
if (StringUtils.isBlank(basedn)) {
|
||||
throw new IllegalArgumentException("ldap basedn is not configured");
|
||||
}
|
||||
byte[] cookie = null;
|
||||
int pageSize = _ldapConfiguration.getLdapPageSize();
|
||||
context.setRequestControls(new Control[]{new PagedResultsControl(pageSize, Control.NONCRITICAL)});
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
NamingEnumeration<SearchResult> results;
|
||||
do {
|
||||
results = context.search(basedn, generateSearchFilter(username), searchControls);
|
||||
while (results.hasMoreElements()) {
|
||||
final SearchResult result = results.nextElement();
|
||||
users.add(createUser(result));
|
||||
}
|
||||
Control[] contextControls = context.getResponseControls();
|
||||
if (contextControls != null) {
|
||||
for (Control control : contextControls) {
|
||||
if (control instanceof PagedResultsResponseControl) {
|
||||
PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
|
||||
cookie = prrc.getCookie();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_logger.info("No controls were sent from the ldap server");
|
||||
}
|
||||
context.setRequestControls(new Control[] {new PagedResultsControl(pageSize, cookie, Control.CRITICAL)});
|
||||
} while (cookie != null);
|
||||
|
||||
return users;
|
||||
}
|
||||
}
|
||||
public List<LdapUser> searchUsers(final String username, final LdapContext context) throws NamingException, IOException;
|
||||
}
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.ldap;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LdapUserManagerFactory implements ApplicationContextAware {
|
||||
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(LdapUserManagerFactory.class.getName());
|
||||
|
||||
private static Map<LdapUserManager.Provider, LdapUserManager> ldapUserManagerMap = new HashMap<>();
|
||||
|
||||
static ApplicationContext applicationCtx;
|
||||
|
||||
public LdapUserManager getInstance(LdapUserManager.Provider provider) {
|
||||
LdapUserManager ldapUserManager;
|
||||
if (provider == LdapUserManager.Provider.MICROSOFTAD) {
|
||||
ldapUserManager = ldapUserManagerMap.get(LdapUserManager.Provider.MICROSOFTAD);
|
||||
if (ldapUserManager == null) {
|
||||
ldapUserManager = new ADLdapUserManagerImpl();
|
||||
applicationCtx.getAutowireCapableBeanFactory().autowireBeanProperties(ldapUserManager, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
|
||||
ldapUserManagerMap.put(LdapUserManager.Provider.MICROSOFTAD, ldapUserManager);
|
||||
}
|
||||
} else {
|
||||
//defaults to opendldap
|
||||
ldapUserManager = ldapUserManagerMap.get(LdapUserManager.Provider.OPENLDAP);
|
||||
if (ldapUserManager == null) {
|
||||
ldapUserManager = new OpenLdapUserManagerImpl();
|
||||
applicationCtx.getAutowireCapableBeanFactory().autowireBeanProperties(ldapUserManager, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
|
||||
ldapUserManagerMap.put(LdapUserManager.Provider.OPENLDAP, ldapUserManager);
|
||||
}
|
||||
}
|
||||
return ldapUserManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
applicationCtx = applicationContext;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,233 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.ldap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.ldap.Control;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
import javax.naming.ldap.PagedResultsControl;
|
||||
import javax.naming.ldap.PagedResultsResponseControl;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
public class OpenLdapUserManagerImpl implements LdapUserManager {
|
||||
private static final Logger s_logger = Logger.getLogger(OpenLdapUserManagerImpl.class.getName());
|
||||
|
||||
@Inject
|
||||
protected LdapConfiguration _ldapConfiguration;
|
||||
|
||||
public OpenLdapUserManagerImpl() {
|
||||
}
|
||||
|
||||
public OpenLdapUserManagerImpl(final LdapConfiguration ldapConfiguration) {
|
||||
_ldapConfiguration = ldapConfiguration;
|
||||
}
|
||||
|
||||
protected LdapUser createUser(final SearchResult result) throws NamingException {
|
||||
final Attributes attributes = result.getAttributes();
|
||||
|
||||
final String username = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getUsernameAttribute());
|
||||
final String email = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getEmailAttribute());
|
||||
final String firstname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getFirstnameAttribute());
|
||||
final String lastname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getLastnameAttribute());
|
||||
final String principal = result.getNameInNamespace();
|
||||
|
||||
String domain = principal.replace("cn=" + LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getCommonNameAttribute()) + ",", "");
|
||||
domain = domain.replace("," + _ldapConfiguration.getBaseDn(), "");
|
||||
domain = domain.replace("ou=", "");
|
||||
|
||||
return new LdapUser(username, email, firstname, lastname, principal, domain);
|
||||
}
|
||||
|
||||
private String generateSearchFilter(final String username) {
|
||||
final StringBuilder userObjectFilter = new StringBuilder();
|
||||
userObjectFilter.append("(objectClass=");
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject());
|
||||
userObjectFilter.append(")");
|
||||
|
||||
final StringBuilder usernameFilter = new StringBuilder();
|
||||
usernameFilter.append("(");
|
||||
usernameFilter.append(_ldapConfiguration.getUsernameAttribute());
|
||||
usernameFilter.append("=");
|
||||
usernameFilter.append((username == null ? "*" : username));
|
||||
usernameFilter.append(")");
|
||||
|
||||
final StringBuilder memberOfFilter = new StringBuilder();
|
||||
if (_ldapConfiguration.getSearchGroupPrinciple() != null) {
|
||||
memberOfFilter.append("(memberof=");
|
||||
memberOfFilter.append(_ldapConfiguration.getSearchGroupPrinciple());
|
||||
memberOfFilter.append(")");
|
||||
}
|
||||
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append("(&");
|
||||
result.append(userObjectFilter);
|
||||
result.append(usernameFilter);
|
||||
result.append(memberOfFilter);
|
||||
result.append(")");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String generateGroupSearchFilter(final String groupName) {
|
||||
final StringBuilder groupObjectFilter = new StringBuilder();
|
||||
groupObjectFilter.append("(objectClass=");
|
||||
groupObjectFilter.append(_ldapConfiguration.getGroupObject());
|
||||
groupObjectFilter.append(")");
|
||||
|
||||
final StringBuilder groupNameFilter = new StringBuilder();
|
||||
groupNameFilter.append("(");
|
||||
groupNameFilter.append(_ldapConfiguration.getCommonNameAttribute());
|
||||
groupNameFilter.append("=");
|
||||
groupNameFilter.append((groupName == null ? "*" : groupName));
|
||||
groupNameFilter.append(")");
|
||||
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append("(&");
|
||||
result.append(groupObjectFilter);
|
||||
result.append(groupNameFilter);
|
||||
result.append(")");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LdapUser getUser(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
List<LdapUser> result = searchUsers(username, context);
|
||||
if (result!= null && result.size() == 1) {
|
||||
return result.get(0);
|
||||
} else {
|
||||
throw new NamingException("No user found for username " + username);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsers(final LdapContext context) throws NamingException, IOException {
|
||||
return getUsers(null, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsers(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
List<LdapUser> users = searchUsers(username, context);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(users)) {
|
||||
Collections.sort(users);
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context) throws NamingException {
|
||||
String attributeName = _ldapConfiguration.getGroupUniqueMemeberAttribute();
|
||||
final SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(_ldapConfiguration.getScope());
|
||||
controls.setReturningAttributes(new String[] {attributeName});
|
||||
|
||||
NamingEnumeration<SearchResult> result = context.search(_ldapConfiguration.getBaseDn(), generateGroupSearchFilter(groupName), controls);
|
||||
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
//Expecting only one result which has all the users
|
||||
if (result.hasMoreElements()) {
|
||||
Attribute attribute = result.nextElement().getAttributes().get(attributeName);
|
||||
NamingEnumeration<?> values = attribute.getAll();
|
||||
|
||||
while (values.hasMoreElements()) {
|
||||
String userdn = String.valueOf(values.nextElement());
|
||||
try{
|
||||
users.add(getUserForDn(userdn, context));
|
||||
} catch (NamingException e){
|
||||
s_logger.info("Userdn: " + userdn + " Not Found:: Exception message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(users);
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private LdapUser getUserForDn(String userdn, LdapContext context) throws NamingException {
|
||||
final SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(_ldapConfiguration.getScope());
|
||||
controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
|
||||
NamingEnumeration<SearchResult> result = context.search(userdn, "(objectClass=" + _ldapConfiguration.getUserObject() + ")", controls);
|
||||
if (result.hasMoreElements()) {
|
||||
return createUser(result.nextElement());
|
||||
} else {
|
||||
throw new NamingException("No user found for dn " + userdn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> searchUsers(final LdapContext context) throws NamingException, IOException {
|
||||
return searchUsers(null, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> searchUsers(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
|
||||
final SearchControls searchControls = new SearchControls();
|
||||
|
||||
searchControls.setSearchScope(_ldapConfiguration.getScope());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
|
||||
String basedn = _ldapConfiguration.getBaseDn();
|
||||
if (StringUtils.isBlank(basedn)) {
|
||||
throw new IllegalArgumentException("ldap basedn is not configured");
|
||||
}
|
||||
byte[] cookie = null;
|
||||
int pageSize = _ldapConfiguration.getLdapPageSize();
|
||||
context.setRequestControls(new Control[]{new PagedResultsControl(pageSize, Control.NONCRITICAL)});
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
NamingEnumeration<SearchResult> results;
|
||||
do {
|
||||
results = context.search(basedn, generateSearchFilter(username), searchControls);
|
||||
while (results.hasMoreElements()) {
|
||||
final SearchResult result = results.nextElement();
|
||||
users.add(createUser(result));
|
||||
}
|
||||
Control[] contextControls = context.getResponseControls();
|
||||
if (contextControls != null) {
|
||||
for (Control control : contextControls) {
|
||||
if (control instanceof PagedResultsResponseControl) {
|
||||
PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
|
||||
cookie = prrc.getCookie();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_logger.info("No controls were sent from the ldap server");
|
||||
}
|
||||
context.setRequestControls(new Control[] {new PagedResultsControl(pageSize, cookie, Control.CRITICAL)});
|
||||
} while (cookie != null);
|
||||
|
||||
return users;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package groovy.org.apache.cloudstack.ldap
|
||||
|
||||
import org.apache.cloudstack.ldap.ADLdapUserManagerImpl
|
||||
import org.apache.cloudstack.ldap.LdapConfiguration
|
||||
import spock.lang.Shared
|
||||
|
||||
import javax.naming.directory.SearchControls
|
||||
import javax.naming.ldap.LdapContext
|
||||
|
||||
class ADLdapUserManagerImplSpec extends spock.lang.Specification {
|
||||
|
||||
@Shared
|
||||
ADLdapUserManagerImpl adLdapUserManager;
|
||||
|
||||
@Shared
|
||||
LdapConfiguration ldapConfiguration;
|
||||
|
||||
def setup() {
|
||||
adLdapUserManager = new ADLdapUserManagerImpl();
|
||||
ldapConfiguration = Mock(LdapConfiguration);
|
||||
adLdapUserManager._ldapConfiguration = ldapConfiguration;
|
||||
}
|
||||
|
||||
def "test generate AD search filter"() {
|
||||
ldapConfiguration.getUserObject() >> "user"
|
||||
ldapConfiguration.getCommonNameAttribute() >> "CN"
|
||||
ldapConfiguration.getBaseDn() >> "DC=cloud,DC=citrix,DC=com"
|
||||
|
||||
def result = adLdapUserManager.generateADGroupSearchFilter(group);
|
||||
expect:
|
||||
assert result.contains("memberOf:1.2.840.113556.1.4.1941:=")
|
||||
result == "(&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=" + group + ",DC=cloud,DC=citrix,DC=com))"
|
||||
where:
|
||||
group << ["dev", "dev-hyd"]
|
||||
}
|
||||
|
||||
def "test getUsersInGroup null group"() {
|
||||
ldapConfiguration.getScope() >> SearchControls.SUBTREE_SCOPE
|
||||
ldapConfiguration.getReturnAttributes() >> ["username", "firstname", "lastname", "email"]
|
||||
ldapConfiguration.getBaseDn() >>> [null, null, "DC=cloud,DC=citrix,DC=com"]
|
||||
|
||||
LdapContext context = Mock(LdapContext);
|
||||
|
||||
when:
|
||||
def result = adLdapUserManager.getUsersInGroup(group, context)
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
where:
|
||||
group << [null, "group", null]
|
||||
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,8 @@ import org.apache.cloudstack.framework.config.impl.ConfigurationVO
|
||||
import org.apache.cloudstack.ldap.LdapConfiguration
|
||||
import org.apache.cloudstack.ldap.LdapConfigurationVO
|
||||
import org.apache.cloudstack.ldap.LdapManager
|
||||
import org.apache.cloudstack.ldap.LdapUserManager
|
||||
import org.apache.cloudstack.ldap.dao.LdapConfigurationDao
|
||||
import org.apache.cxf.common.util.StringUtils
|
||||
|
||||
import javax.naming.directory.SearchControls
|
||||
@ -33,8 +35,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def "Test that getAuthentication returns none"() {
|
||||
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get authentication is called"
|
||||
String authentication = ldapConfiguration.getAuthentication()
|
||||
then: "none should be returned"
|
||||
@ -44,8 +46,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def "Test that getAuthentication returns simple"() {
|
||||
given: "We have a configDao, LdapManager and LdapConfiguration with bind principle and password set"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
configDao.getValue("ldap.bind.password") >> "password"
|
||||
configDao.getValue("ldap.bind.principal") >> "cn=rmurphy,dc=cloudstack,dc=org"
|
||||
when: "Get authentication is called"
|
||||
@ -58,8 +60,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
given: "We have a ConfigDao, LdapManager and ldapConfiguration with a baseDn value set."
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.basedn") >> "dc=cloudstack,dc=org"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get basedn is called"
|
||||
String baseDn = ldapConfiguration.getBaseDn();
|
||||
then: "The set baseDn should be returned"
|
||||
@ -70,8 +72,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
given: "Given that we have a ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.email.attribute") >> "mail"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get Email Attribute is called"
|
||||
String emailAttribute = ldapConfiguration.getEmailAttribute()
|
||||
then: "mail should be returned"
|
||||
@ -81,8 +83,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def "Test that getFactory returns com.sun.jndi.ldap.LdapCtxFactory"() {
|
||||
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get Factory is scalled"
|
||||
String factory = ldapConfiguration.getFactory();
|
||||
then: "com.sun.jndi.ldap.LdapCtxFactory is returned"
|
||||
@ -93,8 +95,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.firstname.attribute") >> "givenname"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get firstname attribute is called"
|
||||
String firstname = ldapConfiguration.getFirstnameAttribute()
|
||||
then: "givennam should be returned"
|
||||
@ -105,8 +107,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.lastname.attribute") >> "sn"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get Lastname Attribute is scalled "
|
||||
String lastname = ldapConfiguration.getLastnameAttribute()
|
||||
then: "sn should be returned"
|
||||
@ -120,8 +122,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
configDao.getValue("ldap.lastname.attribute") >> "sn"
|
||||
configDao.getValue("ldap.username.attribute") >> "uid"
|
||||
configDao.getValue("ldap.email.attribute") >> "mail"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get return attributes is called"
|
||||
String[] returnAttributes = ldapConfiguration.getReturnAttributes()
|
||||
then: "An array containing uid, mail, givenname, sn and cn is returned"
|
||||
@ -131,8 +133,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def "Test that getScope returns SearchControls.SUBTREE_SCOPE"() {
|
||||
given: "We have ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get scope is called"
|
||||
int scope = ldapConfiguration.getScope()
|
||||
then: "SearchControls.SUBTRE_SCOPE should be returned"
|
||||
@ -143,8 +145,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
given: "We have ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.username.attribute") >> "uid"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get Username Attribute is called"
|
||||
String usernameAttribute = ldapConfiguration.getUsernameAttribute()
|
||||
then: "uid should be returned"
|
||||
@ -155,8 +157,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.user.object") >> "inetOrgPerson"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get user object is called"
|
||||
String userObject = ldapConfiguration.getUserObject()
|
||||
then: "inetOrgPerson is returned"
|
||||
@ -166,14 +168,14 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def "Test that providerUrl successfully returns a URL when a configuration is available"() {
|
||||
given: "We have a ConfigDao, LdapManager, LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
List<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
|
||||
ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
|
||||
Pair<List<LdapConfigurationVO>, Integer> result = new Pair<List<LdapConfigurationVO>, Integer>();
|
||||
result.set(ldapConfigurationList, ldapConfigurationList.size())
|
||||
ldapManager.listConfigurations(_) >> result
|
||||
ldapConfigurationDao.searchConfigurations(_,_) >> result
|
||||
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
when: "A request is made to get the providerUrl"
|
||||
String providerUrl = ldapConfiguration.getProviderUrl()
|
||||
@ -186,8 +188,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
given: "We have a ConfigDao with a value for ldap.search.group.principle and an LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.search.group.principle") >> "cn=cloudstack,cn=users,dc=cloudstack,dc=org"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
when: "A request is made to get the search group principle"
|
||||
String result = ldapConfiguration.getSearchGroupPrinciple();
|
||||
@ -200,8 +202,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
given: "We have a ConfigDao with a value for truststore password"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.truststore.password") >> "password"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
when: "A request is made to get the truststore password"
|
||||
String result = ldapConfiguration.getTrustStorePassword()
|
||||
@ -215,8 +217,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.truststore") >> "/tmp/ldap.ts"
|
||||
configDao.getValue("ldap.truststore.password") >> "password"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManager)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
when: "A request is made to get the status of SSL"
|
||||
boolean result = ldapConfiguration.getSSLStatus();
|
||||
@ -230,8 +232,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.group.object") >> groupObject
|
||||
|
||||
def ldapManger = Mock(LdapManager)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
def expectedResult = groupObject == null ? "groupOfUniqueNames" : groupObject
|
||||
|
||||
def result = ldapConfiguration.getGroupObject()
|
||||
@ -246,8 +248,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.group.user.uniquemember") >> groupObject
|
||||
|
||||
def ldapManger = Mock(LdapManager)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
def expectedResult = groupObject == null ? "uniquemember" : groupObject
|
||||
|
||||
def result = ldapConfiguration.getGroupUniqueMemeberAttribute()
|
||||
@ -268,8 +270,8 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
configDepotImpl.global() >> configDao
|
||||
ConfigKey.init(configDepotImpl)
|
||||
|
||||
def ldapManger = Mock(LdapManager)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
def expected = timeout == null ? 1000 : timeout.toLong() //1000 is the default value
|
||||
|
||||
@ -280,4 +282,28 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
timeout << ["1000000", "1000", null]
|
||||
}
|
||||
|
||||
def "Test getLdapProvider()"() {
|
||||
given: "We have configdao for ldap group object"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
ConfigurationVO configurationVo = new ConfigurationVO("ldap.read.timeout", LdapConfiguration.ldapProvider);
|
||||
configurationVo.setValue(provider)
|
||||
configDao.findById("ldap.provider") >> configurationVo
|
||||
|
||||
def configDepotImpl = Mock(ConfigDepotImpl)
|
||||
configDepotImpl.global() >> configDao
|
||||
ConfigKey.init(configDepotImpl)
|
||||
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
def expected = provider.equalsIgnoreCase("microsoftad") ? LdapUserManager.Provider.MICROSOFTAD : LdapUserManager.Provider.OPENLDAP //"openldap" is the default value
|
||||
|
||||
def result = ldapConfiguration.getLdapProvider()
|
||||
expect:
|
||||
println "asserting for provider configuration: " + provider
|
||||
result == expected
|
||||
where:
|
||||
provider << ["openldap", "microsoftad", "", " ", "xyz", "MicrosoftAd", "OpenLdap", "MicrosoftAD"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
||||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = Spy(LdapCreateAccountCmd, constructorArgs: [ldapManager, accountService])
|
||||
ldapCreateAccountCmd.getCurrentContext() >> Mock(CallContext)
|
||||
ldapCreateAccountCmd.createCloudstackUserAccount(_) >> null
|
||||
ldapCreateAccountCmd.createCloudstackUserAccount(_, _, _) >> null
|
||||
when: "Cloudstack fail to create the user"
|
||||
ldapCreateAccountCmd.execute()
|
||||
then: "An exception is thrown"
|
||||
|
||||
@ -41,8 +41,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> { throw new NoLdapUserMatchingQueryException() }
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a user but there is a bind issue"
|
||||
ldapManager.getUser("rmurphy")
|
||||
then: "an exception is thrown"
|
||||
@ -54,8 +57,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> { throw new NamingException() }
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a group of users but there is a bind issue"
|
||||
ldapManager.getUsers()
|
||||
then: "An exception is thrown"
|
||||
@ -67,8 +73,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> { throw new NamingException() }
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for users"
|
||||
ldapManager.searchUsers("rmurphy")
|
||||
then: "An exception is thrown"
|
||||
@ -80,7 +89,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A ldap configuration response is generated"
|
||||
def result = ldapManager.createLdapConfigurationResponse(new LdapConfigurationVO("localhost", 389))
|
||||
then: "the result of the response should match the given LdapConfigurationVO"
|
||||
@ -93,7 +105,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A ldap user response is generated"
|
||||
def result = ldapManager.createLdapUserResponse(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org",
|
||||
"engineering"))
|
||||
@ -111,11 +126,14 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> null
|
||||
List<LdapUser> users = new ArrayList<>();
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null))
|
||||
ldapUserManager.getUsers(_) >> users;
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a group of users"
|
||||
def result = ldapManager.getUsers()
|
||||
then: "A list greater than 0 is returned"
|
||||
@ -127,9 +145,12 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> null
|
||||
ldapUserManager.getUser(_, _) >> new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a user"
|
||||
def result = ldapManager.getUser("rmurphy")
|
||||
then: "The user is returned"
|
||||
@ -145,7 +166,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "The context is closed"
|
||||
def context = Mock(InitialLdapContext)
|
||||
ldapManager.closeContext(context)
|
||||
@ -159,7 +183,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
ldapContextFactory.createUserContext(_, _) >> { throw new NamingException() }
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration])
|
||||
ldapManager.getUser(_) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null) }
|
||||
when: "The user attempts to authenticate with a bad password"
|
||||
def result = ldapManager.canAuthenticate("rmurphy", "password")
|
||||
@ -172,7 +199,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration])
|
||||
ldapManager.getUser(_) >> { throw new NamingException() }
|
||||
when: "The user attempts to authenticate and the user is not found"
|
||||
def result = ldapManager.canAuthenticate("rmurphy", "password")
|
||||
@ -185,8 +215,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapConfigurationDao.findByHostname(_) >> null
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A ldap configuration that doesn't exist is deleted"
|
||||
ldapManager.deleteConfiguration("localhost")
|
||||
then: "A exception is thrown"
|
||||
@ -198,7 +231,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "The context is closed"
|
||||
def context = Mock(InitialLdapContext)
|
||||
context.close() >> { throw new NamingException() }
|
||||
@ -213,7 +249,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
ldapContextFactory.createUserContext(_, _) >> null
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManager])
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration])
|
||||
ldapManager.getUser(_) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null) }
|
||||
when: "A user authenticates"
|
||||
def result = ldapManager.canAuthenticate("rmurphy", "password")
|
||||
@ -226,13 +265,16 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapConfigurationDao.findByHostname(_) >> {
|
||||
def configuration = new LdapConfigurationVO("localhost", 389)
|
||||
configuration.setId(0);
|
||||
return configuration;
|
||||
}
|
||||
ldapConfigurationDao.remove(_) >> null
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A ldap configuration is deleted"
|
||||
def result = ldapManager.deleteConfiguration("localhost")
|
||||
then: "The deleted configuration is returned"
|
||||
@ -245,13 +287,16 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapContextFactory.createBindContext() >> null;
|
||||
|
||||
List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering"))
|
||||
ldapUserManager.getUsers(_, _) >> users;
|
||||
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for users"
|
||||
def result = ldapManager.searchUsers("rmurphy");
|
||||
then: "A list of atleast 1 is returned"
|
||||
@ -263,9 +308,12 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext(_) >> null
|
||||
ldapConfigurationDao.persist(_) >> null
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A ldap configuration is added"
|
||||
def result = ldapManager.addConfiguration("localhost", 389)
|
||||
then: "the resulting object contain the given hostname and port"
|
||||
@ -278,8 +326,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext(_) >> { throw new NamingException() }
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A configuration is added that can not be binded"
|
||||
ldapManager.addConfiguration("localhost", 389)
|
||||
then: "An exception is thrown"
|
||||
@ -291,8 +342,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapConfigurationDao.findByHostname(_) >> new LdapConfigurationVO("localhost", 389)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "a configuration that already exists is added"
|
||||
ldapManager.addConfiguration("localhost", 389)
|
||||
then: "An exception is thrown"
|
||||
@ -318,8 +372,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
final List<Class<?>> cmdList = supportedLdapCommands()
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "Get commands is called"
|
||||
def result = ldapManager.getCommands()
|
||||
then: "it must return all the commands"
|
||||
@ -332,12 +389,15 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
List<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
|
||||
ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
|
||||
Pair<List<LdapConfigurationVO>, Integer> configurations = new Pair<List<LdapConfigurationVO>, Integer>();
|
||||
configurations.set(ldapConfigurationList, ldapConfigurationList.size())
|
||||
ldapConfigurationDao.searchConfigurations(_, _) >> configurations
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A request for configurations is made"
|
||||
def result = ldapManager.listConfigurations(new LdapListConfigurationCmd())
|
||||
then: "Then atleast 1 ldap configuration is returned"
|
||||
@ -349,12 +409,15 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
List<LdapConfigurationVO> ldapConfigurationList = new ArrayList()
|
||||
ldapConfigurationList.add(new LdapConfigurationVO("localhost", 389))
|
||||
Pair<List<LdapConfigurationVO>, Integer> configurations = new Pair<List<LdapConfigurationVO>, Integer>();
|
||||
configurations.set(ldapConfigurationList, ldapConfigurationList.size())
|
||||
ldapConfigurationDao.searchConfigurations(_, _) >> configurations
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A request to find out is ldap enabled"
|
||||
def result = ldapManager.isLdapEnabled();
|
||||
then: "true is returned because a configuration was found"
|
||||
@ -366,11 +429,14 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(LdapUserManager)
|
||||
def ldapUserManagerFactory = Mock(LdapUserManagerFactory)
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> null
|
||||
List<LdapUser> users = new ArrayList<>();
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", "engineering"))
|
||||
ldapUserManager.getUsersInGroup("engineering", _) >> users;
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManager)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a group of users"
|
||||
def result = ldapManager.getUsersInGroup("engineering")
|
||||
then: "A list greater of size one is returned"
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package groovy.org.apache.cloudstack.ldap
|
||||
|
||||
import org.apache.cloudstack.ldap.ADLdapUserManagerImpl
|
||||
import org.apache.cloudstack.ldap.LdapUserManager
|
||||
import org.apache.cloudstack.ldap.LdapUserManagerFactory
|
||||
import org.apache.cloudstack.ldap.OpenLdapUserManagerImpl
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory
|
||||
import org.springframework.context.ApplicationContext
|
||||
import spock.lang.Shared
|
||||
|
||||
class LdapUserManagerFactorySpec extends spock.lang.Specification {
|
||||
|
||||
@Shared
|
||||
def LdapUserManagerFactory ldapUserManagerFactory;
|
||||
|
||||
def setupSpec() {
|
||||
ldapUserManagerFactory = new LdapUserManagerFactory();
|
||||
ApplicationContext applicationContext = Mock(ApplicationContext);
|
||||
AutowireCapableBeanFactory autowireCapableBeanFactory = Mock(AutowireCapableBeanFactory);
|
||||
applicationContext.getAutowireCapableBeanFactory() >> autowireCapableBeanFactory;
|
||||
ldapUserManagerFactory.setApplicationContext(applicationContext);
|
||||
}
|
||||
|
||||
def "Test getInstance() from factory"() {
|
||||
def result = ldapUserManagerFactory.getInstance(id);
|
||||
|
||||
def expected;
|
||||
if(id == LdapUserManager.Provider.MICROSOFTAD) {
|
||||
expected = ADLdapUserManagerImpl.class;
|
||||
} else {
|
||||
expected = OpenLdapUserManagerImpl.class;
|
||||
}
|
||||
|
||||
expect:
|
||||
assert result.class.is(expected)
|
||||
where:
|
||||
id << [LdapUserManager.Provider.MICROSOFTAD, LdapUserManager.Provider.OPENLDAP, null]
|
||||
}
|
||||
}
|
||||
@ -18,6 +18,7 @@ package groovy.org.apache.cloudstack.ldap
|
||||
|
||||
import org.apache.cloudstack.ldap.LdapConfiguration
|
||||
import org.apache.cloudstack.ldap.LdapUserManager
|
||||
import org.apache.cloudstack.ldap.OpenLdapUserManagerImpl
|
||||
import spock.lang.Shared
|
||||
|
||||
import javax.naming.NamingException
|
||||
@ -29,7 +30,7 @@ import javax.naming.directory.SearchResult
|
||||
import javax.naming.ldap.InitialLdapContext
|
||||
import javax.naming.ldap.LdapContext
|
||||
|
||||
class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
class OpenLdapUserManagerSpec extends spock.lang.Specification {
|
||||
|
||||
@Shared
|
||||
private def ldapConfiguration
|
||||
@ -184,7 +185,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
given: "We have attributes, a search and a user manager"
|
||||
def attributes = createUserAttributes(username, email, firstname, lastname)
|
||||
def search = createSearchResult(attributes)
|
||||
def userManager = new LdapUserManager(ldapConfiguration)
|
||||
def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
def result = userManager.createUser(search)
|
||||
|
||||
expect: "The crated user the data supplied from LDAP"
|
||||
@ -199,7 +200,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
def "Test successfully returning a list from get users"() {
|
||||
given: "We have a LdapUserManager"
|
||||
|
||||
def userManager = new LdapUserManager(ldapConfiguration)
|
||||
def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "A request for users is made"
|
||||
def result = userManager.getUsers(username, createContext())
|
||||
@ -211,7 +212,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
def "Test successfully returning a list from get users when no username is given"() {
|
||||
given: "We have a LdapUserManager"
|
||||
|
||||
def userManager = new LdapUserManager(ldapConfiguration)
|
||||
def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "Get users is called without a username"
|
||||
def result = userManager.getUsers(createContext())
|
||||
@ -222,7 +223,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
|
||||
def "Test successfully returning a ldap user from searchUsers"() {
|
||||
given: "We have a LdapUserManager"
|
||||
def userManager = new LdapUserManager(ldapConfiguration)
|
||||
def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "We search for users"
|
||||
def result = userManager.searchUsers(createContext())
|
||||
@ -234,7 +235,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
def "Test successfully returning an Ldap user from a get user request"() {
|
||||
given: "We have a LdapUserMaanger"
|
||||
|
||||
def userManager = new LdapUserManager(ldapConfiguration)
|
||||
def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "A request for a user is made"
|
||||
def result = userManager.getUser(username, createContext())
|
||||
@ -255,7 +256,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
def context = Mock(LdapContext)
|
||||
context.search(_, _, _) >> searchUsersResults;
|
||||
|
||||
def userManager = new LdapUserManager(ldapConfiguration)
|
||||
def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "a get user request is made and no user is found"
|
||||
def result = userManager.getUser(username, context)
|
||||
@ -266,14 +267,14 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
|
||||
def "Test that a newly created Ldap User Manager is not null"() {
|
||||
given: "You have created a new Ldap user manager object"
|
||||
def result = new LdapUserManager();
|
||||
def result = new OpenLdapUserManagerImpl();
|
||||
expect: "The result is not null"
|
||||
result != null
|
||||
}
|
||||
|
||||
def "test successful generateGroupSearchFilter"() {
|
||||
given: "ldap user manager and ldap config"
|
||||
def ldapUserManager = new LdapUserManager(ldapConfiguration)
|
||||
def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
def groupName = varGroupName == null ? "*" : varGroupName
|
||||
def expectedResult = "(&(objectClass=groupOfUniqueNames)(cn=" + groupName + "))";
|
||||
|
||||
@ -286,7 +287,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
|
||||
def "test successful getUsersInGroup one user"() {
|
||||
given: "ldap user manager and ldap config"
|
||||
def ldapUserManager = new LdapUserManager(ldapConfiguration)
|
||||
def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "A request for users is made"
|
||||
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextOneUser())
|
||||
@ -296,7 +297,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
|
||||
def "test successful getUsersInGroup no user"() {
|
||||
given: "ldap user manager and ldap config"
|
||||
def ldapUserManager = new LdapUserManager(ldapConfiguration)
|
||||
def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "A request for users is made"
|
||||
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextNoUser())
|
||||
@ -306,7 +307,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
|
||||
def "test successful getUserForDn"() {
|
||||
given: "ldap user manager and ldap config"
|
||||
def ldapUserManager = new LdapUserManager(ldapConfiguration)
|
||||
def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "A request for users is made"
|
||||
def result = ldapUserManager.getUserForDn("cn=Ryan Murphy,ou=engineering,dc=cloudstack,dc=org", createContext())
|
||||
@ -324,7 +325,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
given: "ldap configuration where basedn is not set"
|
||||
def ldapconfig = Mock(LdapConfiguration)
|
||||
ldapconfig.getBaseDn() >> null
|
||||
def ldapUserManager = new LdapUserManager(ldapconfig)
|
||||
def ldapUserManager = new OpenLdapUserManagerImpl(ldapconfig)
|
||||
|
||||
when: "A request for search users is made"
|
||||
def result = ldapUserManager.searchUsers(new InitialLdapContext())
|
||||
Loading…
x
Reference in New Issue
Block a user