Repository: cloudstack Updated Branches: refs/heads/master a7e3861f5 -> cd2f27a66
Fixed bug: CLOUDSTACK-7214 added a config for ldap connection read timeout. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/cd2f27a6 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/cd2f27a6 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/cd2f27a6 Branch: refs/heads/master Commit: cd2f27a6628472b1c0a6289989dc802f534ec74e Parents: a7e3861 Author: Rajani Karuturi <rajanikarut...@gmail.com> Authored: Thu Jul 31 17:16:20 2014 +0530 Committer: Rajani Karuturi <rajanikarut...@gmail.com> Committed: Thu Jul 31 17:33:18 2014 +0530 ---------------------------------------------------------------------- .../cloudstack/ldap/LdapConfiguration.java | 21 +- .../cloudstack/ldap/LdapContextFactory.java | 2 +- .../ldap/LdapConfigurationSpec.groovy | 329 ++++++++++--------- 3 files changed, 199 insertions(+), 153 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cd2f27a6/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java index 7b7eb8e..5ddaa63 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java @@ -22,13 +22,18 @@ 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; -public class LdapConfiguration { +public class LdapConfiguration implements Configurable{ private final static String factory = "com.sun.jndi.ldap.LdapCtxFactory"; + private static final ConfigKey<Long> ldapReadTimeout = new ConfigKey<Long>(Long.class, "ldap.read.timeout", "Secure", "1000", + "LDAP connection Timeout in milli sec", true, ConfigKey.Scope.Global, 1l); + private final static int scope = SearchControls.SUBTREE_SCOPE; @Inject @@ -148,4 +153,18 @@ public class LdapConfiguration { public String getCommonNameAttribute() { return "cn"; } + + public Long getReadTimeout() { + return ldapReadTimeout.value(); + } + + @Override + public String getConfigComponentName() { + return LdapConfiguration.class.getSimpleName(); + } + + @Override + public ConfigKey<?>[] getConfigKeys() { + return new ConfigKey<?>[] {ldapReadTimeout}; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cd2f27a6/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 index 5811c32..dc53578 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java @@ -82,7 +82,7 @@ public class LdapContextFactory { 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.read.timeout", _ldapConfiguration.getReadTimeout().toString()); environment.put("com.sun.jndi.ldap.connect.pool", "true"); enableSSL(environment); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cd2f27a6/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 index 1017a0f..adc3463 100644 --- 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 @@ -16,241 +16,268 @@ // under the License. package groovy.org.apache.cloudstack.ldap +import org.apache.cloudstack.framework.config.ConfigKey import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import com.cloud.utils.Pair import org.apache.cloudstack.api.ServerApiException +import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl +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.cxf.common.util.StringUtils import javax.naming.directory.SearchControls 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) - when: "Get authentication is called" - String authentication = ldapConfiguration.getAuthentication() - then: "none should be returned" - authentication == "none" + given: "We have a ConfigDao, LdapManager and LdapConfiguration" + def configDao = Mock(ConfigurationDao) + def ldapManager = Mock(LdapManager) + def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) + when: "Get authentication is called" + String authentication = ldapConfiguration.getAuthentication() + then: "none should be returned" + authentication == "none" } def "Test that getAuthentication returns simple"() { - given: "We have a configDao, LdapManager and LdapConfiguration with bind principle and password set" + 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) configDao.getValue("ldap.bind.password") >> "password" configDao.getValue("ldap.bind.principal") >> "cn=rmurphy,dc=cloudstack,dc=org" - when: "Get authentication is called" + when: "Get authentication is called" String authentication = ldapConfiguration.getAuthentication() - then: "authentication should be set to simple" - authentication == "simple" + then: "authentication should be set to simple" + authentication == "simple" } def "Test that getBaseDn returns dc=cloudstack,dc=org"() { - 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) - when: "Get basedn is called" - String baseDn = ldapConfiguration.getBaseDn(); - then: "The set baseDn should be returned" - baseDn == "dc=cloudstack,dc=org" + 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) + when: "Get basedn is called" + String baseDn = ldapConfiguration.getBaseDn(); + then: "The set baseDn should be returned" + baseDn == "dc=cloudstack,dc=org" } def "Test that getEmailAttribute returns mail"() { - given: "Given that we have a ConfigDao, LdapManager and LdapConfiguration" + 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) - when: "Get Email Attribute is called" + when: "Get Email Attribute is called" String emailAttribute = ldapConfiguration.getEmailAttribute() - then: "mail should be returned" - emailAttribute == "mail" + then: "mail should be returned" + emailAttribute == "mail" } 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) - when: "Get Factory is scalled" - String factory = ldapConfiguration.getFactory(); - then: "com.sun.jndi.ldap.LdapCtxFactory is returned" - factory == "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) + when: "Get Factory is scalled" + String factory = ldapConfiguration.getFactory(); + then: "com.sun.jndi.ldap.LdapCtxFactory is returned" + factory == "com.sun.jndi.ldap.LdapCtxFactory" } def "Test that getFirstnameAttribute returns givenname"() { - given: "We have a ConfigDao, LdapManager and LdapConfiguration" + 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) - when: "Get firstname attribute is called" + when: "Get firstname attribute is called" String firstname = ldapConfiguration.getFirstnameAttribute() - then: "givennam should be returned" + then: "givennam should be returned" firstname == "givenname" } def "Test that getLastnameAttribute returns givenname"() { - given: "We have a ConfigDao, LdapManager and LdapConfiguration" + 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) - when: "Get Lastname Attribute is scalled " + when: "Get Lastname Attribute is scalled " String lastname = ldapConfiguration.getLastnameAttribute() - then: "sn should be returned" - lastname == "sn" + then: "sn should be returned" + lastname == "sn" } def "Test that getReturnAttributes returns the correct data"() { - given: "We have a ConfigDao, LdapManager and LdapConfiguration" - def configDao = Mock(ConfigurationDao) + given: "We have a ConfigDao, LdapManager and LdapConfiguration" + 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: "Get return attributes is called" + when: "Get return attributes is called" String[] returnAttributes = ldapConfiguration.getReturnAttributes() - then: "An array containing uid, mail, givenname, sn and cn is returned" - returnAttributes == ["uid", "mail", "givenname", "sn", "cn"] + then: "An array containing uid, mail, givenname, sn and cn is returned" + returnAttributes == ["uid", "mail", "givenname", "sn", "cn"] } def "Test that getScope returns SearchControls.SUBTREE_SCOPE"() { - given: "We have ConfigDao, LdapManager and LdapConfiguration" + given: "We have ConfigDao, LdapManager and LdapConfiguration" def configDao = Mock(ConfigurationDao) def ldapManager = Mock(LdapManager) def ldapConfiguration = new LdapConfiguration(configDao, ldapManager) - when: "Get scope is called" + when: "Get scope is called" int scope = ldapConfiguration.getScope() - then: "SearchControls.SUBTRE_SCOPE should be returned" - scope == SearchControls.SUBTREE_SCOPE; + then: "SearchControls.SUBTRE_SCOPE should be returned" + scope == SearchControls.SUBTREE_SCOPE; } def "Test that getUsernameAttribute returns uid"() { - 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) - when: "Get Username Attribute is called" - String usernameAttribute = ldapConfiguration.getUsernameAttribute() - then: "uid should be returned" - usernameAttribute == "uid" + 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) + when: "Get Username Attribute is called" + String usernameAttribute = ldapConfiguration.getUsernameAttribute() + then: "uid should be returned" + usernameAttribute == "uid" } def "Test that getUserObject returns inetOrgPerson"() { - 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) - when: "Get user object is called" - String userObject = ldapConfiguration.getUserObject() - then: "inetOrgPerson is returned" - userObject == "inetOrgPerson" + 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) + when: "Get user object is called" + String userObject = ldapConfiguration.getUserObject() + then: "inetOrgPerson is returned" + userObject == "inetOrgPerson" } 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) - 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: "A request is made to get the providerUrl" - String providerUrl = ldapConfiguration.getProviderUrl() - - then: "The providerUrl should be given." - providerUrl == "ldap://localhost:389" + given: "We have a ConfigDao, LdapManager, LdapConfiguration" + 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: "A request is made to get the providerUrl" + String providerUrl = ldapConfiguration.getProviderUrl() + + then: "The providerUrl should be given." + providerUrl == "ldap://localhost:389" } - def "Test that get search group principle returns successfully"() { - 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) - - when: "A request is made to get the search group principle" - String result = ldapConfiguration.getSearchGroupPrinciple(); - - then: "The result holds the same value configDao did" - result == "cn=cloudstack,cn=users,dc=cloudstack,dc=org" - } - - def "Test that getTrustStorePassword resopnds"() { - 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) - - when: "A request is made to get the truststore password" - String result = ldapConfiguration.getTrustStorePassword() - - then: "The result is password" - result == "password"; - } - - def "Test that getSSLStatus can be true"() { - given: "We have a ConfigDao with values for truststore and truststore password set" - 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) - - when: "A request is made to get the status of SSL" - boolean result = ldapConfiguration.getSSLStatus(); - - then: "The response should be true" - result == true - } + def "Test that get search group principle returns successfully"() { + 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) + + when: "A request is made to get the search group principle" + String result = ldapConfiguration.getSearchGroupPrinciple(); + + then: "The result holds the same value configDao did" + result == "cn=cloudstack,cn=users,dc=cloudstack,dc=org" + } + + def "Test that getTrustStorePassword resopnds"() { + 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) + + when: "A request is made to get the truststore password" + String result = ldapConfiguration.getTrustStorePassword() + + then: "The result is password" + result == "password"; + } + + def "Test that getSSLStatus can be true"() { + given: "We have a ConfigDao with values for truststore and truststore password set" + 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) + + when: "A request is made to get the status of SSL" + boolean result = ldapConfiguration.getSSLStatus(); + + then: "The response should be true" + result == true + } def "Test getgroupobject"() { - given: "We have configdao for ldap group object" - def configDao = Mock(ConfigurationDao) - configDao.getValue("ldap.group.object") >> groupObject - - def ldapManger = Mock(LdapManager) - LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger) - def expectedResult = groupObject == null ? "groupOfUniqueNames" : groupObject - - def result = ldapConfiguration.getGroupObject() - expect: - result == expectedResult - where: - groupObject << [null, "", "groupOfUniqueNames"] + given: "We have configdao for ldap group object" + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.group.object") >> groupObject + + def ldapManger = Mock(LdapManager) + LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger) + def expectedResult = groupObject == null ? "groupOfUniqueNames" : groupObject + + def result = ldapConfiguration.getGroupObject() + expect: + result == expectedResult + where: + groupObject << [null, "", "groupOfUniqueNames"] } def "Test getGroupUniqueMemeberAttribute"() { - given: "We have configdao for ldap group object" - def configDao = Mock(ConfigurationDao) - configDao.getValue("ldap.group.user.uniquemember") >> groupObject - - def ldapManger = Mock(LdapManager) - LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger) - def expectedResult = groupObject == null ? "uniquemember" : groupObject - - def result = ldapConfiguration.getGroupUniqueMemeberAttribute() - expect: - result == expectedResult - where: - groupObject << [null, "", "uniquemember"] + given: "We have configdao for ldap group object" + def configDao = Mock(ConfigurationDao) + configDao.getValue("ldap.group.user.uniquemember") >> groupObject + + def ldapManger = Mock(LdapManager) + LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger) + def expectedResult = groupObject == null ? "uniquemember" : groupObject + + def result = ldapConfiguration.getGroupUniqueMemeberAttribute() + expect: + result == expectedResult + where: + groupObject << [null, "", "uniquemember"] + } + + def "Test getReadTimeout"() { + given: "We have configdao for ldap group object" + def configDao = Mock(ConfigurationDao) + ConfigurationVO configurationVo = new ConfigurationVO("ldap.read.timeout", LdapConfiguration.ldapReadTimeout); + configurationVo.setValue(timeout) + configDao.findById("ldap.read.timeout") >> configurationVo + + def configDepotImpl = Mock(ConfigDepotImpl) + configDepotImpl.global() >> configDao + ConfigKey.init(configDepotImpl) + + def ldapManger = Mock(LdapManager) + LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapManger) + + def expected = timeout == null ? 1000 : timeout.toLong() //1000 is the default value + + def result = ldapConfiguration.getReadTimeout() + expect: + result == expected + where: + timeout << ["1000000", "1000", null] } }