| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| package groovy.org.apache.cloudstack.ldap |
| |
| import org.apache.cloudstack.ldap.LdapConfiguration |
| import org.apache.cloudstack.ldap.OpenLdapUserManagerImpl |
| import spock.lang.Shared |
| |
| import javax.naming.NamingException |
| import javax.naming.directory.Attribute |
| import javax.naming.directory.Attributes |
| import javax.naming.directory.SearchControls |
| import javax.naming.directory.SearchResult |
| import javax.naming.ldap.InitialLdapContext |
| import javax.naming.ldap.LdapContext |
| |
| class OpenLdapUserManagerSpec extends spock.lang.Specification { |
| |
| @Shared |
| private def ldapConfiguration |
| |
| @Shared |
| private def username |
| |
| @Shared |
| private def email |
| |
| @Shared |
| private def firstname |
| |
| @Shared |
| private def lastname |
| |
| @Shared |
| private def principal |
| |
| private def createGroupSearchContextOneUser() { |
| |
| def umSearchResult = Mock(SearchResult) |
| umSearchResult.getName() >> principal; |
| umSearchResult.getAttributes() >> principal |
| |
| def uniqueMembers = new BasicNamingEnumerationImpl() |
| uniqueMembers.add(umSearchResult); |
| def attributes = Mock(Attributes) |
| def uniqueMemberAttribute = Mock(Attribute) |
| uniqueMemberAttribute.getId() >> "uniquemember" |
| uniqueMemberAttribute.getAll() >> uniqueMembers |
| attributes.get("uniquemember") >> uniqueMemberAttribute |
| |
| def groupSearchResult = Mock(SearchResult) |
| groupSearchResult.getName() >> principal; |
| groupSearchResult.getAttributes() >> attributes |
| |
| def searchGroupResults = new BasicNamingEnumerationImpl() |
| searchGroupResults.add(groupSearchResult); |
| |
| attributes = createUserAttributes(username, email, firstname, lastname) |
| SearchResult userSearchResult = createSearchResult(attributes) |
| def searchUsersResults = new BasicNamingEnumerationImpl() |
| searchUsersResults.add(userSearchResult); |
| |
| def context = Mock(LdapContext) |
| context.search(_, _, _) >>> [searchGroupResults, searchUsersResults, searchGroupResults, new BasicNamingEnumerationImpl()]; |
| |
| return context |
| } |
| |
| private def createGroupSearchContextNoUser() { |
| |
| def umSearchResult = Mock(SearchResult) |
| umSearchResult.getName() >> principal; |
| umSearchResult.getAttributes() >> principal |
| |
| def uniqueMembers = new BasicNamingEnumerationImpl() |
| uniqueMembers.add(umSearchResult); |
| def attributes = Mock(Attributes) |
| def uniqueMemberAttribute = Mock(Attribute) |
| uniqueMemberAttribute.getId() >> "uniquemember" |
| uniqueMemberAttribute.getAll() >> uniqueMembers |
| attributes.get("uniquemember") >> uniqueMemberAttribute |
| |
| def groupSearchResult = Mock(SearchResult) |
| groupSearchResult.getName() >> principal; |
| groupSearchResult.getAttributes() >> attributes |
| |
| def searchGroupResults = new BasicNamingEnumerationImpl() |
| searchGroupResults.add(groupSearchResult); |
| |
| def context = Mock(LdapContext) |
| context.search(_, _, _) >>> [searchGroupResults, new BasicNamingEnumerationImpl()]; |
| |
| return context |
| } |
| |
| private def createContext() { |
| Attributes attributes = createUserAttributes(username, email, firstname, lastname) |
| SearchResult searchResults = createSearchResult(attributes) |
| def searchUsersResults = new BasicNamingEnumerationImpl() |
| searchUsersResults.add(searchResults); |
| |
| def context = Mock(LdapContext) |
| context.search(_, _, _) >> searchUsersResults; |
| |
| return context |
| } |
| |
| private SearchResult createSearchResult(attributes) { |
| def search = Mock(SearchResult) |
| |
| search.getName() >> "cn=" + attributes.getAt("uid").get(); |
| |
| search.getAttributes() >> attributes |
| search.getNameInNamespace() >> principal |
| |
| return search |
| } |
| |
| private Attributes createUserAttributes(String username, String email, String firstname, String lastname) { |
| def attributes = Mock(Attributes) |
| |
| def nameAttribute = Mock(Attribute) |
| nameAttribute.getId() >> "uid" |
| nameAttribute.get() >> username |
| attributes.get("uid") >> nameAttribute |
| |
| def mailAttribute = Mock(Attribute) |
| mailAttribute.getId() >> "mail" |
| mailAttribute.get() >> email |
| attributes.get("mail") >> mailAttribute |
| |
| def givennameAttribute = Mock(Attribute) |
| givennameAttribute.getId() >> "givenname" |
| givennameAttribute.get() >> firstname |
| attributes.get("givenname") >> givennameAttribute |
| |
| def snAttribute = Mock(Attribute) |
| snAttribute.getId() >> "sn" |
| snAttribute.get() >> lastname |
| attributes.get("sn") >> snAttribute |
| |
| return attributes |
| } |
| |
| def setupSpec() { |
| ldapConfiguration = Mock(LdapConfiguration) |
| |
| ldapConfiguration.getScope() >> SearchControls.SUBTREE_SCOPE |
| ldapConfiguration.getReturnAttributes() >> ["uid", "mail", "cn"] |
| ldapConfiguration.getUsernameAttribute() >> "uid" |
| ldapConfiguration.getEmailAttribute() >> "mail" |
| ldapConfiguration.getFirstnameAttribute() >> "givenname" |
| ldapConfiguration.getLastnameAttribute() >> "sn" |
| ldapConfiguration.getBaseDn(_) >> "dc=cloudstack,dc=org" |
| ldapConfiguration.getCommonNameAttribute() >> "cn" |
| ldapConfiguration.getGroupObject() >> "groupOfUniqueNames" |
| ldapConfiguration.getGroupUniqueMemberAttribute(_) >> "uniquemember" |
| ldapConfiguration.getLdapPageSize() >> 1 |
| ldapConfiguration.getReadTimeout(_) >> 1000 |
| |
| username = "rmurphy" |
| email = "rmurphy@test.com" |
| firstname = "Ryan" |
| lastname = "Murphy" |
| principal = "cn=" + username + "," + ldapConfiguration.getBaseDn() |
| } |
| |
| def "Test successfully creating an Ldap User from Search result"() { |
| given: "We have attributes, a search and a user manager" |
| def attributes = createUserAttributes(username, email, firstname, lastname) |
| def search = createSearchResult(attributes) |
| def userManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| def result = userManager.createUser(search,) |
| |
| expect: "The crated user the data supplied from LDAP" |
| |
| result.username == username |
| result.email == email |
| result.firstname == firstname |
| result.lastname == lastname |
| result.principal == principal |
| } |
| |
| def "Test successfully returning a list from get users"() { |
| given: "We have a LdapUserManager" |
| |
| def userManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| |
| when: "A request for users is made" |
| def result = userManager.getUsers(username, createContext()) |
| |
| then: "A list of users is returned" |
| result.size() == 1 |
| } |
| |
| def "Test successfully returning a list from get users when no username is given"() { |
| given: "We have a LdapUserManager" |
| |
| def userManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| |
| when: "Get users is called without a username" |
| def result = userManager.getUsers(createContext()) |
| |
| then: "All users are returned" |
| result.size() == 1 |
| } |
| |
| def "Test successfully returning a ldap user from searchUsers"() { |
| given: "We have a LdapUserManager" |
| def userManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| |
| when: "We search for users" |
| def result = userManager.searchUsers(createContext()) |
| |
| then: "A list of users are returned." |
| result.first().getPrincipal() == principal |
| } |
| |
| def "Test successfully returning an Ldap user from a get user request"() { |
| given: "We have a LdapUserMaanger" |
| |
| def userManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| |
| when: "A request for a user is made" |
| def result = userManager.getUser(username, createContext()) |
| |
| then: "The user is returned" |
| result.username == username |
| result.email == email |
| result.firstname == firstname |
| result.lastname == lastname |
| result.principal == principal |
| } |
| |
| def "Test successfully throwing an exception when no users are found with getUser"() { |
| given: "We have a seachResult of users and a User Manager" |
| |
| def searchUsersResults = new BasicNamingEnumerationImpl() |
| |
| def context = Mock(LdapContext) |
| context.search(_, _, _) >> searchUsersResults; |
| |
| def userManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| |
| when: "a get user request is made and no user is found" |
| def result = userManager.getUser(username, context) |
| |
| then: "An exception is thrown." |
| thrown NamingException |
| } |
| |
| 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 OpenLdapUserManagerImpl(); |
| expect: "The result is not null" |
| result != null |
| } |
| |
| def "test successful generateGroupSearchFilter"() { |
| given: "ldap user manager and ldap config" |
| def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| def groupName = varGroupName == null ? "*" : varGroupName |
| def expectedResult = "(&(objectClass=groupOfUniqueNames)(cn=" + groupName + "))"; |
| |
| def result = ldapUserManager.generateGroupSearchFilter(varGroupName) |
| expect: |
| result == expectedResult |
| where: "The group name passed is set to " |
| varGroupName << ["", null, "Murphy"] |
| } |
| |
| def "test successful getUsersInGroup one user"() { |
| given: "ldap user manager and ldap config" |
| def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| |
| when: "A request for users is made" |
| def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextOneUser(),) |
| then: "one user is returned" |
| result.size() == 1 |
| } |
| |
| def "test successful getUsersInGroup no user"() { |
| given: "ldap user manager and ldap config" |
| def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration) |
| |
| when: "A request for users is made" |
| def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextNoUser(),) |
| then: "no user is returned" |
| result.size() == 0 |
| } |
| |
| def "test successful getUserForDn"() { |
| given: "ldap user manager and ldap config" |
| 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()) |
| then: "A list of users is returned" |
| result != 1 |
| result.username == username |
| result.email == email |
| result.firstname == firstname |
| result.lastname == lastname |
| result.principal == principal |
| |
| } |
| |
| def "test searchUsers when ldap basedn in not set"() { |
| given: "ldap configuration where basedn is not set" |
| def ldapconfig = Mock(LdapConfiguration) |
| ldapconfig.getBaseDn() >> null |
| def ldapUserManager = new OpenLdapUserManagerImpl(ldapconfig) |
| |
| when: "A request for search users is made" |
| def result = ldapUserManager.searchUsers(new InitialLdapContext()) |
| |
| then: "An exception with no basedn defined is returned" |
| def e = thrown(IllegalArgumentException) |
| e.message == "ldap basedn is not configured" |
| } |
| } |