mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
added group and domain params to importLdapUsers api call
Signed-off-by: Ian Duffy <ian@ianduffy.ie>
This commit is contained in:
parent
856703cc1c
commit
b436a82392
@ -26,6 +26,7 @@ import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.ldap.LdapManager;
|
||||
import org.apache.cloudstack.ldap.LdapUser;
|
||||
import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
|
||||
@ -55,6 +56,15 @@ public class LdapImportUsersCmd extends BaseListCmd {
|
||||
@Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
|
||||
private Map<String, String> details;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN, type = CommandType.STRING,
|
||||
description = "Specifies the domain to which the ldap users are to be imported. If no domain is specified, a domain will created using group parameter. If the " +
|
||||
"group is also not specified, a domain name based on the OU information will be created. If no OU hierarchy exists, will be defaulted to ROOT domain")
|
||||
private String domainName;
|
||||
|
||||
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING,
|
||||
description = "Specifies the group name from which the ldap users are to be imported. If no group is specified, all the users will be imported.")
|
||||
private String groupName;
|
||||
|
||||
@Inject
|
||||
private LdapManager _ldapManager;
|
||||
|
||||
@ -75,14 +85,15 @@ public class LdapImportUsersCmd extends BaseListCmd {
|
||||
List<LdapUserResponse> ldapResponses = null;
|
||||
final ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>();
|
||||
try {
|
||||
final List<LdapUser> users = _ldapManager.getUsers();
|
||||
List<LdapUser> users;
|
||||
if(StringUtils.isNotBlank(groupName)) {
|
||||
users = _ldapManager.getUsersInGroup(groupName);
|
||||
} else {
|
||||
users = _ldapManager.getUsers();
|
||||
}
|
||||
for (LdapUser user : users) {
|
||||
Domain domain = _domainService.getDomainByName(user.getDomain(), Domain.ROOT_DOMAIN);
|
||||
|
||||
if (domain == null) {
|
||||
domain = _domainService.createDomain(user.getDomain(), Domain.ROOT_DOMAIN, user.getDomain(), UUID.randomUUID().toString());
|
||||
}
|
||||
_accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, user.getUsername(),
|
||||
Domain domain = getDomain(user);
|
||||
_accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, user.getUsername(),
|
||||
accountType, domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString());
|
||||
}
|
||||
ldapResponses = createLdapUserResponse(users);
|
||||
@ -95,6 +106,33 @@ public class LdapImportUsersCmd extends BaseListCmd {
|
||||
}
|
||||
}
|
||||
|
||||
private Domain getDomain(LdapUser user) {
|
||||
String csDomainName = null;
|
||||
if (StringUtils.isNotBlank(domainName)) {
|
||||
csDomainName = domainName;
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(groupName)) {
|
||||
csDomainName = groupName;
|
||||
} else if (StringUtils.isNotBlank(user.getDomain())) {
|
||||
csDomainName = user.getDomain();
|
||||
}
|
||||
//removing all the special characters and trimming it length 190 to make the domain valid.
|
||||
csDomainName = StringUtils.substring(csDomainName.replaceAll("\\W",""),0,190);
|
||||
}
|
||||
Domain domain;
|
||||
if (StringUtils.isNotBlank(csDomainName)) {
|
||||
domain = _domainService.getDomainByName(csDomainName, Domain.ROOT_DOMAIN);
|
||||
|
||||
if (domain == null) {
|
||||
domain = _domainService.createDomain(csDomainName, Domain.ROOT_DOMAIN, csDomainName, UUID.randomUUID().toString());
|
||||
}
|
||||
} else {
|
||||
domain = _domainService.getDomain(Domain.ROOT_DOMAIN);
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
private List<LdapUserResponse> createLdapUserResponse(List<LdapUser> users) {
|
||||
final List<LdapUserResponse> ldapResponses = new ArrayList<LdapUserResponse>();
|
||||
for (final LdapUser user : users) {
|
||||
|
||||
@ -143,6 +143,16 @@ public class LdapConfiguration {
|
||||
return userObject == null ? "inetOrgPerson" : userObject;
|
||||
}
|
||||
|
||||
public String getGroupObject() {
|
||||
final String groupObject = _configDao.getValue("ldap.group.object");
|
||||
return groupObject == null ? "groupOfUniqueNames" : groupObject;
|
||||
}
|
||||
|
||||
public String getGroupUniqueMemeberAttribute() {
|
||||
final String uniqueMemberAttribute = _configDao.getValue("ldap.group.user.uniquemember");
|
||||
return uniqueMemberAttribute == null ? "uniquemember" : uniqueMemberAttribute;
|
||||
}
|
||||
|
||||
public String getCommonNameAttribute() {
|
||||
return "cn";
|
||||
}
|
||||
|
||||
@ -47,6 +47,8 @@ public interface LdapManager extends PluggableService {
|
||||
|
||||
List<LdapUser> getUsers() throws NoLdapUserMatchingQueryException;
|
||||
|
||||
List<LdapUser> getUsersInGroup(String groupName) throws NoLdapUserMatchingQueryException;
|
||||
|
||||
boolean isLdapEnabled();
|
||||
|
||||
Pair<List<? extends LdapConfigurationVO>, Integer> listConfigurations(
|
||||
|
||||
@ -194,7 +194,20 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public List<LdapUser> getUsersInGroup(String groupName) throws NoLdapUserMatchingQueryException {
|
||||
DirContext context = null;
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
return _ldapUserManager.getUsersInGroup(groupName, context);
|
||||
} catch (final NamingException e) {
|
||||
throw new NoLdapUserMatchingQueryException("groupName=" + groupName);
|
||||
} finally {
|
||||
closeContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLdapEnabled() {
|
||||
return listConfigurations(new LdapListConfigurationCmd(this)).second() > 0;
|
||||
}
|
||||
|
||||
@ -23,10 +23,7 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.directory.*;
|
||||
|
||||
public class LdapUserManager {
|
||||
|
||||
@ -86,6 +83,28 @@ public class LdapUserManager {
|
||||
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 DirContext context) throws NamingException {
|
||||
final NamingEnumeration<SearchResult> result = searchUsers(username, context);
|
||||
if (result.hasMoreElements()) {
|
||||
@ -114,6 +133,44 @@ public class LdapUserManager {
|
||||
return users;
|
||||
}
|
||||
|
||||
public List<LdapUser> getUsersInGroup(String groupName, DirContext 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());
|
||||
users.add(getUserForDn(userdn,context));
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(users);
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private LdapUser getUserForDn(String userdn, DirContext 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 NamingEnumeration<SearchResult> searchUsers(final DirContext context) throws NamingException {
|
||||
return searchUsers(null, context);
|
||||
}
|
||||
|
||||
@ -220,4 +220,37 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
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"]
|
||||
}
|
||||
|
||||
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"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
||||
def "Test failed creation due to a null response from cloudstack account creater"() {
|
||||
given: "We have an LdapManager, AccountService and LdapCreateAccountCmd"
|
||||
LdapManager ldapManager = Mock(LdapManager)
|
||||
ldapManager.getUser(_) >> new LdapUser("rmurphy", "rmurphy@cloudstack.org", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org")
|
||||
ldapManager.getUser(_) >> new LdapUser("rmurphy", "rmurphy@cloudstack.org", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = Spy(LdapCreateAccountCmd, constructorArgs: [ldapManager, accountService])
|
||||
ldapCreateAccountCmd.getCurrentContext() >> Mock(CallContext)
|
||||
@ -104,7 +104,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
||||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = new LdapCreateAccountCmd(ldapManager, accountService);
|
||||
when: "a user with an username, email, firstname and lastname is validated"
|
||||
def result = ldapCreateAccountCmd.validateUser(new LdapUser("username","email","firstname","lastname","principal"))
|
||||
def result = ldapCreateAccountCmd.validateUser(new LdapUser("username","email","firstname","lastname","principal","domain"))
|
||||
then: "the result is true"
|
||||
result == true
|
||||
}
|
||||
@ -115,7 +115,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
||||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = new LdapCreateAccountCmd(ldapManager, accountService)
|
||||
when: "A user with no email address attempts to validate"
|
||||
ldapCreateAccountCmd.validateUser(new LdapUser("username",null,"firstname","lastname","principal"))
|
||||
ldapCreateAccountCmd.validateUser(new LdapUser("username",null,"firstname","lastname","principal","domain"))
|
||||
then: "An exception is thrown"
|
||||
thrown Exception
|
||||
}
|
||||
@ -137,7 +137,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
||||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = new LdapCreateAccountCmd(ldapManager, accountService)
|
||||
when: "A user with no lastname attempts to validate"
|
||||
ldapCreateAccountCmd.validateUser(new LdapUser("username","email","firstname",null,"principal"))
|
||||
ldapCreateAccountCmd.validateUser(new LdapUser("username","email","firstname",null,"principal","domain"))
|
||||
then: "An exception is thown"
|
||||
thrown Exception
|
||||
}
|
||||
|
||||
@ -34,7 +34,8 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
||||
given: "We have an LdapManager, DomainService and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def domainService = Mock(DomainService)
|
||||
def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService)
|
||||
def accountService = Mock(AccountService)
|
||||
def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService)
|
||||
when: "Get command name is called"
|
||||
String commandName = ldapImportUsersCmd.getCommandName()
|
||||
then: "ldapuserresponse is returned"
|
||||
@ -42,7 +43,7 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
||||
}
|
||||
|
||||
def "Test successful response from execute"() {
|
||||
given: "We have an LdapManager, DomainService, one user and a LdapImportUsersCmd"
|
||||
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def domainService = Mock(DomainService)
|
||||
def accountService = Mock(AccountService)
|
||||
@ -68,4 +69,123 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
||||
then: "a list of size 2 is returned"
|
||||
ldapImportUsersCmd.responseObject.getResponses().size() == 2
|
||||
}
|
||||
|
||||
def "Test successful response from execute with group specified"() {
|
||||
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def domainService = Mock(DomainService)
|
||||
def accountService = Mock(AccountService)
|
||||
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering"))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering"))
|
||||
ldapManager.getUsersInGroup("TestGroup") >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
LdapUserResponse response2 = new LdapUserResponse("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>>[response1, response2]
|
||||
|
||||
|
||||
Domain domain = new DomainVO("TestGroup", 1L, 1L, "TestGroup", UUID.randomUUID().toString())
|
||||
domainService.getDomainByName("TestGroup", 1L) >>> [null, domain]
|
||||
1 * domainService.createDomain("TestGroup", 1L, "TestGroup", _) >> domain
|
||||
|
||||
def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService)
|
||||
ldapImportUsersCmd.accountType = 2;
|
||||
ldapImportUsersCmd.groupName = "TestGroup";
|
||||
|
||||
when: "LdapListUsersCmd is executed"
|
||||
ldapImportUsersCmd.execute()
|
||||
then: "a list of size 2 is returned"
|
||||
ldapImportUsersCmd.responseObject.getResponses().size() == 2
|
||||
}
|
||||
|
||||
def "Test successful response from execute with group and domain specified"() {
|
||||
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def domainService = Mock(DomainService)
|
||||
def accountService = Mock(AccountService)
|
||||
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering"))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering"))
|
||||
ldapManager.getUsersInGroup("TestGroup") >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
LdapUserResponse response2 = new LdapUserResponse("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>>[response1, response2]
|
||||
|
||||
|
||||
Domain domain = new DomainVO("TestDomain", 1L, 1L, "TestDomain", UUID.randomUUID().toString())
|
||||
domainService.getDomainByName("TestDomain", 1L) >>> [null, domain]
|
||||
1 * domainService.createDomain("TestDomain", 1L, "TestDomain", _) >> domain
|
||||
|
||||
def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService)
|
||||
ldapImportUsersCmd.accountType = 2;
|
||||
ldapImportUsersCmd.groupName = "TestGroup";
|
||||
ldapImportUsersCmd.domainName = "TestDomain";
|
||||
|
||||
when: "LdapListUsersCmd is executed"
|
||||
ldapImportUsersCmd.execute()
|
||||
then: "a list of size 2 is returned"
|
||||
ldapImportUsersCmd.responseObject.getResponses().size() == 2
|
||||
}
|
||||
|
||||
def "Test successful response from execute with domain specified"() {
|
||||
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def domainService = Mock(DomainService)
|
||||
def accountService = Mock(AccountService)
|
||||
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering"))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering"))
|
||||
ldapManager.getUsers() >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
LdapUserResponse response2 = new LdapUserResponse("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>>[response1, response2]
|
||||
|
||||
|
||||
Domain domain = new DomainVO("TestDomain", 1L, 1L, "TestDomain", UUID.randomUUID().toString())
|
||||
domainService.getDomainByName("TestDomain", 1L) >>> [null, domain]
|
||||
1 * domainService.createDomain("TestDomain", 1L, "TestDomain", _) >> domain
|
||||
|
||||
def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService)
|
||||
ldapImportUsersCmd.accountType = 2;
|
||||
ldapImportUsersCmd.domainName = "TestDomain";
|
||||
|
||||
when: "LdapListUsersCmd is executed"
|
||||
ldapImportUsersCmd.execute()
|
||||
then: "a list of size 2 is returned"
|
||||
ldapImportUsersCmd.responseObject.getResponses().size() == 2
|
||||
}
|
||||
|
||||
def "Test getDomain with no domain or group name specified specified"() {
|
||||
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
def domainService = Mock(DomainService)
|
||||
def accountService = Mock(AccountService)
|
||||
def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService)
|
||||
ldapImportUsersCmd.domainName = varDomainName
|
||||
ldapImportUsersCmd.groupName = varGroupName
|
||||
|
||||
def ldapUser1 = new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
def ldapUser2 = new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering");
|
||||
|
||||
Domain domain = new DomainVO(expectedDomainName, 1L, 1L, expectedDomainName, UUID.randomUUID().toString())
|
||||
2 * domainService.getDomainByName(expectedDomainName, 1L) >>> [null, domain]
|
||||
1 * domainService.createDomain(expectedDomainName, 1L, expectedDomainName, _) >> domain
|
||||
|
||||
def result1 = ldapImportUsersCmd.getDomain(ldapUser1)
|
||||
def result2 = ldapImportUsersCmd.getDomain(ldapUser2)
|
||||
expect: "engineering domain is returned"
|
||||
result1 == domain
|
||||
result2 == domain
|
||||
where: "The domain and group are set to the following values"
|
||||
varDomainName | varGroupName | expectedDomainName
|
||||
null | null | "engineering"
|
||||
"TestDomain" | null | "TestDomain"
|
||||
"TestDomain" | "TestGroup" | "TestDomain"
|
||||
null | "TestGroup" | "TestGroup"
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -356,4 +356,20 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
||||
then: "true is returned because a configuration was found"
|
||||
result == true;
|
||||
}
|
||||
|
||||
def "Test success getUsersInGroup"() {
|
||||
given: "We have an LdapConfigurationDao, LdapContextFactory, LdapUserManager and LdapManager"
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDaoImpl)
|
||||
def ldapContextFactory = Mock(LdapContextFactory)
|
||||
def ldapUserManager = Mock(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)
|
||||
when: "We search for a group of users"
|
||||
def result = ldapManager.getUsersInGroup("engineering")
|
||||
then: "A list greater of size one is returned"
|
||||
result.size() == 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,8 +21,10 @@ import org.apache.cloudstack.ldap.LdapUserManager
|
||||
import spock.lang.Shared
|
||||
|
||||
import javax.naming.NamingException
|
||||
import javax.naming.NamingEnumeration
|
||||
import javax.naming.directory.Attribute
|
||||
import javax.naming.directory.Attributes
|
||||
import javax.naming.directory.DirContext
|
||||
import javax.naming.directory.SearchControls
|
||||
import javax.naming.directory.SearchResult
|
||||
import javax.naming.ldap.LdapContext
|
||||
@ -47,6 +49,38 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
@Shared
|
||||
private def principal
|
||||
|
||||
private def createGroupSearchContext() {
|
||||
|
||||
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];
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
private def createContext() {
|
||||
Attributes attributes = createUserAttributes(username, email, firstname, lastname)
|
||||
SearchResult searchResults = createSearchResult(attributes)
|
||||
@ -65,6 +99,7 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
search.getName() >> "cn=" + attributes.getAt("uid").get();
|
||||
|
||||
search.getAttributes() >> attributes
|
||||
search.getNameInNamespace() >> principal
|
||||
|
||||
return search
|
||||
}
|
||||
@ -105,6 +140,9 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
ldapConfiguration.getFirstnameAttribute() >> "givenname"
|
||||
ldapConfiguration.getLastnameAttribute() >> "sn"
|
||||
ldapConfiguration.getBaseDn() >> "dc=cloudstack,dc=org"
|
||||
ldapConfiguration.getCommonNameAttribute() >> "cn"
|
||||
ldapConfiguration.getGroupObject() >> "groupOfUniqueNames"
|
||||
ldapConfiguration.getGroupUniqueMemeberAttribute() >> "uniquemember"
|
||||
|
||||
username = "rmurphy"
|
||||
email = "rmurphy@test.com"
|
||||
@ -203,4 +241,43 @@ class LdapUserManagerSpec extends spock.lang.Specification {
|
||||
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 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"(){
|
||||
given: "ldap user manager and ldap config"
|
||||
def ldapUserManager = new LdapUserManager(ldapConfiguration)
|
||||
|
||||
when: "A request for users is made"
|
||||
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContext())
|
||||
then: "one user is returned"
|
||||
result.size() == 1
|
||||
}
|
||||
|
||||
def "test successful getUserForDn"(){
|
||||
given: "ldap user manager and ldap config"
|
||||
def ldapUserManager = new LdapUserManager(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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,6 +394,9 @@ public enum Config {
|
||||
LdapSearchGroupPrinciple("Advanced", ManagementServer.class, String.class, "ldap.search.group.principle", null, "Sets the principle of the group that users must be a member of", null),
|
||||
LdapTrustStore("Advanced", ManagementServer.class, String.class, "ldap.truststore", null, "Sets the path to the truststore to use for SSL", null),
|
||||
LdapTrustStorePassword("Advanced", ManagementServer.class, String.class, "ldap.truststore.password", null, "Sets the password for the truststore", null),
|
||||
LdapGroupObject("Advanced", ManagementServer.class, String.class, "ldap.group.object", "groupOfUniqueNames", "Sets the object type of groups within LDAP", null),
|
||||
LdapGroupUniqueMemberAttribute("Advanced", ManagementServer.class, String.class, "ldap.group.user.uniquemember", "uniquemember",
|
||||
"Sets the attribute for uniquemembers within a group", null),
|
||||
|
||||
// VMSnapshots
|
||||
VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null),
|
||||
|
||||
@ -483,3 +483,8 @@ ALTER TABLE `cloud`.`nic_details` CHANGE `display_detail` `display` tinyint(1) N
|
||||
ALTER TABLE `cloud`.`user_vm_details` CHANGE `display_detail` `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end user';
|
||||
ALTER TABLE `cloud`.`service_offering_details` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end user';
|
||||
ALTER TABLE `cloud`.`storage_pool_details` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end user';
|
||||
|
||||
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.group.object', 'groupOfUniqueNames',
|
||||
'Sets the object type of groups within LDAP','groupOfUniqueNames',NULL,NULL,0);
|
||||
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'ldap.group.user.uniquemember', 'uniquemember',
|
||||
'Sets the attribute for uniquemembers within a group','uniquemember',NULL,NULL,0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user